Re: [Qemu-devel] [PATCH 1/2] configure: require glib 2.22

2015-05-22 Thread Alex Bennée

John Snow  writes:

> This provides g_ptr_array_new_with_free_func, as well as a few
> other functions that we've been hacking around in glib-compat.h.
> Cleaning up the compatibility headers will come later.
>
> Signed-off-by: Paolo Bonzini 
> Signed-off-by: John Snow 
Reviewed-by: Alex Bennée 

> ---
>  configure | 7 +--
>  1 file changed, 1 insertion(+), 6 deletions(-)
>
> diff --git a/configure b/configure
> index 1f0f485..0c86eb2 100755
> --- a/configure
> +++ b/configure
> @@ -2773,12 +2773,7 @@ fi
>  ##
>  # glib support probe
>  
> -if test "$mingw32" = yes; then
> -# g_poll is required in order to integrate with the glib main loop.
> -glib_req_ver=2.20
> -else
> -glib_req_ver=2.12
> -fi
> +glib_req_ver=2.22
>  glib_modules=gthread-2.0
>  if test "$modules" = yes; then
>  glib_modules="$glib_modules gmodule-2.0"

-- 
Alex Bennée



Re: [Qemu-devel] [PATCH 2/2] glib: remove stale compat functions

2015-05-22 Thread Alex Bennée

John Snow  writes:

> Since we're bumping the version to 2.22+,
> remove the now-stale compat functions.
>
> Signed-off-by: John Snow 
Reviewed-by: Alex Bennée 

> ---
>  include/glib-compat.h | 35 ---
>  1 file changed, 35 deletions(-)
>
> diff --git a/include/glib-compat.h b/include/glib-compat.h
> index 28d9f15..318e000 100644
> --- a/include/glib-compat.h
> +++ b/include/glib-compat.h
> @@ -23,14 +23,6 @@
>  #define G_TIME_SPAN_SECOND  (G_GINT64_CONSTANT(100))
>  #endif
>  
> -#if !GLIB_CHECK_VERSION(2, 14, 0)
> -static inline guint g_timeout_add_seconds(guint interval, GSourceFunc 
> function,
> -  gpointer data)
> -{
> -return g_timeout_add(interval * 1000, function, data);
> -}
> -#endif
> -
>  #if !GLIB_CHECK_VERSION(2, 28, 0)
>  static inline gint64 qemu_g_get_monotonic_time(void)
>  {
> @@ -47,23 +39,6 @@ static inline gint64 qemu_g_get_monotonic_time(void)
>  #define g_get_monotonic_time() qemu_g_get_monotonic_time()
>  #endif
>  
> -#if !GLIB_CHECK_VERSION(2, 16, 0)
> -static inline int g_strcmp0(const char *str1, const char *str2)
> -{
> -int result;
> -
> -if (!str1) {
> -result = -(str1 != str2);
> -} else if (!str2) {
> -result = (str1 != str2);
> -} else {
> -result = strcmp(str1, str2);
> -}
> -
> -return result;
> -}
> -#endif
> -
>  #ifdef _WIN32
>  /*
>   * g_poll has a problem on Windows when using
> @@ -71,16 +46,6 @@ static inline int g_strcmp0(const char *str1, const char 
> *str2)
>   */
>  #define g_poll(fds, nfds, timeout) g_poll_fixed(fds, nfds, timeout)
>  gint g_poll_fixed(GPollFD *fds, guint nfds, gint timeout);
> -#elif !GLIB_CHECK_VERSION(2, 20, 0)
> -/*
> - * Glib before 2.20.0 doesn't implement g_poll, so wrap it to compile 
> properly
> - * on older systems.
> - */
> -static inline gint g_poll(GPollFD *fds, guint nfds, gint timeout)
> -{
> -GMainContext *ctx = g_main_context_default();
> -return g_main_context_get_poll_func(ctx)(fds, nfds, timeout);
> -}
>  #endif
>  
>  #if !GLIB_CHECK_VERSION(2, 31, 0)

-- 
Alex Bennée



Re: [Qemu-devel] [libvirt] RFC: exposing qemu's block-set-write-threshold

2015-05-22 Thread Francesco Romani
- Original Message -
> From: "Eric Blake" 
> To: "Francesco Romani" 
> Cc: libvir-l...@redhat.com, "Nir Soffer" , "Peter Krempa" 
> ,
> qemu-devel@nongnu.org
> Sent: Friday, May 22, 2015 6:33:01 AM
> Subject: Re: [libvirt] RFC: exposing qemu's block-set-write-threshold
> 
> [adding qemu]
> 

> > I read the thread and I'm pretty sure this will be a silly question, but I
> > want
> > to make sure I am on the same page and I'm not somehow confused by the
> > terminology.
> > 
> > Let's consider the simplest of the situation we face in oVirt:
> > 
> > (thin provisioned qcow2 disk on LV)
> > 
> > vda=[format=qcow2] -> lv=[path=/dev/mapper/$UUID]
> > 
> > Isn't the LV here the 'backing file' (actually, backing block device) of
> > the disk?
> 
> Restating what you wrote into libvirt terminology, I think this means
>
> that you have a  where:
>  is qcow2
>  is a local file name
>  names vda
>  describes the backing LV:
>is also qcow2 (as polling allocation growth in order to
> resize on demand only makes sense for qcow2 format)
>is /dev/mapper/$UUID


Yes, exactly my point. I just want to be 100% sure that the three (slightly) 
different
parlances of the three groups (oVirt/libvirt/QEMU) are aligned on the same 
meaning,
and that we're not getting anything lost in translation

> that you have a  where:
>  is qcow2
>  is a local file name
>  names vda
>  describes the backing LV:
>is also qcow2 (as polling allocation growth in order to
> resize on demand only makes sense for qcow2 format)
>is /dev/mapper/$UUID

For the final confirmation, here's the actual XML we produce:


  
  
  
  ee1295ee-7ddc-4030-be5e-4557538bc4d2
  
  


For the sake of completeness:

$ ls -lh 
/rhev/data-center/0002-0002-0002-0002-014b/12f68692-2a5a-4e48-af5e-4679bca7fd44/images/ee1295ee-7ddc-4030-be5e-4557538bc4d2/05a88a94-5bd6-4698-be69-39e78c84e1a5
 
lrwxrwxrwx. 1 vdsm kvm 78 May 22 08:49 
/rhev/data-center/0002-0002-0002-0002-014b/12f68692-2a5a-4e48-af5e-4679bca7fd44/images/ee1295ee-7ddc-4030-be5e-4557538bc4d2/05a88a94-5bd6-4698-be69-39e78c84e1a5
 -> 
/dev/12f68692-2a5a-4e48-af5e-4679bca7fd44/05a88a94-5bd6-4698-be69-39e78c84e1a5

$ ls -lh /dev/12f68692-2a5a-4e48-af5e-4679bca7fd44/
total 0
lrwxrwxrwx. 1 root root 8 May 22 08:49 05a88a94-5bd6-4698-be69-39e78c84e1a5 -> 
../dm-11
lrwxrwxrwx. 1 root root 8 May 22 08:49 54673e6d-207d-4a66-8f0d-3f5b3cda78e5 -> 
../dm-12
lrwxrwxrwx. 1 root root 9 May 22 08:49 ids -> ../dm-606
lrwxrwxrwx. 1 root root 9 May 22 08:49 inbox -> ../dm-607
lrwxrwxrwx. 1 root root 9 May 22 08:49 leases -> ../dm-605
lrwxrwxrwx. 1 root root 9 May 22 08:49 master -> ../dm-608
lrwxrwxrwx. 1 root root 9 May 22 08:49 metadata -> ../dm-603
lrwxrwxrwx. 1 root root 9 May 22 08:49 outbox -> ../dm-604

lvs | grep 05a88a94
  05a88a94-5bd6-4698-be69-39e78c84e1a5 12f68692-2a5a-4e48-af5e-4679bca7fd44 
-wi-ao  14.12g

 
> then indeed, "vda" is the local qcow2 file, and "vda[1]" is the backing
> file on the LV storage.
> 
> Normally, you only care about the write threshold at the active layer
> (the local file, with name "vda"), because that is the only image that
> will normally be allocating sectors.  But in the case of active commit,
> where you are taking the thin-provisioned local file and writing its
> clusters back into the backing LV, the action of commit can allocate
> sectors in the backing file. 

Right

> Thus, libvirt wants to let you set a
> write-threshold on both parts of the backing chain (the active wrapper,
> and the LV backing file), where the event could fire on either node
> first.  The existing libvirt virConnectDomainGetAllStats() can already
> be used to poll allocation growth (the block.N.allocation statistic in
> libvirt, or 'virtual-size' in QMP's 'ImageInfo'), but the event would
> let you drop polling.

Yes, exactly the intent

> However, while starting to code the libvirt side of things, I've hit a
> couple of snags with interacting with the qemu design.  First, the
> 'block-set-write-threshold' command is allowed to set a threshold by
> 'node-name' (any BDS, whether active or backing),

Yes, this emerged during the review of my patch. 
I first took the simplest approach (probably simplistic, in retrospect),
but -IIRC- was pointed out that setting by node-name grants the most
flexible approach, hence was required.

See:
http://lists.nongnu.org/archive/html/qemu-devel/2014-11/msg02503.html
http://lists.nongnu.org/archive/html/qemu-devel/2014-11/msg02580.html
http://lists.nongnu.org/archive/html/qemu-devel/2014-11/msg02831.html

> but libvirt is not yet
> setting 'node-name' for backing files (so even though libvirt knows how
> to resolve "vda[1]" to the backing chain, 

I had vague memories of this, hence my clumsy and poorly worded question
about how to resolve 'vda[1]' before :\

> it does not yet have a way to
> tell qemu to set the threshold on that BDS until libvirt starts naming
> all nodes).  Second, querying for the current threshold value is on

Re: [Qemu-devel] [PATCH v6 3/4] cpu/apic: drop icc bus/bridge

2015-05-22 Thread Chen Fan


On 05/20/2015 10:53 PM, Igor Mammedov wrote:

On Wed, 20 May 2015 10:40:48 +0800
Zhu Guihua  wrote:


From: Chen Fan 

After CPU hotplug has been converted to BUS-less hot-plug infrastructure,
the only function ICC bus performs is to propagate reset to LAPICs. However
LAPIC could be reset by its parent (CPU) directly when CPU is being reset.
Do so and drop ~200LOC of not needed anymore ICCBus related code.

Signed-off-by: Chen Fan 
Signed-off-by: Zhu Guihua 

This patch regresses emulated APIC,
during RHEL7 boot:

[1.073487] [ cut here ]
[1.074019] WARNING: at arch/x86/kernel/apic/apic.c:1401 
setup_local_APIC+0x268/0x320()
[1.075011] Modules linked in:
[1.076474] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.10.0.sort+ #100
[1.077012] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 
rel-1.8.1-0-g4adadbd-20150316_085822-nilsson.home.kraxel.org 04/01/2014
[1.078011]   d1b49dbb 88007c787da8 
81649983
[1.082011]  88007c787de0 810b3241 0001 

[1.085012]  00f0   
88007c787df0
[1.088012] Call Trace:
[1.089019]  [] dump_stack+0x19/0x1b
[1.090017]  [] warn_slowpath_common+0x61/0x80
[1.091015]  [] warn_slowpath_null+0x1a/0x20
[1.092016]  [] setup_local_APIC+0x268/0x320
[1.093019]  [] native_smp_prepare_cpus+0x294/0x35b
[1.094018]  [] kernel_init_freeable+0xbb/0x217
[1.095017]  [] ? rest_init+0x80/0x80
[1.096015]  [] kernel_init+0xe/0x180
[1.097016]  [] ret_from_fork+0x7c/0xb0
[1.098016]  [] ? rest_init+0x80/0x80
[1.099017] ---[ end trace d99eba50bffa17c5 ]---


void setup_local_APIC(void)
...
 } while (queued && max_loops > 0);
 WARN_ON(max_loops <= 0); <=== here
...

reproducer:
   qemu-system-x86_64 -enable-kvm -m 2048  -smp 4 -machine kernel_irqchip=off 
rhel7.img
or just slower plain TCG
   qemu-system-x86_64 -m 2048 -smp 4 rhel7.img

it happens only on VM startup, there isn't any warning when booting after reset.

Hi Igor, Thanks for you pointing it out.

I had found that the problem appeared after we moved the apic reset into 
cpu reset.


the original operation is that there are devices (such as hpet, rtc) 
reset before apic reset,
when these devices reset, it would send irq to apic, before the change, 
the apic reset
is behind these devices reset. so the apic register is set to default 
values.


but after the change, thanks to the cpu reset is before the qemu system 
reset which causes
that the apic reset ahead the other devices reset. but before guest boot 
up, the irq request
should be rejected.  so when linux enable local apic, it would found 
there were irr requests.

then cause warn_on.

so I make a enforce cpu reset after qemu system reset. and I also change 
the apicbase value
by default, because cpu_set_apic_base()/apic_set_base() can not enable 
the APICBASE_ENABLE
bit in apic model. and I have test it, it seems work fine. the hasty 
change is that:


diff --git a/cpus.c b/cpus.c
index de6469f..b99e6ec 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1196,6 +1196,15 @@ void resume_all_vcpus(void)
 }
 }

+void reset_all_vcpus(void)
+{
+CPUState *cpu;
+
+CPU_FOREACH(cpu) {
+cpu_reset(cpu);
+}
+}
+
 /* For temporary buffers for forming a name */
 #define VCPU_THREAD_NAME_SIZE 16

diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h
index 3f162a9..5c1e9f2 100644
--- a/include/sysemu/cpus.h
+++ b/include/sysemu/cpus.h
@@ -5,6 +5,7 @@
 void qemu_init_cpu_loop(void);
 void resume_all_vcpus(void);
 void pause_all_vcpus(void);
+void reset_all_vcpus(void);
 void cpu_stop_current(void);

 void cpu_synchronize_all_states(void);
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 4080909..18bbe35 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2694,13 +2694,6 @@ bool cpu_is_bsp(X86CPU *cpu)
 {
 return cpu_get_apic_base(cpu->apic_state) & MSR_IA32_APICBASE_BSP;
 }
-
-/* TODO: remove me, when reset over QOM tree is implemented */
-static void x86_cpu_machine_reset_cb(void *opaque)
-{
-X86CPU *cpu = opaque;
-cpu_reset(CPU(cpu));
-}
 #endif

 static void mce_init(X86CPU *cpu)
@@ -2739,8 +2732,7 @@ static void x86_cpu_apic_create(X86CPU *cpu, Error 
**errp)

 /* TODO: convert to link<> */
 apic = APIC_COMMON(cpu->apic_state);
 apic->cpu = cpu;
-cpu_set_apic_base(cpu->apic_state,
-  APIC_DEFAULT_ADDRESS | MSR_IA32_APICBASE_ENABLE);
+apic->apicbase = APIC_DEFAULT_ADDRESS | MSR_IA32_APICBASE_ENABLE;
 }

 static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
@@ -2801,8 +2793,6 @@ static void x86_cpu_realizefn(DeviceState *dev, 
Error **errp)

 }

 #ifndef CONFIG_USER_ONLY
-qemu_register_reset(x86_cpu_machine_reset_cb, cpu);
-
 if (cpu->env.features[FEAT_1_EDX] & CPUID_APIC || smp_cpus > 1) {
 x86_cpu_apic_create(cpu, &local_err);

Re: [Qemu-devel] [PATCH] exec: optimize phys_page_set_level

2015-05-22 Thread Stefan Hajnoczi
On Thu, May 21, 2015 at 03:19:58PM +0200, Paolo Bonzini wrote:
> phys_page_set_level is writing zeroes to a struct that has just been
> filled in by phys_map_node_alloc.  Instead, tell phys_map_node_alloc
> whether to fill in the page "as a leaf" or "as a non-leaf".
> 
> memcpy is faster than struct assignment, which copies each bitfield
> individually.  Arguably a compiler bug, but memcpy is super-special
> cased anyway so what could go wrong?
> 
> This cuts the cost of phys_page_set_level from 25% to 5% when
> booting qboot.
> 
> Signed-off-by: Paolo Bonzini 
> ---
>  exec.c | 24 ++--
>  1 file changed, 10 insertions(+), 14 deletions(-)

Reviewed-by: Stefan Hajnoczi 


pgprBjTs67Xga.pgp
Description: PGP signature


Re: [Qemu-devel] [PATCH 04/10] target-tricore: add CMPSWP instructions of the v1.6.1 ISA

2015-05-22 Thread Bastian Koppelmann



On 05/21/2015 07:22 PM, Richard Henderson wrote:

On 05/13/2015 02:45 AM, Bastian Koppelmann wrote:

Those instruction were introduced in the new Aurix platform.

Signed-off-by: Bastian Koppelmann 

I can't really review this, because I can only find the v1.6 isa.
That said, the code for gen_cmpswap looks plausible, so...
Unfortunately I can't give you the documentation either, because my 
University has a NDA with Infineon and I'm only allowed to post the 
implementation of the new Instructions.


Cheers,
Bastian




Re: [Qemu-devel] [PATCH 08/10] target-tricore: add FCALL instructions of the v1.6 ISA

2015-05-22 Thread Bastian Koppelmann



On 05/21/2015 07:28 PM, Richard Henderson wrote:

On 05/13/2015 02:45 AM, Bastian Koppelmann wrote:

+static void gen_fcall_save_ctx(DisasContext *ctx)
+{
+tcg_gen_addi_tl(cpu_gpr_a[10], cpu_gpr_a[10], -4);
+tcg_gen_qemu_st_tl(cpu_gpr_a[11], cpu_gpr_a[10], ctx->mem_idx, MO_LESL);
+tcg_gen_movi_tl(cpu_gpr_a[11], ctx->next_pc);
+}

Does a[10] really get updated if the store traps?

Good catch! It does not and a tmp is required.

Cheers,
Bastian




Re: [Qemu-devel] [PATCH] qapi: add dirty bitmap status

2015-05-22 Thread Kevin Wolf
Am 21.05.2015 um 23:48 hat John Snow geschrieben:
> 
> 
> On 05/20/2015 04:20 AM, Markus Armbruster wrote:
> > John Snow  writes:
> > 
> >> On 05/12/2015 04:06 PM, Eric Blake wrote:
> >>> On 05/12/2015 01:53 PM, John Snow wrote:
>  Bitmaps can be in a handful of different states with potentially
>  more to come as we tool around with migration and persistence patches.
> 
>  Instead of having a bunch of boolean fields, it was suggested that we
>  just have an enum status field that will help expose the reason to
>  management APIs why certain bitmaps may be unavailable for various
>  commands
> 
>  (e.g. busy in another operation, busy being migrated, etc.)
> >>>
> >>> Might be worth mentioning that this is an API change, but safe because
> >>> the old API is unreleased (and therefore, this patch MUST go in the 2.4
> >>> time frame, if at all).
> >>>
> 
>  Suggested-by: Eric Blake 
>  Signed-off-by: John Snow 
>  ---
>   block.c   | 13 -
>   include/block/block.h |  1 +
>   qapi/block-core.json  | 23 +--
>   3 files changed, 34 insertions(+), 3 deletions(-)
> 
> >>>
> >>> Reviewed-by: Eric Blake 
> >>>
> >>
> >> I'm not actually sure whose tree this should go in. Markus's, perhaps?
> >>
> >> ("ping")
> > 
> > I guess the case for "Block layer core" (Kevin) is at least as strong as
> > the case for "QAPI" (me).  Kevin, what do you think?

I think bdrv_query_dirty_bitmaps() really belongs into block/qapi.c,
which is yours anyway. So it's either you as the QAPI maintainer or you
as the block submaintainer.

But if you think otherwise, I can consider it.

> His silence says "Markus, can you please do it? I discovered today that
> I don't care about this patch."

I'm sorry, John, but you didn't CC me, you didn't CC qemu-block, you
didn't CC anyone. I only had a chance to know about it since Wednesday
when Markus forwarded it, and I'm not sitting there waiting for new
patch emails because I'm bored. Rest assured, I have enough of them.

And then the forwarded email didn't even quote the patch any more, so I
couldn't just give a quick reply, but had to find the full email thread
in a different folder.

If you want to have patches applied quickly, make it easy for the
maintainers. You did the exact opposite, so you have no reason to
complain.

Kevin



[Qemu-devel] [PATCH v2 10/10] target-tricore: add RR_DIV and RR_DIV_U instructions of the v1.6 ISA

2015-05-22 Thread Bastian Koppelmann
Signed-off-by: Bastian Koppelmann 
Reviewed-by: Richard Henderson 
---
 target-tricore/helper.h  |  2 ++
 target-tricore/op_helper.c   | 49 
 target-tricore/translate.c   | 21 +
 target-tricore/tricore-opcodes.h |  2 ++
 4 files changed, 74 insertions(+)

diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index 842506c..cc221f1 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -113,6 +113,8 @@ 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)
+DEF_HELPER_3(divide, i64, env, i32, i32)
+DEF_HELPER_3(divide_u, i64, env, i32, 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 7aa1f8e..10ed541 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -2094,6 +2094,55 @@ uint64_t helper_dvstep_u(uint64_t r1, uint32_t r2)
 return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient;
 }
 
+uint64_t helper_divide(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
+{
+int32_t quotient, remainder;
+int32_t dividend = (int32_t)r1;
+int32_t divisor = (int32_t)r2;
+
+if (divisor == 0) {
+if (dividend >= 0) {
+quotient = 0x7fff;
+remainder = 0;
+} else {
+quotient = 0x8000;
+remainder = 0;
+}
+env->PSW_USB_V = (1 << 31);
+} else if ((divisor == 0x) && (dividend == 0x8000)) {
+quotient = 0x7fff;
+remainder = 0;
+env->PSW_USB_V = (1 << 31);
+} else {
+remainder = dividend % divisor;
+quotient = (dividend - remainder)/divisor;
+env->PSW_USB_V = 0;
+}
+env->PSW_USB_SV |= env->PSW_USB_V;
+env->PSW_USB_AV = 0;
+return ((uint64_t)remainder << 32) | (uint32_t)quotient;
+}
+
+uint64_t helper_divide_u(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
+{
+uint32_t quotient, remainder;
+uint32_t dividend = r1;
+uint32_t divisor = r2;
+
+if (divisor == 0) {
+quotient = 0x;
+remainder = 0;
+env->PSW_USB_V = (1 << 31);
+} else {
+remainder = dividend % divisor;
+quotient = (dividend - remainder)/divisor;
+env->PSW_USB_V = 0;
+}
+env->PSW_USB_SV |= env->PSW_USB_V;
+env->PSW_USB_AV = 0;
+return ((uint64_t)remainder << 32) | quotient;
+}
+
 uint64_t helper_mul_h(uint32_t arg00, uint32_t arg01,
   uint32_t arg10, uint32_t arg11, uint32_t n)
 {
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index d4e4226..5f8eff0 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -201,6 +201,15 @@ void tricore_cpu_dump_state(CPUState *cs, FILE *f,
 tcg_temp_free_i64(arg1); \
 } while (0)
 
+#define GEN_HELPER_RR(name, rl, rh, arg1, arg2) do {\
+TCGv_i64 ret = tcg_temp_new_i64();  \
+\
+gen_helper_##name(ret, cpu_env, arg1, arg2);\
+tcg_gen_extr_i64_i32(rl, rh, ret);  \
+\
+tcg_temp_free_i64(ret); \
+} while (0)
+
 #define EA_ABS_FORMAT(con) (((con & 0x3C000) << 14) + (con & 0x3FFF))
 #define EA_B_ABSOLUT(con) (((offset & 0xf0) << 8) | \
((offset & 0x0f) << 1))
@@ -6494,6 +6503,18 @@ static void decode_rr_divide(CPUTriCoreState *env, 
DisasContext *ctx)
 gen_helper_crc32(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
 } /* TODO: else raise illegal opcode trap */
 break;
+case OPC2_32_RR_DIV:
+if (tricore_feature(env, TRICORE_FEATURE_16)) {
+GEN_HELPER_RR(divide, cpu_gpr_d[r3], cpu_gpr_d[r3+1], 
cpu_gpr_d[r1],
+  cpu_gpr_d[r2]);
+} /* TODO: else raise illegal opcode trap */
+break;
+case OPC2_32_RR_DIV_U:
+if (tricore_feature(env, TRICORE_FEATURE_16)) {
+GEN_HELPER_RR(divide_u, cpu_gpr_d[r3], cpu_gpr_d[r3+1],
+  cpu_gpr_d[r1], cpu_gpr_d[r2]);
+} /* TODO: else raise illegal opcode trap */
+break;
 }
 }
 
diff --git a/target-tricore/tricore-opcodes.h b/target-tricore/tricore-opcodes.h
index 22c79f5..1bfed0c 100644
--- a/target-tricore/tricore-opcodes.h
+++ b/target-tricore/tricore-opcodes.h
@@ -1124,6 +1124,8 @@ enum {
 OPC2_32_RR_PARITY= 0x02,
 OPC2_32_RR_UNPACK= 0x08,
 OPC2_32_RR_CRC32  

[Qemu-devel] [PATCH v2 01/10] target-tricore: Add ISA v1.3.1 cpu and fix tc1796 to using v1.3

2015-05-22 Thread Bastian Koppelmann
Signed-off-by: Bastian Koppelmann 
Reviewed-by: Richard Henderson 
---
 target-tricore/cpu.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/target-tricore/cpu.c b/target-tricore/cpu.c
index 2ba0cf4..9fe0b97 100644
--- a/target-tricore/cpu.c
+++ b/target-tricore/cpu.c
@@ -118,6 +118,13 @@ static void tc1796_initfn(Object *obj)
 {
 TriCoreCPU *cpu = TRICORE_CPU(obj);
 
+set_feature(&cpu->env, TRICORE_FEATURE_13);
+}
+
+static void tc1797_initfn(Object *obj)
+{
+TriCoreCPU *cpu = TRICORE_CPU(obj);
+
 set_feature(&cpu->env, TRICORE_FEATURE_131);
 }
 
@@ -136,6 +143,7 @@ typedef struct TriCoreCPUInfo {
 
 static const TriCoreCPUInfo tricore_cpus[] = {
 { .name = "tc1796",  .initfn = tc1796_initfn },
+{ .name = "tc1797",  .initfn = tc1797_initfn },
 { .name = "aurix",   .initfn = aurix_initfn },
 { .name = NULL }
 };
-- 
2.4.1




[Qemu-devel] [PATCH v2 03/10] target-tricore: Add SRC_MOV_E instruction of the v1.6 ISA

2015-05-22 Thread Bastian Koppelmann
Signed-off-by: Bastian Koppelmann 
Reviewed-by: Richard Henderson 
---
 target-tricore/translate.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 663b2a0..1c37e48 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -3485,7 +3485,7 @@ static void gen_compute_branch(DisasContext *ctx, 
uint32_t opc, int r1,
  * Functions for decoding instructions
  */
 
-static void decode_src_opc(DisasContext *ctx, int op1)
+static void decode_src_opc(CPUTriCoreState *env, DisasContext *ctx, int op1)
 {
 int r1;
 int32_t const4;
@@ -3546,6 +3546,12 @@ static void decode_src_opc(DisasContext *ctx, int op1)
 const4 = MASK_OP_SRC_CONST4(ctx->opcode);
 tcg_gen_movi_tl(cpu_gpr_a[r1], const4);
 break;
+case OPC1_16_SRC_MOV_E:
+if (tricore_feature(env, TRICORE_FEATURE_16)) {
+tcg_gen_movi_tl(cpu_gpr_d[r1], const4);
+tcg_gen_sari_tl(cpu_gpr_d[r1+1], cpu_gpr_d[r1], 31);
+} /* TODO: else raise illegal opcode trap */
+break;
 case OPC1_16_SRC_SH:
 gen_shi(cpu_gpr_d[r1], cpu_gpr_d[r1], const4);
 break;
@@ -3883,9 +3889,10 @@ static void decode_16Bit_opc(CPUTriCoreState *env, 
DisasContext *ctx)
 case OPC1_16_SRC_LT:
 case OPC1_16_SRC_MOV:
 case OPC1_16_SRC_MOV_A:
+case OPC1_16_SRC_MOV_E:
 case OPC1_16_SRC_SH:
 case OPC1_16_SRC_SHA:
-decode_src_opc(ctx, op1);
+decode_src_opc(env, ctx, op1);
 break;
 /* SRR-format */
 case OPC1_16_SRR_ADD:
-- 
2.4.1




[Qemu-devel] [PATCH v2 08/10] target-tricore: add FCALL instructions of the v1.6 ISA

2015-05-22 Thread Bastian Koppelmann
Signed-off-by: Bastian Koppelmann 
---
v1 -> v2:
- gen_fcall_save_ctx now uses a temp for the a[10] register, so this does 
  not get updated if the store traps.

 target-tricore/translate.c   | 26 ++
 target-tricore/tricore-opcodes.h |  3 +++
 2 files changed, 29 insertions(+)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 4aea0c6..76bab8e 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -3275,6 +3275,18 @@ static void gen_loop(DisasContext *ctx, int r1, int32_t 
offset)
 gen_goto_tb(ctx, 0, ctx->next_pc);
 }
 
+static void gen_fcall_save_ctx(DisasContext *ctx)
+{
+TCGv temp = tcg_temp_new();
+
+tcg_gen_addi_tl(temp, cpu_gpr_a[10], -4);
+tcg_gen_qemu_st_tl(cpu_gpr_a[11], temp, ctx->mem_idx, MO_LESL);
+tcg_gen_movi_tl(cpu_gpr_a[11], ctx->next_pc);
+tcg_gen_mov_tl(cpu_gpr_a[10], temp);
+
+tcg_temp_free(temp);
+}
+
 static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1,
int r2 , int32_t constant , int32_t offset)
 {
@@ -3369,6 +3381,14 @@ static void gen_compute_branch(DisasContext *ctx, 
uint32_t opc, int r1,
 gen_helper_1arg(call, ctx->next_pc);
 gen_goto_tb(ctx, 0, EA_B_ABSOLUT(offset));
 break;
+case OPC1_32_B_FCALL:
+gen_fcall_save_ctx(ctx);
+gen_goto_tb(ctx, 0, ctx->pc + offset * 2);
+break;
+case OPC1_32_B_FCALLA:
+gen_fcall_save_ctx(ctx);
+gen_goto_tb(ctx, 0, EA_B_ABSOLUT(offset));
+break;
 case OPC1_32_B_JLA:
 tcg_gen_movi_tl(cpu_gpr_a[11], ctx->next_pc);
 /* fall through */
@@ -6311,6 +6331,10 @@ static void decode_rr_idirect(CPUTriCoreState *env, 
DisasContext *ctx)
 gen_helper_1arg(call, ctx->next_pc);
 tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], ~0x1);
 break;
+case OPC2_32_RR_FCALLI:
+gen_fcall_save_ctx(ctx);
+tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], ~0x1);
+break;
 }
 tcg_gen_exit_tb(0);
 ctx->bstate = BS_BRANCH;
@@ -7946,6 +7970,8 @@ static void decode_32Bit_opc(CPUTriCoreState *env, 
DisasContext *ctx)
 /* B-format */
 case OPC1_32_B_CALL:
 case OPC1_32_B_CALLA:
+case OPC1_32_B_FCALL:
+case OPC1_32_B_FCALLA:
 case OPC1_32_B_J:
 case OPC1_32_B_JA:
 case OPC1_32_B_JL:
diff --git a/target-tricore/tricore-opcodes.h b/target-tricore/tricore-opcodes.h
index d1506a9..bb1939c 100644
--- a/target-tricore/tricore-opcodes.h
+++ b/target-tricore/tricore-opcodes.h
@@ -428,6 +428,8 @@ enum {
 /* B Format */
 OPC1_32_B_CALL   = 0x6d,
 OPC1_32_B_CALLA  = 0xed,
+OPC1_32_B_FCALL  = 0x61,
+OPC1_32_B_FCALLA = 0xe1,
 OPC1_32_B_J  = 0x1d,
 OPC1_32_B_JA = 0x9d,
 OPC1_32_B_JL = 0x5d,
@@ -1127,6 +1129,7 @@ enum {
 OPC2_32_RR_JI= 0x03,
 OPC2_32_RR_JLI   = 0x02,
 OPC2_32_RR_CALLI = 0x00,
+OPC2_32_RR_FCALLI= 0x01,
 };
 /*
  * RR1 Format
-- 
2.4.1




[Qemu-devel] [PATCH v2 02/10] target-tricore: introduce ISA v1.6.1 feature

2015-05-22 Thread Bastian Koppelmann
The aurix platform contains of several different cpu models and uses
the 1.6.1 ISA. This patch changes the generic aurix model to the more
specific tc27x cpu model and sets specific features.

Signed-off-by: Bastian Koppelmann 
Reviewed-by: Richard Henderson 
---
 target-tricore/cpu.c | 10 +++---
 target-tricore/cpu.h |  1 +
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/target-tricore/cpu.c b/target-tricore/cpu.c
index 9fe0b97..b3e5512 100644
--- a/target-tricore/cpu.c
+++ b/target-tricore/cpu.c
@@ -68,6 +68,10 @@ static void tricore_cpu_realizefn(DeviceState *dev, Error 
**errp)
 CPUTriCoreState *env = &cpu->env;
 
 /* Some features automatically imply others */
+if (tricore_feature(env, TRICORE_FEATURE_161)) {
+set_feature(env, TRICORE_FEATURE_16);
+}
+
 if (tricore_feature(env, TRICORE_FEATURE_16)) {
 set_feature(env, TRICORE_FEATURE_131);
 }
@@ -128,11 +132,11 @@ static void tc1797_initfn(Object *obj)
 set_feature(&cpu->env, TRICORE_FEATURE_131);
 }
 
-static void aurix_initfn(Object *obj)
+static void tc27x_initfn(Object *obj)
 {
 TriCoreCPU *cpu = TRICORE_CPU(obj);
 
-set_feature(&cpu->env, TRICORE_FEATURE_16);
+set_feature(&cpu->env, TRICORE_FEATURE_161);
 }
 
 typedef struct TriCoreCPUInfo {
@@ -144,7 +148,7 @@ typedef struct TriCoreCPUInfo {
 static const TriCoreCPUInfo tricore_cpus[] = {
 { .name = "tc1796",  .initfn = tc1796_initfn },
 { .name = "tc1797",  .initfn = tc1797_initfn },
-{ .name = "aurix",   .initfn = aurix_initfn },
+{ .name = "tc27x",   .initfn = tc27x_initfn },
 { .name = NULL }
 };
 
diff --git a/target-tricore/cpu.h b/target-tricore/cpu.h
index c14b5f9..504f156 100644
--- a/target-tricore/cpu.h
+++ b/target-tricore/cpu.h
@@ -254,6 +254,7 @@ enum tricore_features {
 TRICORE_FEATURE_13,
 TRICORE_FEATURE_131,
 TRICORE_FEATURE_16,
+TRICORE_FEATURE_161,
 };
 
 static inline int tricore_feature(CPUTriCoreState *env, int feature)
-- 
2.4.1




[Qemu-devel] [PATCH v2 00/10] TriCore v1.6.1 ISA and missing v1.6 instructions

2015-05-22 Thread Bastian Koppelmann
Hi,

the new Aurix platform introduces a new ISA version, so this patchset
adds a new feature bit and changes the generic Aurix cpu to a more specific
tc27x cpu model. While at this, it introduces a new cpu model tc1797 which
uses the v1.3.1 ISA and fixes the tc1796 to us the v1.3 ISA.

It also adds the with v1.6.1 introduces instructions cmpswap, swapmsk and
crc32. While at this, it adds the missing instructions of the v1.6 ISA.

Cheers,
Bastian

v1->v2:
- FRET and FCALL don't create a wrong register state anymore, if the load 
traps.

Bastian Koppelmann (10):
  target-tricore: Add ISA v1.3.1 cpu and fix tc1796 to using v1.3
  target-tricore: introduce ISA v1.6.1 feature
  target-tricore: Add SRC_MOV_E instruction of the v1.6 ISA
  target-tricore: add CMPSWP instructions of the v1.6.1 ISA
  target-tricore: add SWAPMSK instructions of the v1.6.1 ISA
  target-tricore: add RR_CRC32 instruction of the v1.6.1 ISA
  target-tricore: add SYS_RESTORE instruction of the v1.6 ISA
  target-tricore: add FCALL instructions of the v1.6 ISA
  target-tricore: add FRET instructions of the v1.6 ISA
  target-tricore: add RR_DIV and RR_DIV_U instructions of the v1.6 ISA

 target-tricore/cpu.c |  18 -
 target-tricore/cpu.h |   1 +
 target-tricore/helper.h  |   4 +
 target-tricore/op_helper.c   |  60 ++
 target-tricore/translate.c   | 166 ++-
 target-tricore/tricore-opcodes.h |  19 +
 6 files changed, 263 insertions(+), 5 deletions(-)

-- 
2.4.1




[Qemu-devel] [PATCH v2 05/10] target-tricore: add SWAPMSK instructions of the v1.6.1 ISA

2015-05-22 Thread Bastian Koppelmann
Those instruction were introduced in the new Aurix platform.

Signed-off-by: Bastian Koppelmann 
Reviewed-by: Richard Henderson 
---
 target-tricore/translate.c   | 39 +++
 target-tricore/tricore-opcodes.h |  5 +
 2 files changed, 44 insertions(+)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 06d183b..b2e25e7 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -333,6 +333,25 @@ static void gen_cmpswap(DisasContext *ctx, int reg, TCGv 
ea)
 tcg_temp_free(temp2);
 }
 
+static void gen_swapmsk(DisasContext *ctx, int reg, TCGv ea)
+{
+TCGv temp = tcg_temp_new();
+TCGv temp2 = tcg_temp_new();
+TCGv temp3 = tcg_temp_new();
+
+tcg_gen_qemu_ld_tl(temp, ea, ctx->mem_idx, MO_LEUL);
+tcg_gen_and_tl(temp2, cpu_gpr_d[reg], cpu_gpr_d[reg+1]);
+tcg_gen_andc_tl(temp3, temp, cpu_gpr_d[reg+1]);
+tcg_gen_or_tl(temp2, temp2, temp3);
+tcg_gen_qemu_st_tl(temp2, ea, ctx->mem_idx, MO_LEUL);
+tcg_gen_mov_tl(cpu_gpr_d[reg], temp);
+
+tcg_temp_free(temp);
+tcg_temp_free(temp2);
+tcg_temp_free(temp3);
+}
+
+
 /* We generate loads and store to core special function register (csfr) through
the function gen_mfcr and gen_mtcr. To handle access permissions, we use 3
makros R, A and E, which allow read-only, all and endinit protected access.
@@ -5072,6 +5091,18 @@ static void 
decode_bo_addrmode_stctx_post_pre_base(CPUTriCoreState *env,
 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
 gen_cmpswap(ctx, r1, cpu_gpr_a[r2]);
 break;
+case OPC2_32_BO_SWAPMSK_W_SHORTOFF:
+tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10);
+gen_swapmsk(ctx, r1, temp);
+break;
+case OPC2_32_BO_SWAPMSK_W_POSTINC:
+gen_swapmsk(ctx, r1, cpu_gpr_a[r2]);
+tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
+break;
+case OPC2_32_BO_SWAPMSK_W_PREINC:
+tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
+gen_swapmsk(ctx, r1, cpu_gpr_a[r2]);
+break;
 }
 tcg_temp_free(temp);
 tcg_temp_free(temp2);
@@ -5123,6 +5154,14 @@ static void 
decode_bo_addrmode_ldmst_bitreverse_circular(CPUTriCoreState *env,
 gen_cmpswap(ctx, r1, temp2);
 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3);
 break;
+case OPC2_32_BO_SWAPMSK_W_BR:
+gen_swapmsk(ctx, r1, temp2);
+gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
+break;
+case OPC2_32_BO_SWAPMSK_W_CIRC:
+gen_swapmsk(ctx, r1, temp2);
+gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3);
+break;
 }
 
 tcg_temp_free(temp);
diff --git a/target-tricore/tricore-opcodes.h b/target-tricore/tricore-opcodes.h
index 95837aa..7ad6df9 100644
--- a/target-tricore/tricore-opcodes.h
+++ b/target-tricore/tricore-opcodes.h
@@ -766,6 +766,9 @@ enum {
 OPC2_32_BO_CMPSWAP_W_SHORTOFF= 0x23,
 OPC2_32_BO_CMPSWAP_W_POSTINC = 0x03,
 OPC2_32_BO_CMPSWAP_W_PREINC  = 0x13,
+OPC2_32_BO_SWAPMSK_W_SHORTOFF= 0x22,
+OPC2_32_BO_SWAPMSK_W_POSTINC = 0x02,
+OPC2_32_BO_SWAPMSK_W_PREINC  = 0x12,
 };
 /*OPCM_32_BO_ADDRMODE_LDMST_BITREVERSE_CIRCULAR  */
 enum {
@@ -775,6 +778,8 @@ enum {
 OPC2_32_BO_SWAP_W_CIRC   = 0x10,
 OPC2_32_BO_CMPSWAP_W_BR  = 0x03,
 OPC2_32_BO_CMPSWAP_W_CIRC= 0x13,
+OPC2_32_BO_SWAPMSK_W_BR  = 0x02,
+OPC2_32_BO_SWAPMSK_W_CIRC= 0x12,
 };
 /*
  * BRC Format
-- 
2.4.1




[Qemu-devel] [PATCH v2 09/10] target-tricore: add FRET instructions of the v1.6 ISA

2015-05-22 Thread Bastian Koppelmann
Signed-off-by: Bastian Koppelmann 
---
v1 -> v2:
- gen_fret uses a temp now, so the PC does not get updated if the load 
traps.
 target-tricore/translate.c   | 19 +++
 target-tricore/tricore-opcodes.h |  2 ++
 2 files changed, 21 insertions(+)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 76bab8e..d4e4226 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -3287,6 +3287,20 @@ static void gen_fcall_save_ctx(DisasContext *ctx)
 tcg_temp_free(temp);
 }
 
+static void gen_fret(DisasContext *ctx)
+{
+TCGv temp = tcg_temp_new();
+
+tcg_gen_andi_tl(temp, cpu_gpr_a[11], ~0x1);
+tcg_gen_qemu_ld_tl(cpu_gpr_a[11], cpu_gpr_a[10], ctx->mem_idx, MO_LESL);
+tcg_gen_addi_tl(cpu_gpr_a[10], cpu_gpr_a[10], 4);
+tcg_gen_mov_tl(cpu_PC, temp);
+tcg_gen_exit_tb(0);
+ctx->bstate = BS_BRANCH;
+
+tcg_temp_free(temp);
+}
+
 static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1,
int r2 , int32_t constant , int32_t offset)
 {
@@ -3869,6 +3883,8 @@ static void decode_sr_system(CPUTriCoreState *env, 
DisasContext *ctx)
 case OPC2_16_SR_DEBUG:
 /* raise EXCP_DEBUG */
 break;
+case OPC2_16_SR_FRET:
+gen_fret(ctx);
 }
 }
 
@@ -7842,6 +7858,9 @@ static void decode_sys_interrupts(CPUTriCoreState *env, 
DisasContext *ctx)
 case OPC2_32_SYS_RET:
 gen_compute_branch(ctx, op2, 0, 0, 0, 0);
 break;
+case OPC2_32_SYS_FRET:
+gen_fret(ctx);
+break;
 case OPC2_32_SYS_RFE:
 gen_helper_rfe(cpu_env);
 tcg_gen_exit_tb(0);
diff --git a/target-tricore/tricore-opcodes.h b/target-tricore/tricore-opcodes.h
index bb1939c..22c79f5 100644
--- a/target-tricore/tricore-opcodes.h
+++ b/target-tricore/tricore-opcodes.h
@@ -399,6 +399,7 @@ enum {
 OPC2_16_SR_RET   = 0x09,
 OPC2_16_SR_RFE   = 0x08,
 OPC2_16_SR_DEBUG = 0x0a,
+OPC2_16_SR_FRET  = 0x07,
 };
 /* OPCM_16_SR_ACCU   */
 enum {
@@ -1438,4 +1439,5 @@ enum {
 OPC2_32_SYS_TRAPSV   = 0x15,
 OPC2_32_SYS_TRAPV= 0x14,
 OPC2_32_SYS_RESTORE  = 0x0e,
+OPC2_32_SYS_FRET = 0x03,
 };
-- 
2.4.1




[Qemu-devel] [PATCH v2 06/10] target-tricore: add RR_CRC32 instruction of the v1.6.1 ISA

2015-05-22 Thread Bastian Koppelmann
This instruction was introduced by the new Aurix platform.

Signed-off-by: Bastian Koppelmann 
Reviewed-by: Richard Henderson 
---
 target-tricore/helper.h  |  2 ++
 target-tricore/op_helper.c   | 11 +++
 target-tricore/translate.c   |  5 +
 target-tricore/tricore-opcodes.h |  1 +
 4 files changed, 19 insertions(+)

diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index 1a49b00..842506c 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -117,6 +117,8 @@ DEF_HELPER_FLAGS_2(dvstep_u, TCG_CALL_NO_RWG_SE, i64, i64, 
i32)
 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)
 DEF_HELPER_FLAGS_5(mulr_h, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32, i32, i32)
+/* crc32 */
+DEF_HELPER_FLAGS_2(crc32, TCG_CALL_NO_RWG_SE, i32, i32, i32)
 /* CSA */
 DEF_HELPER_2(call, void, env, i32)
 DEF_HELPER_1(ret, void, env)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index 9919b5b..7aa1f8e 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -19,6 +19,7 @@
 #include "qemu/host-utils.h"
 #include "exec/helper-proto.h"
 #include "exec/cpu_ldst.h"
+#include  /* for crc32 */
 
 /* Addressing mode helper */
 
@@ -2165,6 +2166,16 @@ uint32_t helper_mulr_h(uint32_t arg00, uint32_t arg01,
 return (result1 & 0x) | (result0 >> 16);
 }
 
+uint32_t helper_crc32(uint32_t arg0, uint32_t arg1)
+{
+uint8_t buf[4];
+uint32_t ret;
+stl_be_p(buf, arg0);
+
+ret = crc32(arg1, buf, 4);
+return ret;
+}
+
 /* context save area (CSA) related helpers */
 
 static int cdc_increment(target_ulong *psw)
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index b2e25e7..52f474b 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -6449,6 +6449,11 @@ static void decode_rr_divide(CPUTriCoreState *env, 
DisasContext *ctx)
 case OPC2_32_RR_UNPACK:
 gen_unpack(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1]);
 break;
+case OPC2_32_RR_CRC32:
+if (tricore_feature(env, TRICORE_FEATURE_161)) {
+gen_helper_crc32(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+} /* TODO: else raise illegal opcode trap */
+break;
 }
 }
 
diff --git a/target-tricore/tricore-opcodes.h b/target-tricore/tricore-opcodes.h
index 7ad6df9..440c7fe 100644
--- a/target-tricore/tricore-opcodes.h
+++ b/target-tricore/tricore-opcodes.h
@@ -1120,6 +1120,7 @@ enum {
 OPC2_32_RR_DVINIT_U  = 0x0a,
 OPC2_32_RR_PARITY= 0x02,
 OPC2_32_RR_UNPACK= 0x08,
+OPC2_32_RR_CRC32 = 0x03,
 };
 /* OPCM_32_RR_IDIRECT   */
 enum {
-- 
2.4.1




[Qemu-devel] [PATCH v2 07/10] target-tricore: add SYS_RESTORE instruction of the v1.6 ISA

2015-05-22 Thread Bastian Koppelmann
Signed-off-by: Bastian Koppelmann 
Reviewed-by: Richard Henderson 
---
 target-tricore/translate.c   | 10 ++
 target-tricore/tricore-opcodes.h |  1 +
 2 files changed, 11 insertions(+)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 52f474b..4aea0c6 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -7792,10 +7792,12 @@ static void decode_rrrw_extract_insert(CPUTriCoreState 
*env, DisasContext *ctx)
 static void decode_sys_interrupts(CPUTriCoreState *env, DisasContext *ctx)
 {
 uint32_t op2;
+uint32_t r1;
 TCGLabel *l1;
 TCGv tmp;
 
 op2 = MASK_OP_SYS_OP2(ctx->opcode);
+r1  = MASK_OP_SYS_S1D(ctx->opcode);
 
 switch (op2) {
 case OPC2_32_SYS_DEBUG:
@@ -7844,6 +7846,14 @@ static void decode_sys_interrupts(CPUTriCoreState *env, 
DisasContext *ctx)
 case OPC2_32_SYS_SVLCX:
 gen_helper_svlcx(cpu_env);
 break;
+case OPC2_32_SYS_RESTORE:
+if (tricore_feature(env, TRICORE_FEATURE_16)) {
+if ((ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_SM ||
+(ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_UM1) {
+tcg_gen_deposit_tl(cpu_ICR, cpu_ICR, cpu_gpr_d[r1], 8, 1);
+} /* else raise privilege trap */
+} /* else raise illegal opcode trap */
+break;
 case OPC2_32_SYS_TRAPSV:
 /* TODO: raise sticky overflow trap */
 break;
diff --git a/target-tricore/tricore-opcodes.h b/target-tricore/tricore-opcodes.h
index 440c7fe..d1506a9 100644
--- a/target-tricore/tricore-opcodes.h
+++ b/target-tricore/tricore-opcodes.h
@@ -1434,4 +1434,5 @@ enum {
 OPC2_32_SYS_SVLCX= 0x08,
 OPC2_32_SYS_TRAPSV   = 0x15,
 OPC2_32_SYS_TRAPV= 0x14,
+OPC2_32_SYS_RESTORE  = 0x0e,
 };
-- 
2.4.1




[Qemu-devel] [PATCH v2 04/10] target-tricore: add CMPSWP instructions of the v1.6.1 ISA

2015-05-22 Thread Bastian Koppelmann
Those instruction were introduced in the new Aurix platform.

Signed-off-by: Bastian Koppelmann 
Reviewed-by: Richard Henderson 
---
 target-tricore/translate.c   | 35 +++
 target-tricore/tricore-opcodes.h |  5 +
 2 files changed, 40 insertions(+)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 1c37e48..06d183b 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -319,6 +319,20 @@ static void gen_swap(DisasContext *ctx, int reg, TCGv ea)
 tcg_temp_free(temp);
 }
 
+static void gen_cmpswap(DisasContext *ctx, int reg, TCGv ea)
+{
+TCGv temp = tcg_temp_new();
+TCGv temp2 = tcg_temp_new();
+tcg_gen_qemu_ld_tl(temp, ea, ctx->mem_idx, MO_LEUL);
+tcg_gen_movcond_tl(TCG_COND_EQ, temp2, cpu_gpr_d[reg+1], temp,
+   cpu_gpr_d[reg], temp);
+tcg_gen_qemu_st_tl(temp2, ea, ctx->mem_idx, MO_LEUL);
+tcg_gen_mov_tl(cpu_gpr_d[reg], temp);
+
+tcg_temp_free(temp);
+tcg_temp_free(temp2);
+}
+
 /* We generate loads and store to core special function register (csfr) through
the function gen_mfcr and gen_mtcr. To handle access permissions, we use 3
makros R, A and E, which allow read-only, all and endinit protected access.
@@ -5046,6 +5060,18 @@ static void 
decode_bo_addrmode_stctx_post_pre_base(CPUTriCoreState *env,
 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
 gen_swap(ctx, r1, cpu_gpr_a[r2]);
 break;
+case OPC2_32_BO_CMPSWAP_W_SHORTOFF:
+tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10);
+gen_cmpswap(ctx, r1, temp);
+break;
+case OPC2_32_BO_CMPSWAP_W_POSTINC:
+gen_cmpswap(ctx, r1, cpu_gpr_a[r2]);
+tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
+break;
+case OPC2_32_BO_CMPSWAP_W_PREINC:
+tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
+gen_cmpswap(ctx, r1, cpu_gpr_a[r2]);
+break;
 }
 tcg_temp_free(temp);
 tcg_temp_free(temp2);
@@ -5089,7 +5115,16 @@ static void 
decode_bo_addrmode_ldmst_bitreverse_circular(CPUTriCoreState *env,
 gen_swap(ctx, r1, temp2);
 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3);
 break;
+case OPC2_32_BO_CMPSWAP_W_BR:
+gen_cmpswap(ctx, r1, temp2);
+gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
+break;
+case OPC2_32_BO_CMPSWAP_W_CIRC:
+gen_cmpswap(ctx, r1, temp2);
+gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3);
+break;
 }
+
 tcg_temp_free(temp);
 tcg_temp_free(temp2);
 tcg_temp_free(temp3);
diff --git a/target-tricore/tricore-opcodes.h b/target-tricore/tricore-opcodes.h
index 2291f75..95837aa 100644
--- a/target-tricore/tricore-opcodes.h
+++ b/target-tricore/tricore-opcodes.h
@@ -763,6 +763,9 @@ enum {
 OPC2_32_BO_SWAP_W_SHORTOFF   = 0x20,
 OPC2_32_BO_SWAP_W_POSTINC= 0x00,
 OPC2_32_BO_SWAP_W_PREINC = 0x10,
+OPC2_32_BO_CMPSWAP_W_SHORTOFF= 0x23,
+OPC2_32_BO_CMPSWAP_W_POSTINC = 0x03,
+OPC2_32_BO_CMPSWAP_W_PREINC  = 0x13,
 };
 /*OPCM_32_BO_ADDRMODE_LDMST_BITREVERSE_CIRCULAR  */
 enum {
@@ -770,6 +773,8 @@ enum {
 OPC2_32_BO_LDMST_CIRC= 0x11,
 OPC2_32_BO_SWAP_W_BR = 0x00,
 OPC2_32_BO_SWAP_W_CIRC   = 0x10,
+OPC2_32_BO_CMPSWAP_W_BR  = 0x03,
+OPC2_32_BO_CMPSWAP_W_CIRC= 0x13,
 };
 /*
  * BRC Format
-- 
2.4.1




Re: [Qemu-devel] [PATCH] qapi: add dirty bitmap status

2015-05-22 Thread Markus Armbruster
Kevin Wolf  writes:

> Am 21.05.2015 um 23:48 hat John Snow geschrieben:
>> 
>> 
>> On 05/20/2015 04:20 AM, Markus Armbruster wrote:
>> > John Snow  writes:
>> > 
>> >> On 05/12/2015 04:06 PM, Eric Blake wrote:
>> >>> On 05/12/2015 01:53 PM, John Snow wrote:
>>  Bitmaps can be in a handful of different states with potentially
>>  more to come as we tool around with migration and persistence patches.
>> 
>>  Instead of having a bunch of boolean fields, it was suggested that we
>>  just have an enum status field that will help expose the reason to
>>  management APIs why certain bitmaps may be unavailable for various
>>  commands
>> 
>>  (e.g. busy in another operation, busy being migrated, etc.)
>> >>>
>> >>> Might be worth mentioning that this is an API change, but safe because
>> >>> the old API is unreleased (and therefore, this patch MUST go in the 2.4
>> >>> time frame, if at all).
>> >>>
>> 
>>  Suggested-by: Eric Blake 
>>  Signed-off-by: John Snow 
>>  ---
>>   block.c   | 13 -
>>   include/block/block.h |  1 +
>>   qapi/block-core.json  | 23 +--
>>   3 files changed, 34 insertions(+), 3 deletions(-)
>> 
>> >>>
>> >>> Reviewed-by: Eric Blake 
>> >>>
>> >>
>> >> I'm not actually sure whose tree this should go in. Markus's, perhaps?
>> >>
>> >> ("ping")
>> > 
>> > I guess the case for "Block layer core" (Kevin) is at least as strong as
>> > the case for "QAPI" (me).  Kevin, what do you think?
>
> I think bdrv_query_dirty_bitmaps() really belongs into block/qapi.c,
> which is yours anyway. So it's either you as the QAPI maintainer or you
> as the block submaintainer.

s/the block submaintainer/the newly minted block submaintainer/

> But if you think otherwise, I can consider it.
>
>> His silence says "Markus, can you please do it? I discovered today that
>> I don't care about this patch."
>
> I'm sorry, John, but you didn't CC me, you didn't CC qemu-block, you
> didn't CC anyone. I only had a chance to know about it since Wednesday
> when Markus forwarded it, and I'm not sitting there waiting for new
> patch emails because I'm bored. Rest assured, I have enough of them.
>
> And then the forwarded email didn't even quote the patch any more, so I
> couldn't just give a quick reply, but had to find the full email thread
> in a different folder.
>
> If you want to have patches applied quickly, make it easy for the
> maintainers. You did the exact opposite, so you have no reason to
> complain.

On the other hand, his "complaining" made me smile, which I appreciate :)

Don't worry, John, I'll take it through my tree.



Re: [Qemu-devel] [PATCH] qapi: add dirty bitmap status

2015-05-22 Thread Markus Armbruster
Eric Blake  writes:

> On 05/12/2015 01:53 PM, John Snow wrote:
>> Bitmaps can be in a handful of different states with potentially
>> more to come as we tool around with migration and persistence patches.
>> 
>> Instead of having a bunch of boolean fields, it was suggested that we
>> just have an enum status field that will help expose the reason to
>> management APIs why certain bitmaps may be unavailable for various
>> commands
>> 
>> (e.g. busy in another operation, busy being migrated, etc.)
>
> Might be worth mentioning that this is an API change, but safe because
> the old API is unreleased (and therefore, this patch MUST go in the 2.4
> time frame, if at all).
>
>> 
>> Suggested-by: Eric Blake 
>> Signed-off-by: John Snow 
>> ---
>>  block.c   | 13 -
>>  include/block/block.h |  1 +
>>  qapi/block-core.json  | 23 +--
>>  3 files changed, 34 insertions(+), 3 deletions(-)
>> 
>
> Reviewed-by: Eric Blake 

Patch does two things:

1. Convert status from bool frozen to enum.
2. Add new status 'disabled'.

I would've done this separately, but it's no big deal.  But I think we
should spell it out in the commit message.

What about:

qapi: add dirty bitmap status

Bitmaps can be in a handful of different states with potentially
more to come as we tool around with migration and persistence patches.

Management applications may need to know why certain bitmaps are
unavailable for various commands, e.g. busy in another operation,
busy being migrated, etc.

Right now, all we offer is BlockDirtyInfo's boolean member 'frozen'.
Instead of adding more booleans, replace it by an enumeration member
'status' with values 'active' and 'frozen'.  Then add new value
'disabled'.

Incompatible change.  Fine because the changed part hasn't been
released so far.

Suggested-by: Eric Blake 
Signed-off-by: John Snow 
Reviewed-by: Eric Blake 
[Commit message tweaked]
Signed-off-by: Markus Armbruster 



[Qemu-devel] [PULL 02/38] block/parallels: rename parallels_header to ParallelsHeader

2015-05-22 Thread Stefan Hajnoczi
From: "Denis V. Lunev" 

this follows QEMU coding convention

Signed-off-by: Denis V. Lunev 
Reviewed-by: Roman Kagan 
Reviewed-by: Stefan Hajnoczi 
Message-id: 1430207220-24458-3-git-send-email-...@openvz.org
CC: Kevin Wolf 
Signed-off-by: Stefan Hajnoczi 
---
 block/parallels.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/block/parallels.c b/block/parallels.c
index 4f9cd8d..dca0df6 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -35,7 +35,7 @@
 #define HEADER_SIZE 64
 
 // always little-endian
-struct parallels_header {
+typedef struct ParallelsHeader {
 char magic[16]; // "WithoutFreeSpace"
 uint32_t version;
 uint32_t heads;
@@ -46,7 +46,7 @@ struct parallels_header {
 uint32_t inuse;
 uint32_t data_off;
 char padding[12];
-} QEMU_PACKED;
+} QEMU_PACKED ParallelsHeader;
 
 typedef struct BDRVParallelsState {
 CoMutex lock;
@@ -61,7 +61,7 @@ typedef struct BDRVParallelsState {
 
 static int parallels_probe(const uint8_t *buf, int buf_size, const char 
*filename)
 {
-const struct parallels_header *ph = (const void *)buf;
+const ParallelsHeader *ph = (const void *)buf;
 
 if (buf_size < HEADER_SIZE)
 return 0;
@@ -79,7 +79,7 @@ static int parallels_open(BlockDriverState *bs, QDict 
*options, int flags,
 {
 BDRVParallelsState *s = bs->opaque;
 int i;
-struct parallels_header ph;
+ParallelsHeader ph;
 int ret;
 
 bs->read_only = 1; // no write support yet
-- 
2.1.0




[Qemu-devel] [PULL 05/38] block/parallels: add get_block_status

2015-05-22 Thread Stefan Hajnoczi
From: Roman Kagan 

Implement VFS method for get_block_status to Parallels format driver.

qemu_co_mutex_lock is not necessary yet (the driver is read-only) but
will be necessary very soon when write will be supported.

Signed-off-by: Roman Kagan 
Reviewed-by: Denis V. Lunev 
Signed-off-by: Denis V. Lunev 
Message-id: 1430207220-24458-6-git-send-email-...@openvz.org
CC: Kevin Wolf 
CC: Stefan Hajnoczi 
Signed-off-by: Stefan Hajnoczi 
---
 block/parallels.c | 21 +
 1 file changed, 21 insertions(+)

diff --git a/block/parallels.c b/block/parallels.c
index 8770c82..b469984 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -166,6 +166,26 @@ static int cluster_remainder(BDRVParallelsState *s, 
int64_t sector_num,
 return MIN(nb_sectors, ret);
 }
 
+static int64_t coroutine_fn parallels_co_get_block_status(BlockDriverState *bs,
+int64_t sector_num, int nb_sectors, int *pnum)
+{
+BDRVParallelsState *s = bs->opaque;
+int64_t offset;
+
+qemu_co_mutex_lock(&s->lock);
+offset = seek_to_sector(s, sector_num);
+qemu_co_mutex_unlock(&s->lock);
+
+*pnum = cluster_remainder(s, sector_num, nb_sectors);
+
+if (offset < 0) {
+return 0;
+}
+
+return (offset << BDRV_SECTOR_BITS) |
+BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
+}
+
 static int parallels_read(BlockDriverState *bs, int64_t sector_num,
 uint8_t *buf, int nb_sectors)
 {
@@ -213,6 +233,7 @@ static BlockDriver bdrv_parallels = {
 .bdrv_open = parallels_open,
 .bdrv_read  = parallels_co_read,
 .bdrv_close= parallels_close,
+.bdrv_co_get_block_status = parallels_co_get_block_status,
 };
 
 static void bdrv_parallels_init(void)
-- 
2.1.0




[Qemu-devel] [PULL 01/38] iotests, parallels: quote TEST_IMG in 076 test to be path-safe

2015-05-22 Thread Stefan Hajnoczi
From: "Denis V. Lunev" 

suggested by Jeff Cody

Signed-off-by: Denis V. Lunev 
Reviewed-by: Roman Kagan 
Reviewed-by: Stefan Hajnoczi 
Message-id: 1430207220-24458-2-git-send-email-...@openvz.org
CC: Kevin Wolf 
Signed-off-by: Stefan Hajnoczi 
---
 tests/qemu-iotests/076 | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/tests/qemu-iotests/076 b/tests/qemu-iotests/076
index ed2be35..0139976 100755
--- a/tests/qemu-iotests/076
+++ b/tests/qemu-iotests/076
@@ -49,31 +49,31 @@ nb_sectors_offset=$((0x24))
 echo
 echo "== Read from a valid v1 image =="
 _use_sample_img parallels-v1.bz2
-{ $QEMU_IO -c "read -P 0x11 0 64k" $TEST_IMG; } 2>&1 | _filter_qemu_io | 
_filter_testdir
+{ $QEMU_IO -c "read -P 0x11 0 64k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | 
_filter_testdir
 
 echo
 echo "== Negative catalog size =="
 _use_sample_img parallels-v1.bz2
 poke_file "$TEST_IMG" "$catalog_entries_offset" "\xff\xff\xff\xff"
-{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | 
_filter_testdir
+{ $QEMU_IO -c "read 0 512" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | 
_filter_testdir
 
 echo
 echo "== Overflow in catalog allocation =="
 _use_sample_img parallels-v1.bz2
 poke_file "$TEST_IMG" "$nb_sectors_offset" "\xff\xff\xff\xff"
 poke_file "$TEST_IMG" "$catalog_entries_offset" "\x01\x00\x00\x40"
-{ $QEMU_IO -c "read 64M 64M" $TEST_IMG; } 2>&1 | _filter_qemu_io | 
_filter_testdir
+{ $QEMU_IO -c "read 64M 64M" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | 
_filter_testdir
 
 echo
 echo "== Zero sectors per track =="
 _use_sample_img parallels-v1.bz2
 poke_file "$TEST_IMG" "$tracks_offset" "\x00\x00\x00\x00"
-{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | 
_filter_testdir
+{ $QEMU_IO -c "read 0 512" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | 
_filter_testdir
 
 echo
 echo "== Read from a valid v2 image =="
 _use_sample_img parallels-v2.bz2
-{ $QEMU_IO -c "read -P 0x11 0 64k" $TEST_IMG; } 2>&1 | _filter_qemu_io | 
_filter_testdir
+{ $QEMU_IO -c "read -P 0x11 0 64k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | 
_filter_testdir
 
 # success, all done
 echo "*** done"
-- 
2.1.0




[Qemu-devel] [PULL 00/38] Block patches

2015-05-22 Thread Stefan Hajnoczi
The following changes since commit 9e549d36e989b14423279fb991b71728a2a4ae7c:

  Merge remote-tracking branch 'remotes/kraxel/tags/pull-vnc-20150520-1' into 
staging (2015-05-21 09:07:19 +0100)

are available in the git repository at:

  git://github.com/stefanha/qemu.git tags/block-pull-request

for you to fetch changes up to a53f1a95f9605f300fbafbc8b60b8a8c67e9c4b4:

  block: get_block_status: use "else" when testing the opposite condition 
(2015-05-22 09:37:33 +0100)





Denis V. Lunev (26):
  iotests, parallels: quote TEST_IMG in 076 test to be path-safe
  block/parallels: rename parallels_header to ParallelsHeader
  block/parallels: provide _co_readv routine for parallels format driver
  block/parallels: replace magic constants 4, 64 with proper sizeofs
  block/parallels: mark parallels format driver as zero inited
  block/parallels: _co_writev callback for Parallels format
  iotests, parallels: test for write into Parallels image
  block/parallels: support parallels image creation
  iotests, parallels: test for newly created parallels image via
qemu-img
  parallels: change copyright information in the image header
  block/parallels: rename catalog_ names to bat_
  block/parallels: create bat2sect helper
  block/parallels: keep BAT bitmap data in little endian in memory
  block/parallels: read parallels image header and BAT into single
buffer
  block/parallels: move parallels_open/probe to the very end of the file
  block/parallels: implement parallels_check method of block driver
  block/parallels: implement incorrect close detection
  iotests, parallels: check for incorrectly closed image in tests
  block/parallels: improve image reading performance
  block/parallels: create bat_entry_off helper
  block/parallels: delay writing to BAT till bdrv_co_flush_to_os
  block/parallels: add prealloc-mode and prealloc-size open paramemets
  block/parallels: optimize linear image expansion
  block/parallels: improve image writing performance further
  block: minimal bounce buffer alignment
  block: align bounce buffers to page

Fam Zheng (3):
  Revert "block: Fix unaligned zero write"
  block: Fix NULL deference for unaligned write if qiov is NULL
  qemu-iotests: Test unaligned sub-block zero write

John Snow (3):
  configure: factor out supported flag check
  configure: silence glib unknown attribute __alloc_size__
  configure: Add workaround for ccache and clang

Paolo Bonzini (2):
  block: return EPERM on writes or discards to read-only devices
  block: get_block_status: use "else" when testing the opposite
condition

Roman Kagan (3):
  block/parallels: switch to bdrv_read
  block/parallels: read up to cluster end in one go
  block/parallels: add get_block_status

Stefan Hajnoczi (1):
  configure: handle clang -nopie argument warning

 block.c|  15 +-
 block/io.c | 159 +++
 block/parallels.c  | 683 -
 block/raw-posix.c  |  14 +-
 configure  |  81 --
 include/block/block.h  |   2 +
 include/block/block_int.h  |   3 +
 tests/qemu-iotests/033 |  13 +
 tests/qemu-iotests/033.out |  30 ++
 tests/qemu-iotests/076 |  15 +-
 tests/qemu-iotests/076.out |  10 +
 tests/qemu-iotests/131 |  77 +
 tests/qemu-iotests/131.out |  41 +++
 tests/qemu-iotests/group   |   1 +
 14 files changed, 998 insertions(+), 146 deletions(-)
 create mode 100755 tests/qemu-iotests/131
 create mode 100644 tests/qemu-iotests/131.out

-- 
2.1.0




[Qemu-devel] [PULL 03/38] block/parallels: switch to bdrv_read

2015-05-22 Thread Stefan Hajnoczi
From: Roman Kagan 

Switch the .bdrv_read method implementation from using bdrv_pread() to
bdrv_read() on the underlying file, since the latter is subject to i/o
throttling while the former is not.

Besides, since bdrv_read() operates in sectors rather than bytes, adjust
the helper functions to do so too.

Signed-off-by: Roman Kagan 
Reviewed-by: Denis V. Lunev 
Signed-off-by: Denis V. Lunev 
Message-id: 1430207220-24458-4-git-send-email-...@openvz.org
CC: Kevin Wolf 
CC: Stefan Hajnoczi 
Signed-off-by: Stefan Hajnoczi 
---
 block/parallels.c | 20 +++-
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/block/parallels.c b/block/parallels.c
index dca0df6..baefd3e 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -146,9 +146,8 @@ fail:
 return ret;
 }
 
-static int64_t seek_to_sector(BlockDriverState *bs, int64_t sector_num)
+static int64_t seek_to_sector(BDRVParallelsState *s, int64_t sector_num)
 {
-BDRVParallelsState *s = bs->opaque;
 uint32_t index, offset;
 
 index = sector_num / s->tracks;
@@ -157,24 +156,27 @@ static int64_t seek_to_sector(BlockDriverState *bs, 
int64_t sector_num)
 /* not allocated */
 if ((index >= s->catalog_size) || (s->catalog_bitmap[index] == 0))
 return -1;
-return
-((uint64_t)s->catalog_bitmap[index] * s->off_multiplier + offset) * 
512;
+return (uint64_t)s->catalog_bitmap[index] * s->off_multiplier + offset;
 }
 
 static int parallels_read(BlockDriverState *bs, int64_t sector_num,
 uint8_t *buf, int nb_sectors)
 {
+BDRVParallelsState *s = bs->opaque;
+
 while (nb_sectors > 0) {
-int64_t position = seek_to_sector(bs, sector_num);
+int64_t position = seek_to_sector(s, sector_num);
 if (position >= 0) {
-if (bdrv_pread(bs->file, position, buf, 512) != 512)
-return -1;
+int ret = bdrv_read(bs->file, position, buf, 1);
+if (ret < 0) {
+return ret;
+}
 } else {
-memset(buf, 0, 512);
+memset(buf, 0, BDRV_SECTOR_SIZE);
 }
 nb_sectors--;
 sector_num++;
-buf += 512;
+buf += BDRV_SECTOR_SIZE;
 }
 return 0;
 }
-- 
2.1.0




[Qemu-devel] [PULL 06/38] block/parallels: provide _co_readv routine for parallels format driver

2015-05-22 Thread Stefan Hajnoczi
From: "Denis V. Lunev" 

Main approach is taken from qcow2_co_readv.

The patch drops coroutine lock for the duration of IO operation and
peforms normal scatter-gather IO using standard QEMU backend.

The patch also adds comment about locking considerations in the driver.

Signed-off-by: Denis V. Lunev 
Reviewed-by: Roman Kagan 
Signed-off-by: Roman Kagan 
Message-id: 1430207220-24458-7-git-send-email-...@openvz.org
CC: Roman Kagan 
CC: Kevin Wolf 
CC: Stefan Hajnoczi 
Signed-off-by: Stefan Hajnoczi 
---
 block/parallels.c | 54 +-
 1 file changed, 33 insertions(+), 21 deletions(-)

diff --git a/block/parallels.c b/block/parallels.c
index b469984..f3ffece 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -49,6 +49,10 @@ typedef struct ParallelsHeader {
 } QEMU_PACKED ParallelsHeader;
 
 typedef struct BDRVParallelsState {
+/** Locking is conservative, the lock protects
+ *   - image file extending (truncate, fallocate)
+ *   - any access to block allocation table
+ */
 CoMutex lock;
 
 uint32_t *catalog_bitmap;
@@ -186,37 +190,45 @@ static int64_t coroutine_fn 
parallels_co_get_block_status(BlockDriverState *bs,
 BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
 }
 
-static int parallels_read(BlockDriverState *bs, int64_t sector_num,
-uint8_t *buf, int nb_sectors)
+static coroutine_fn int parallels_co_readv(BlockDriverState *bs,
+int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
 {
 BDRVParallelsState *s = bs->opaque;
+uint64_t bytes_done = 0;
+QEMUIOVector hd_qiov;
+int ret = 0;
+
+qemu_iovec_init(&hd_qiov, qiov->niov);
 
 while (nb_sectors > 0) {
-int64_t position = seek_to_sector(s, sector_num);
-int n = cluster_remainder(s, sector_num, nb_sectors);
-if (position >= 0) {
-int ret = bdrv_read(bs->file, position, buf, n);
+int64_t position;
+int n, nbytes;
+
+qemu_co_mutex_lock(&s->lock);
+position = seek_to_sector(s, sector_num);
+qemu_co_mutex_unlock(&s->lock);
+
+n = cluster_remainder(s, sector_num, nb_sectors);
+nbytes = n << BDRV_SECTOR_BITS;
+
+if (position < 0) {
+qemu_iovec_memset(qiov, bytes_done, 0, nbytes);
+} else {
+qemu_iovec_reset(&hd_qiov);
+qemu_iovec_concat(&hd_qiov, qiov, bytes_done, nbytes);
+
+ret = bdrv_co_readv(bs->file, position, n, &hd_qiov);
 if (ret < 0) {
-return ret;
+break;
 }
-} else {
-memset(buf, 0, n << BDRV_SECTOR_BITS);
 }
+
 nb_sectors -= n;
 sector_num += n;
-buf += n << BDRV_SECTOR_BITS;
+bytes_done += nbytes;
 }
-return 0;
-}
 
-static coroutine_fn int parallels_co_read(BlockDriverState *bs, int64_t 
sector_num,
-  uint8_t *buf, int nb_sectors)
-{
-int ret;
-BDRVParallelsState *s = bs->opaque;
-qemu_co_mutex_lock(&s->lock);
-ret = parallels_read(bs, sector_num, buf, nb_sectors);
-qemu_co_mutex_unlock(&s->lock);
+qemu_iovec_destroy(&hd_qiov);
 return ret;
 }
 
@@ -231,9 +243,9 @@ static BlockDriver bdrv_parallels = {
 .instance_size = sizeof(BDRVParallelsState),
 .bdrv_probe= parallels_probe,
 .bdrv_open = parallels_open,
-.bdrv_read  = parallels_co_read,
 .bdrv_close= parallels_close,
 .bdrv_co_get_block_status = parallels_co_get_block_status,
+.bdrv_co_readv  = parallels_co_readv,
 };
 
 static void bdrv_parallels_init(void)
-- 
2.1.0




[Qemu-devel] [PULL 16/38] block/parallels: keep BAT bitmap data in little endian in memory

2015-05-22 Thread Stefan Hajnoczi
From: "Denis V. Lunev" 

This will allow to use this data as buffer to BAT update directly
without any intermediate buffers.

Signed-off-by: Denis V. Lunev 
Reviewed-by: Roman Kagan 
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Roman Kagan 
Message-id: 1430207220-24458-17-git-send-email-...@openvz.org
CC: Kevin Wolf 
Signed-off-by: Stefan Hajnoczi 
---
 block/parallels.c | 17 +
 1 file changed, 5 insertions(+), 12 deletions(-)

diff --git a/block/parallels.c b/block/parallels.c
index 1540c21..431adf1 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -90,7 +90,6 @@ static int parallels_open(BlockDriverState *bs, QDict 
*options, int flags,
   Error **errp)
 {
 BDRVParallelsState *s = bs->opaque;
-int i;
 ParallelsHeader ph;
 int ret;
 
@@ -143,10 +142,6 @@ static int parallels_open(BlockDriverState *bs, QDict 
*options, int flags,
 goto fail;
 }
 
-for (i = 0; i < s->bat_size; i++) {
-le32_to_cpus(&s->bat_bitmap[i]);
-}
-
 s->has_truncate = bdrv_has_zero_init(bs->file) &&
   bdrv_truncate(bs->file, bdrv_getlength(bs->file)) == 0;
 
@@ -164,7 +159,7 @@ fail:
 
 static int64_t bat2sect(BDRVParallelsState *s, uint32_t idx)
 {
-return (uint64_t)s->bat_bitmap[idx] * s->off_multiplier;
+return (uint64_t)le32_to_cpu(s->bat_bitmap[idx]) * s->off_multiplier;
 }
 
 static int64_t seek_to_sector(BDRVParallelsState *s, int64_t sector_num)
@@ -191,7 +186,7 @@ static int cluster_remainder(BDRVParallelsState *s, int64_t 
sector_num,
 static int64_t allocate_cluster(BlockDriverState *bs, int64_t sector_num)
 {
 BDRVParallelsState *s = bs->opaque;
-uint32_t idx, offset, tmp;
+uint32_t idx, offset;
 int64_t pos;
 int ret;
 
@@ -215,12 +210,10 @@ static int64_t allocate_cluster(BlockDriverState *bs, 
int64_t sector_num)
 return ret;
 }
 
-s->bat_bitmap[idx] = pos / s->off_multiplier;
-
-tmp = cpu_to_le32(s->bat_bitmap[idx]);
-
+s->bat_bitmap[idx] = cpu_to_le32(pos / s->off_multiplier);
 ret = bdrv_pwrite(bs->file,
-sizeof(ParallelsHeader) + idx * sizeof(tmp), &tmp, sizeof(tmp));
+sizeof(ParallelsHeader) + idx * sizeof(s->bat_bitmap[idx]),
+s->bat_bitmap + idx, sizeof(s->bat_bitmap[idx]));
 if (ret < 0) {
 s->bat_bitmap[idx] = 0;
 return ret;
-- 
2.1.0




[Qemu-devel] [PULL 08/38] block/parallels: mark parallels format driver as zero inited

2015-05-22 Thread Stefan Hajnoczi
From: "Denis V. Lunev" 

>From the guest point of view unallocated blocks are zeroed.

Signed-off-by: Denis V. Lunev 
Reviewed-by: Roman Kagan 
Signed-off-by: Roman Kagan 
Message-id: 1430207220-24458-9-git-send-email-...@openvz.org
CC: Roman Kagan 
CC: Kevin Wolf 
CC: Stefan Hajnoczi 
Signed-off-by: Stefan Hajnoczi 
---
 block/parallels.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/block/parallels.c b/block/parallels.c
index 138e618..ae64ce5 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -245,6 +245,7 @@ static BlockDriver bdrv_parallels = {
 .bdrv_open = parallels_open,
 .bdrv_close= parallels_close,
 .bdrv_co_get_block_status = parallels_co_get_block_status,
+.bdrv_has_zero_init   = bdrv_has_zero_init_1,
 .bdrv_co_readv  = parallels_co_readv,
 };
 
-- 
2.1.0




[Qemu-devel] [PULL 09/38] block/parallels: _co_writev callback for Parallels format

2015-05-22 Thread Stefan Hajnoczi
From: "Denis V. Lunev" 

Support write on Parallels images. The code is almost the same as one
in the previous patch implemented scatter-gather IO for read.

Signed-off-by: Denis V. Lunev 
Reviewed-by: Roman Kagan 
Signed-off-by: Roman Kagan 
Message-id: 1430207220-24458-10-git-send-email-...@openvz.org
CC: Roman Kagan 
CC: Kevin Wolf 
CC: Stefan Hajnoczi 
Signed-off-by: Stefan Hajnoczi 
---
 block/parallels.c | 90 +--
 1 file changed, 88 insertions(+), 2 deletions(-)

diff --git a/block/parallels.c b/block/parallels.c
index ae64ce5..8d73803 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -60,6 +60,8 @@ typedef struct BDRVParallelsState {
 unsigned int tracks;
 
 unsigned int off_multiplier;
+
+bool has_truncate;
 } BDRVParallelsState;
 
 static int parallels_probe(const uint8_t *buf, int buf_size, const char 
*filename)
@@ -85,8 +87,6 @@ static int parallels_open(BlockDriverState *bs, QDict 
*options, int flags,
 ParallelsHeader ph;
 int ret;
 
-bs->read_only = 1; // no write support yet
-
 ret = bdrv_pread(bs->file, 0, &ph, sizeof(ph));
 if (ret < 0) {
 goto fail;
@@ -139,6 +139,9 @@ static int parallels_open(BlockDriverState *bs, QDict 
*options, int flags,
 for (i = 0; i < s->catalog_size; i++)
 le32_to_cpus(&s->catalog_bitmap[i]);
 
+s->has_truncate = bdrv_has_zero_init(bs->file) &&
+  bdrv_truncate(bs->file, bdrv_getlength(bs->file)) == 0;
+
 qemu_co_mutex_init(&s->lock);
 return 0;
 
@@ -170,6 +173,46 @@ static int cluster_remainder(BDRVParallelsState *s, 
int64_t sector_num,
 return MIN(nb_sectors, ret);
 }
 
+static int64_t allocate_cluster(BlockDriverState *bs, int64_t sector_num)
+{
+BDRVParallelsState *s = bs->opaque;
+uint32_t idx, offset, tmp;
+int64_t pos;
+int ret;
+
+idx = sector_num / s->tracks;
+offset = sector_num % s->tracks;
+
+if (idx >= s->catalog_size) {
+return -EINVAL;
+}
+if (s->catalog_bitmap[idx] != 0) {
+return (uint64_t)s->catalog_bitmap[idx] * s->off_multiplier + offset;
+}
+
+pos = bdrv_getlength(bs->file) >> BDRV_SECTOR_BITS;
+if (s->has_truncate) {
+ret = bdrv_truncate(bs->file, (pos + s->tracks) << BDRV_SECTOR_BITS);
+} else {
+ret = bdrv_write_zeroes(bs->file, pos, s->tracks, 0);
+}
+if (ret < 0) {
+return ret;
+}
+
+s->catalog_bitmap[idx] = pos / s->off_multiplier;
+
+tmp = cpu_to_le32(s->catalog_bitmap[idx]);
+
+ret = bdrv_pwrite(bs->file,
+sizeof(ParallelsHeader) + idx * sizeof(tmp), &tmp, sizeof(tmp));
+if (ret < 0) {
+s->catalog_bitmap[idx] = 0;
+return ret;
+}
+return (uint64_t)s->catalog_bitmap[idx] * s->off_multiplier + offset;
+}
+
 static int64_t coroutine_fn parallels_co_get_block_status(BlockDriverState *bs,
 int64_t sector_num, int nb_sectors, int *pnum)
 {
@@ -190,6 +233,48 @@ static int64_t coroutine_fn 
parallels_co_get_block_status(BlockDriverState *bs,
 BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
 }
 
+static coroutine_fn int parallels_co_writev(BlockDriverState *bs,
+int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
+{
+BDRVParallelsState *s = bs->opaque;
+uint64_t bytes_done = 0;
+QEMUIOVector hd_qiov;
+int ret = 0;
+
+qemu_iovec_init(&hd_qiov, qiov->niov);
+
+while (nb_sectors > 0) {
+int64_t position;
+int n, nbytes;
+
+qemu_co_mutex_lock(&s->lock);
+position = allocate_cluster(bs, sector_num);
+qemu_co_mutex_unlock(&s->lock);
+if (position < 0) {
+ret = (int)position;
+break;
+}
+
+n = cluster_remainder(s, sector_num, nb_sectors);
+nbytes = n << BDRV_SECTOR_BITS;
+
+qemu_iovec_reset(&hd_qiov);
+qemu_iovec_concat(&hd_qiov, qiov, bytes_done, nbytes);
+
+ret = bdrv_co_writev(bs->file, position, n, &hd_qiov);
+if (ret < 0) {
+break;
+}
+
+nb_sectors -= n;
+sector_num += n;
+bytes_done += nbytes;
+}
+
+qemu_iovec_destroy(&hd_qiov);
+return ret;
+}
+
 static coroutine_fn int parallels_co_readv(BlockDriverState *bs,
 int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
 {
@@ -247,6 +332,7 @@ static BlockDriver bdrv_parallels = {
 .bdrv_co_get_block_status = parallels_co_get_block_status,
 .bdrv_has_zero_init   = bdrv_has_zero_init_1,
 .bdrv_co_readv  = parallels_co_readv,
+.bdrv_co_writev = parallels_co_writev,
 };
 
 static void bdrv_parallels_init(void)
-- 
2.1.0




[Qemu-devel] [PULL 24/38] block/parallels: delay writing to BAT till bdrv_co_flush_to_os

2015-05-22 Thread Stefan Hajnoczi
From: "Denis V. Lunev" 

The idea is that we do not need to immediately sync BAT to the image as
from the guest point of view there is a possibility that IO is lost
even in the physical controller until flush command was finished.
bdrv_co_flush_to_os is exactly the right place for this purpose.

Technically the patch uses loaded BAT data as a cache and performs
actual on-disk metadata updates in parallels_co_flush_to_os callback.

This patch speed ups
  qemu-img create -f parallels -o cluster_size=64k ./1.hds 64G
  qemu-io -f parallels -c "write -P 0x11 0 1024k" 1.hds
writing from 50-60 Mb/sec to 80-90 Mb/sec on rotational media and
from 160 Mb/sec to 190 Mb/sec on SSD disk.

Signed-off-by: Denis V. Lunev 
Reviewed-by: Roman Kagan 
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Roman Kagan 
Message-id: 1430207220-24458-25-git-send-email-...@openvz.org
CC: Kevin Wolf 
Signed-off-by: Stefan Hajnoczi 
---
 block/parallels.c | 50 --
 1 file changed, 44 insertions(+), 6 deletions(-)

diff --git a/block/parallels.c b/block/parallels.c
index 4d8a0d4..05fe030 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -30,6 +30,7 @@
 #include "qemu-common.h"
 #include "block/block_int.h"
 #include "qemu/module.h"
+#include "qemu/bitmap.h"
 
 /**/
 
@@ -66,6 +67,9 @@ typedef struct BDRVParallelsState {
 uint32_t header_size;
 bool header_unclean;
 
+unsigned long *bat_dirty_bmap;
+unsigned int  bat_dirty_block;
+
 uint32_t *bat_bitmap;
 unsigned int bat_size;
 
@@ -165,15 +169,43 @@ static int64_t allocate_cluster(BlockDriverState *bs, 
int64_t sector_num)
 }
 
 s->bat_bitmap[idx] = cpu_to_le32(pos / s->off_multiplier);
-ret = bdrv_pwrite(bs->file, bat_entry_off(idx), s->bat_bitmap + idx,
-  sizeof(s->bat_bitmap[idx]));
-if (ret < 0) {
-s->bat_bitmap[idx] = 0;
-return ret;
-}
+
+bitmap_set(s->bat_dirty_bmap, bat_entry_off(idx) / s->bat_dirty_block, 1);
 return bat2sect(s, idx) + offset;
 }
 
+
+static coroutine_fn int parallels_co_flush_to_os(BlockDriverState *bs)
+{
+BDRVParallelsState *s = bs->opaque;
+unsigned long size = DIV_ROUND_UP(s->header_size, s->bat_dirty_block);
+unsigned long bit;
+
+qemu_co_mutex_lock(&s->lock);
+
+bit = find_first_bit(s->bat_dirty_bmap, size);
+while (bit < size) {
+uint32_t off = bit * s->bat_dirty_block;
+uint32_t to_write = s->bat_dirty_block;
+int ret;
+
+if (off + to_write > s->header_size) {
+to_write = s->header_size - off;
+}
+ret = bdrv_pwrite(bs->file, off, (uint8_t *)s->header + off, to_write);
+if (ret < 0) {
+qemu_co_mutex_unlock(&s->lock);
+return ret;
+}
+bit = find_next_bit(s->bat_dirty_bmap, size, bit + 1);
+}
+bitmap_zero(s->bat_dirty_bmap, size);
+
+qemu_co_mutex_unlock(&s->lock);
+return 0;
+}
+
+
 static int64_t coroutine_fn parallels_co_get_block_status(BlockDriverState *bs,
 int64_t sector_num, int nb_sectors, int *pnum)
 {
@@ -557,6 +589,10 @@ static int parallels_open(BlockDriverState *bs, QDict 
*options, int flags,
 }
 }
 
+s->bat_dirty_block = 4 * getpagesize();
+s->bat_dirty_bmap =
+bitmap_new(DIV_ROUND_UP(s->header_size, s->bat_dirty_block));
+
 qemu_co_mutex_init(&s->lock);
 return 0;
 
@@ -578,6 +614,7 @@ static void parallels_close(BlockDriverState *bs)
 parallels_update_header(bs);
 }
 
+g_free(s->bat_dirty_bmap);
 qemu_vfree(s->header);
 }
 
@@ -608,6 +645,7 @@ static BlockDriver bdrv_parallels = {
 .bdrv_close= parallels_close,
 .bdrv_co_get_block_status = parallels_co_get_block_status,
 .bdrv_has_zero_init   = bdrv_has_zero_init_1,
+.bdrv_co_flush_to_os  = parallels_co_flush_to_os,
 .bdrv_co_readv  = parallels_co_readv,
 .bdrv_co_writev = parallels_co_writev,
 
-- 
2.1.0




[Qemu-devel] [PULL 04/38] block/parallels: read up to cluster end in one go

2015-05-22 Thread Stefan Hajnoczi
From: Roman Kagan 

Teach parallels_read() to do reads in coarser granularity than just a
single sector: if requested, read up to the cluster end in one go.

Signed-off-by: Roman Kagan 
Reviewed-by: Denis V. Lunev 
Signed-off-by: Denis V. Lunev 
Reviewed-by: Stefan Hajnoczi 
Message-id: 1430207220-24458-5-git-send-email-...@openvz.org
CC: Kevin Wolf 
Signed-off-by: Stefan Hajnoczi 
---
 block/parallels.c | 18 +-
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/block/parallels.c b/block/parallels.c
index baefd3e..8770c82 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -159,6 +159,13 @@ static int64_t seek_to_sector(BDRVParallelsState *s, 
int64_t sector_num)
 return (uint64_t)s->catalog_bitmap[index] * s->off_multiplier + offset;
 }
 
+static int cluster_remainder(BDRVParallelsState *s, int64_t sector_num,
+int nb_sectors)
+{
+int ret = s->tracks - sector_num % s->tracks;
+return MIN(nb_sectors, ret);
+}
+
 static int parallels_read(BlockDriverState *bs, int64_t sector_num,
 uint8_t *buf, int nb_sectors)
 {
@@ -166,17 +173,18 @@ static int parallels_read(BlockDriverState *bs, int64_t 
sector_num,
 
 while (nb_sectors > 0) {
 int64_t position = seek_to_sector(s, sector_num);
+int n = cluster_remainder(s, sector_num, nb_sectors);
 if (position >= 0) {
-int ret = bdrv_read(bs->file, position, buf, 1);
+int ret = bdrv_read(bs->file, position, buf, n);
 if (ret < 0) {
 return ret;
 }
 } else {
-memset(buf, 0, BDRV_SECTOR_SIZE);
+memset(buf, 0, n << BDRV_SECTOR_BITS);
 }
-nb_sectors--;
-sector_num++;
-buf += BDRV_SECTOR_SIZE;
+nb_sectors -= n;
+sector_num += n;
+buf += n << BDRV_SECTOR_BITS;
 }
 return 0;
 }
-- 
2.1.0




[Qemu-devel] [PULL 07/38] block/parallels: replace magic constants 4, 64 with proper sizeofs

2015-05-22 Thread Stefan Hajnoczi
From: "Denis V. Lunev" 

simple purification..

Signed-off-by: Denis V. Lunev 
Reviewed-by: Roman Kagan 
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Roman Kagan 
Message-id: 1430207220-24458-8-git-send-email-...@openvz.org
CC: Kevin Wolf 
Signed-off-by: Stefan Hajnoczi 
---
 block/parallels.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/block/parallels.c b/block/parallels.c
index f3ffece..138e618 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -32,7 +32,6 @@
 #define HEADER_MAGIC "WithoutFreeSpace"
 #define HEADER_MAGIC2 "WithouFreSpacExt"
 #define HEADER_VERSION 2
-#define HEADER_SIZE 64
 
 // always little-endian
 typedef struct ParallelsHeader {
@@ -67,7 +66,7 @@ static int parallels_probe(const uint8_t *buf, int buf_size, 
const char *filenam
 {
 const ParallelsHeader *ph = (const void *)buf;
 
-if (buf_size < HEADER_SIZE)
+if (buf_size < sizeof(ParallelsHeader))
 return 0;
 
 if ((!memcmp(ph->magic, HEADER_MAGIC, 16) ||
@@ -120,7 +119,7 @@ static int parallels_open(BlockDriverState *bs, QDict 
*options, int flags,
 }
 
 s->catalog_size = le32_to_cpu(ph.catalog_entries);
-if (s->catalog_size > INT_MAX / 4) {
+if (s->catalog_size > INT_MAX / sizeof(uint32_t)) {
 error_setg(errp, "Catalog too large");
 ret = -EFBIG;
 goto fail;
@@ -131,7 +130,8 @@ static int parallels_open(BlockDriverState *bs, QDict 
*options, int flags,
 goto fail;
 }
 
-ret = bdrv_pread(bs->file, 64, s->catalog_bitmap, s->catalog_size * 4);
+ret = bdrv_pread(bs->file, sizeof(ParallelsHeader),
+ s->catalog_bitmap, s->catalog_size * sizeof(uint32_t));
 if (ret < 0) {
 goto fail;
 }
-- 
2.1.0




[Qemu-devel] [PULL 10/38] iotests, parallels: test for write into Parallels image

2015-05-22 Thread Stefan Hajnoczi
From: "Denis V. Lunev" 

Signed-off-by: Denis V. Lunev 
Reviewed-by: Roman Kagan 
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Roman Kagan 
Message-id: 1430207220-24458-11-git-send-email-...@openvz.org
CC: Kevin Wolf 
Signed-off-by: Stefan Hajnoczi 
---
 tests/qemu-iotests/076 |  5 +
 tests/qemu-iotests/076.out | 10 ++
 2 files changed, 15 insertions(+)

diff --git a/tests/qemu-iotests/076 b/tests/qemu-iotests/076
index 0139976..c9b55a9 100755
--- a/tests/qemu-iotests/076
+++ b/tests/qemu-iotests/076
@@ -74,6 +74,11 @@ echo
 echo "== Read from a valid v2 image =="
 _use_sample_img parallels-v2.bz2
 { $QEMU_IO -c "read -P 0x11 0 64k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | 
_filter_testdir
+{ $QEMU_IO -c "write -P 0x21 1024k 1k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | 
_filter_testdir
+{ $QEMU_IO -c "write -P 0x22 1025k 1k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | 
_filter_testdir
+{ $QEMU_IO -c "read -P 0x21 1024k 1k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | 
_filter_testdir
+{ $QEMU_IO -c "read -P 0x22 1025k 1k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | 
_filter_testdir
+{ $QEMU_IO -c "read -P 0 1026k 62k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | 
_filter_testdir
 
 # success, all done
 echo "*** done"
diff --git a/tests/qemu-iotests/076.out b/tests/qemu-iotests/076.out
index 32ade08..bae 100644
--- a/tests/qemu-iotests/076.out
+++ b/tests/qemu-iotests/076.out
@@ -19,4 +19,14 @@ no file open, try 'help open'
 == Read from a valid v2 image ==
 read 65536/65536 bytes at offset 0
 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 1024/1024 bytes at offset 1048576
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 1024/1024 bytes at offset 1049600
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 1024/1024 bytes at offset 1048576
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 1024/1024 bytes at offset 1049600
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 63488/63488 bytes at offset 1050624
+62 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 *** done
-- 
2.1.0




[Qemu-devel] [PULL 23/38] block/parallels: create bat_entry_off helper

2015-05-22 Thread Stefan Hajnoczi
From: "Denis V. Lunev" 

calculate offset of the BAT entry in the image file.

Signed-off-by: Denis V. Lunev 
Reviewed-by: Roman Kagan 
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Roman Kagan 
Message-id: 1430207220-24458-24-git-send-email-...@openvz.org
CC: Kevin Wolf 
Signed-off-by: Stefan Hajnoczi 
---
 block/parallels.c | 15 +--
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/block/parallels.c b/block/parallels.c
index 5ff74e8..4d8a0d4 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -82,6 +82,11 @@ static int64_t bat2sect(BDRVParallelsState *s, uint32_t idx)
 return (uint64_t)le32_to_cpu(s->bat_bitmap[idx]) * s->off_multiplier;
 }
 
+static uint32_t bat_entry_off(uint32_t idx)
+{
+return sizeof(ParallelsHeader) + sizeof(uint32_t) * idx;
+}
+
 static int64_t seek_to_sector(BDRVParallelsState *s, int64_t sector_num)
 {
 uint32_t index, offset;
@@ -160,9 +165,8 @@ static int64_t allocate_cluster(BlockDriverState *bs, 
int64_t sector_num)
 }
 
 s->bat_bitmap[idx] = cpu_to_le32(pos / s->off_multiplier);
-ret = bdrv_pwrite(bs->file,
-sizeof(ParallelsHeader) + idx * sizeof(s->bat_bitmap[idx]),
-s->bat_bitmap + idx, sizeof(s->bat_bitmap[idx]));
+ret = bdrv_pwrite(bs->file, bat_entry_off(idx), s->bat_bitmap + idx,
+  sizeof(s->bat_bitmap[idx]));
 if (ret < 0) {
 s->bat_bitmap[idx] = 0;
 return ret;
@@ -400,8 +404,7 @@ static int parallels_create(const char *filename, QemuOpts 
*opts, Error **errp)
 }
 
 bat_entries = DIV_ROUND_UP(total_size, cl_size);
-bat_sectors = DIV_ROUND_UP(bat_entries * sizeof(uint32_t) +
-   sizeof(ParallelsHeader), cl_size);
+bat_sectors = DIV_ROUND_UP(bat_entry_off(bat_entries), cl_size);
 bat_sectors = (bat_sectors *  cl_size) >> BDRV_SECTOR_BITS;
 
 memset(&header, 0, sizeof(header));
@@ -513,7 +516,7 @@ static int parallels_open(BlockDriverState *bs, QDict 
*options, int flags,
 goto fail;
 }
 
-size = sizeof(ParallelsHeader) + sizeof(uint32_t) * s->bat_size;
+size = bat_entry_off(s->bat_size);
 s->header_size = ROUND_UP(size, bdrv_opt_mem_align(bs->file));
 s->header = qemu_try_blockalign(bs->file, s->header_size);
 if (s->header == NULL) {
-- 
2.1.0




[Qemu-devel] [PULL 12/38] iotests, parallels: test for newly created parallels image via qemu-img

2015-05-22 Thread Stefan Hajnoczi
From: "Denis V. Lunev" 

Signed-off-by: Denis V. Lunev 
Reviewed-by: Roman Kagan 
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Roman Kagan 
Message-id: 1430207220-24458-13-git-send-email-...@openvz.org
CC: Kevin Wolf 
Signed-off-by: Stefan Hajnoczi 
---
 tests/qemu-iotests/131 | 68 ++
 tests/qemu-iotests/131.out | 24 
 tests/qemu-iotests/group   |  1 +
 3 files changed, 93 insertions(+)
 create mode 100755 tests/qemu-iotests/131
 create mode 100644 tests/qemu-iotests/131.out

diff --git a/tests/qemu-iotests/131 b/tests/qemu-iotests/131
new file mode 100755
index 000..f45afa7
--- /dev/null
+++ b/tests/qemu-iotests/131
@@ -0,0 +1,68 @@
+#!/bin/bash
+#
+# parallels format validation tests (created by QEMU)
+#
+# Copyright (C) 2014 Denis V. Lunev 
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see .
+#
+
+# creator
+owner=d...@openvz.org
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1   # failure is the default!
+
+_cleanup()
+{
+_cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_supported_fmt parallels
+_supported_proto file
+_supported_os Linux
+
+size=64M
+CLUSTER_SIZE=64k
+IMGFMT=parallels
+_make_test_img $size
+
+echo == read empty image ==
+{ $QEMU_IO -c "read -P 0 32k 64k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | 
_filter_testdir
+echo == write more than 1 block in a row ==
+{ $QEMU_IO -c "write -P 0x11 32k 128k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | 
_filter_testdir
+echo == read less than block ==
+{ $QEMU_IO -c "read -P 0x11 32k 32k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | 
_filter_testdir
+echo == read exactly 1 block ==
+{ $QEMU_IO -c "read -P 0x11 64k 64k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | 
_filter_testdir
+echo == read more than 1 block ==
+{ $QEMU_IO -c "read -P 0x11 32k 128k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | 
_filter_testdir
+echo == check that there is no trash after written ==
+{ $QEMU_IO -c "read -P 0 160k 32k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | 
_filter_testdir
+echo == check that there is no trash before written ==
+{ $QEMU_IO -c "read -P 0 0 32k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | 
_filter_testdir
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/131.out b/tests/qemu-iotests/131.out
new file mode 100644
index 000..4158a2f
--- /dev/null
+++ b/tests/qemu-iotests/131.out
@@ -0,0 +1,24 @@
+QA output created by 131
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+== read empty image ==
+read 65536/65536 bytes at offset 32768
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+== write more than 1 block in a row ==
+wrote 131072/131072 bytes at offset 32768
+128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+== read less than block ==
+read 32768/32768 bytes at offset 32768
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+== read exactly 1 block ==
+read 65536/65536 bytes at offset 65536
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+== read more than 1 block ==
+read 131072/131072 bytes at offset 32768
+128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+== check that there is no trash after written ==
+read 32768/32768 bytes at offset 163840
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+== check that there is no trash before written ==
+read 32768/32768 bytes at offset 0
+32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+*** done
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index 6ca3466..34b16cb 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -128,3 +128,4 @@
 128 rw auto quick
 129 rw auto quick
 130 rw auto quick
+131 rw auto quick
-- 
2.1.0




[Qemu-devel] [PULL 11/38] block/parallels: support parallels image creation

2015-05-22 Thread Stefan Hajnoczi
From: "Denis V. Lunev" 

Do not even care to create WithoutFreeSpace image, it is obsolete.
Always create WithouFreSpacExt one.

The code also does not spend a lot of efforts to fill cylinders and
heads fields, they are not used actually in a real life neither in
QEMU nor in Parallels products.

Signed-off-by: Denis V. Lunev 
Reviewed-by: Roman Kagan 
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Roman Kagan 
Message-id: 1430207220-24458-12-git-send-email-...@openvz.org
CC: Kevin Wolf 
Signed-off-by: Stefan Hajnoczi 
---
 block/parallels.c | 97 +++
 1 file changed, 97 insertions(+)

diff --git a/block/parallels.c b/block/parallels.c
index 8d73803..15f6cb3 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -33,6 +33,9 @@
 #define HEADER_MAGIC2 "WithouFreSpacExt"
 #define HEADER_VERSION 2
 
+#define DEFAULT_CLUSTER_SIZE 1048576/* 1 MiB */
+
+
 // always little-endian
 typedef struct ParallelsHeader {
 char magic[16]; // "WithoutFreeSpace"
@@ -317,12 +320,103 @@ static coroutine_fn int 
parallels_co_readv(BlockDriverState *bs,
 return ret;
 }
 
+static int parallels_create(const char *filename, QemuOpts *opts, Error **errp)
+{
+int64_t total_size, cl_size;
+uint8_t tmp[BDRV_SECTOR_SIZE];
+Error *local_err = NULL;
+BlockDriverState *file;
+uint32_t cat_entries, cat_sectors;
+ParallelsHeader header;
+int ret;
+
+total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
+  BDRV_SECTOR_SIZE);
+cl_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_CLUSTER_SIZE,
+  DEFAULT_CLUSTER_SIZE), BDRV_SECTOR_SIZE);
+
+ret = bdrv_create_file(filename, opts, &local_err);
+if (ret < 0) {
+error_propagate(errp, local_err);
+return ret;
+}
+
+file = NULL;
+ret = bdrv_open(&file, filename, NULL, NULL,
+BDRV_O_RDWR | BDRV_O_PROTOCOL, NULL, &local_err);
+if (ret < 0) {
+error_propagate(errp, local_err);
+return ret;
+}
+ret = bdrv_truncate(file, 0);
+if (ret < 0) {
+goto exit;
+}
+
+cat_entries = DIV_ROUND_UP(total_size, cl_size);
+cat_sectors = DIV_ROUND_UP(cat_entries * sizeof(uint32_t) +
+   sizeof(ParallelsHeader), cl_size);
+cat_sectors = (cat_sectors *  cl_size) >> BDRV_SECTOR_BITS;
+
+memset(&header, 0, sizeof(header));
+memcpy(header.magic, HEADER_MAGIC2, sizeof(header.magic));
+header.version = cpu_to_le32(HEADER_VERSION);
+/* don't care much about geometry, it is not used on image level */
+header.heads = cpu_to_le32(16);
+header.cylinders = cpu_to_le32(total_size / BDRV_SECTOR_SIZE / 16 / 32);
+header.tracks = cpu_to_le32(cl_size >> BDRV_SECTOR_BITS);
+header.catalog_entries = cpu_to_le32(cat_entries);
+header.nb_sectors = cpu_to_le64(DIV_ROUND_UP(total_size, 
BDRV_SECTOR_SIZE));
+header.data_off = cpu_to_le32(cat_sectors);
+
+/* write all the data */
+memset(tmp, 0, sizeof(tmp));
+memcpy(tmp, &header, sizeof(header));
+
+ret = bdrv_pwrite(file, 0, tmp, BDRV_SECTOR_SIZE);
+if (ret < 0) {
+goto exit;
+}
+ret = bdrv_write_zeroes(file, 1, cat_sectors - 1, 0);
+if (ret < 0) {
+goto exit;
+}
+ret = 0;
+
+done:
+bdrv_unref(file);
+return ret;
+
+exit:
+error_setg_errno(errp, -ret, "Failed to create Parallels image");
+goto done;
+}
+
 static void parallels_close(BlockDriverState *bs)
 {
 BDRVParallelsState *s = bs->opaque;
 g_free(s->catalog_bitmap);
 }
 
+static QemuOptsList parallels_create_opts = {
+.name = "parallels-create-opts",
+.head = QTAILQ_HEAD_INITIALIZER(parallels_create_opts.head),
+.desc = {
+{
+.name = BLOCK_OPT_SIZE,
+.type = QEMU_OPT_SIZE,
+.help = "Virtual disk size",
+},
+{
+.name = BLOCK_OPT_CLUSTER_SIZE,
+.type = QEMU_OPT_SIZE,
+.help = "Parallels image cluster size",
+.def_value_str = stringify(DEFAULT_CLUSTER_SIZE),
+},
+{ /* end of list */ }
+}
+};
+
 static BlockDriver bdrv_parallels = {
 .format_name   = "parallels",
 .instance_size = sizeof(BDRVParallelsState),
@@ -333,6 +427,9 @@ static BlockDriver bdrv_parallels = {
 .bdrv_has_zero_init   = bdrv_has_zero_init_1,
 .bdrv_co_readv  = parallels_co_readv,
 .bdrv_co_writev = parallels_co_writev,
+
+.bdrv_create= parallels_create,
+.create_opts= ¶llels_create_opts,
 };
 
 static void bdrv_parallels_init(void)
-- 
2.1.0




[Qemu-devel] [PULL 25/38] block/parallels: add prealloc-mode and prealloc-size open paramemets

2015-05-22 Thread Stefan Hajnoczi
From: "Denis V. Lunev" 

This is preparational commit for tweaks in Parallels image expansion.
The idea is that enlarge via truncate by one data block is slow. It
would be much better to use fallocate via bdrv_write_zeroes and
expand by some significant amount at once.

Original idea with sequential file writing to the end of the file without
fallocate/truncate would be slower than this approach if the image is
expanded with several operations:
- each image expanding means file metadata update, i.e. filesystem
  journal write. Truncate/write to newly truncated space update file
  metadata twice thus truncate removal helps. With fallocate call
  inside bdrv_write_zeroes file metadata is updated only once and
  this should happen infrequently thus this approach is the best one
  for the image expansion
- tail writes are ordered, i.e. the guest IO queue could not be sent
  immediately to the host introducing additional IO delays

This patch just adds proper parameters into BDRVParallelsState and
performs options parsing in parallels_open.

Signed-off-by: Denis V. Lunev 
Reviewed-by: Roman Kagan 
Signed-off-by: Roman Kagan 
Message-id: 1430207220-24458-26-git-send-email-...@openvz.org
CC: Roman Kagan 
CC: Kevin Wolf 
CC: Stefan Hajnoczi 
Signed-off-by: Stefan Hajnoczi 
---
 block/parallels.c | 83 +++
 1 file changed, 77 insertions(+), 6 deletions(-)

diff --git a/block/parallels.c b/block/parallels.c
index 05fe030..440938e 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -31,6 +31,7 @@
 #include "block/block_int.h"
 #include "qemu/module.h"
 #include "qemu/bitmap.h"
+#include "qapi/util.h"
 
 /**/
 
@@ -56,6 +57,20 @@ typedef struct ParallelsHeader {
 char padding[12];
 } QEMU_PACKED ParallelsHeader;
 
+
+typedef enum ParallelsPreallocMode {
+PRL_PREALLOC_MODE_FALLOCATE = 0,
+PRL_PREALLOC_MODE_TRUNCATE = 1,
+PRL_PREALLOC_MODE_MAX = 2,
+} ParallelsPreallocMode;
+
+static const char *prealloc_mode_lookup[] = {
+"falloc",
+"truncate",
+NULL,
+};
+
+
 typedef struct BDRVParallelsState {
 /** Locking is conservative, the lock protects
  *   - image file extending (truncate, fallocate)
@@ -73,14 +88,40 @@ typedef struct BDRVParallelsState {
 uint32_t *bat_bitmap;
 unsigned int bat_size;
 
+uint64_t prealloc_size;
+ParallelsPreallocMode prealloc_mode;
+
 unsigned int tracks;
 
 unsigned int off_multiplier;
-
-bool has_truncate;
 } BDRVParallelsState;
 
 
+#define PARALLELS_OPT_PREALLOC_MODE "prealloc-mode"
+#define PARALLELS_OPT_PREALLOC_SIZE "prealloc-size"
+
+static QemuOptsList parallels_runtime_opts = {
+.name = "parallels",
+.head = QTAILQ_HEAD_INITIALIZER(parallels_runtime_opts.head),
+.desc = {
+{
+.name = PARALLELS_OPT_PREALLOC_SIZE,
+.type = QEMU_OPT_SIZE,
+.help = "Preallocation size on image expansion",
+.def_value_str = "128MiB",
+},
+{
+.name = PARALLELS_OPT_PREALLOC_MODE,
+.type = QEMU_OPT_STRING,
+.help = "Preallocation mode on image expansion "
+"(allowed values: falloc, truncate)",
+.def_value_str = "falloc",
+},
+{ /* end of list */ },
+},
+};
+
+
 static int64_t bat2sect(BDRVParallelsState *s, uint32_t idx)
 {
 return (uint64_t)le32_to_cpu(s->bat_bitmap[idx]) * s->off_multiplier;
@@ -159,7 +200,7 @@ static int64_t allocate_cluster(BlockDriverState *bs, 
int64_t sector_num)
 }
 
 pos = bdrv_getlength(bs->file) >> BDRV_SECTOR_BITS;
-if (s->has_truncate) {
+if (s->prealloc_mode == PRL_PREALLOC_MODE_TRUNCATE) {
 ret = bdrv_truncate(bs->file, (pos + s->tracks) << BDRV_SECTOR_BITS);
 } else {
 ret = bdrv_write_zeroes(bs->file, pos, s->tracks, 0);
@@ -509,6 +550,9 @@ static int parallels_open(BlockDriverState *bs, QDict 
*options, int flags,
 BDRVParallelsState *s = bs->opaque;
 ParallelsHeader ph;
 int ret, size;
+QemuOpts *opts = NULL;
+Error *local_err = NULL;
+char *buf;
 
 ret = bdrv_pread(bs->file, 0, &ph, sizeof(ph));
 if (ret < 0) {
@@ -567,9 +611,6 @@ static int parallels_open(BlockDriverState *bs, QDict 
*options, int flags,
 }
 s->bat_bitmap = (uint32_t *)(s->header + 1);
 
-s->has_truncate = bdrv_has_zero_init(bs->file) &&
-  bdrv_truncate(bs->file, bdrv_getlength(bs->file)) == 0;
-
 if (le32_to_cpu(ph.inuse) == HEADER_INUSE_MAGIC) {
 /* Image was not closed correctly. The check is mandatory */
 s->header_unclean = true;
@@ -581,6 +622,31 @@ static int parallels_open(BlockDriverState *bs, QDict 
*options, int flags,
 }
 }
 
+opts = qemu_opts_create(¶llels_runtime_opts, NULL, 0, &local_err);
+if (local_err != NULL) {
+goto fail_options;
+}
+
+qemu_opts_absorb_qdict(opts, options,

[Qemu-devel] [PULL 13/38] parallels: change copyright information in the image header

2015-05-22 Thread Stefan Hajnoczi
From: "Denis V. Lunev" 

Signed-off-by: Denis V. Lunev 
Reviewed-by: Roman Kagan 
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Roman Kagan 
Message-id: 1430207220-24458-14-git-send-email-...@openvz.org
CC: Kevin Wolf 
Signed-off-by: Stefan Hajnoczi 
---
 block/parallels.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/block/parallels.c b/block/parallels.c
index 15f6cb3..f615f44 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -2,8 +2,12 @@
  * Block driver for Parallels disk image format
  *
  * Copyright (c) 2007 Alex Beregszaszi
+ * Copyright (c) 2015 Denis V. Lunev 
  *
- * This code is based on comparing different disk images created by Parallels.
+ * This code was originally based on comparing different disk images created
+ * by Parallels. Currently it is based on opened OpenVZ sources
+ * available at
+ * http://git.openvz.org/?p=ploop;a=summary
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to 
deal
-- 
2.1.0




[Qemu-devel] [PULL 20/38] block/parallels: implement incorrect close detection

2015-05-22 Thread Stefan Hajnoczi
From: "Denis V. Lunev" 

The software driver must set inuse field in Parallels header to
0x746F6E59 when the image is opened in read-write mode. The presence of
this magic in the header on open forces image consistency check.

There is an unfortunate trick here. We can not check for inuse in
parallels_check as this will happen too late. It is possible to do
that for simple check, but during the fix this would always report
an error as the image was opened in BDRV_O_RDWR mode. Thus we save
the flag in BDRVParallelsState for this.

On the other hand, nothing should be done to clear inuse in
parallels_check. Generic close will do the job right.

Signed-off-by: Denis V. Lunev 
Reviewed-by: Roman Kagan 
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Roman Kagan 
Message-id: 1430207220-24458-21-git-send-email-...@openvz.org
CC: Kevin Wolf 
Signed-off-by: Stefan Hajnoczi 
---
 block/parallels.c | 50 ++
 1 file changed, 50 insertions(+)

diff --git a/block/parallels.c b/block/parallels.c
index 35f231a..76e3a4e 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -36,6 +36,7 @@
 #define HEADER_MAGIC "WithoutFreeSpace"
 #define HEADER_MAGIC2 "WithouFreSpacExt"
 #define HEADER_VERSION 2
+#define HEADER_INUSE_MAGIC  (0x746F6E59)
 
 #define DEFAULT_CLUSTER_SIZE 1048576/* 1 MiB */
 
@@ -63,6 +64,8 @@ typedef struct BDRVParallelsState {
 
 ParallelsHeader *header;
 uint32_t header_size;
+bool header_unclean;
+
 uint32_t *bat_bitmap;
 unsigned int bat_size;
 
@@ -259,6 +262,17 @@ static int parallels_check(BlockDriverState *bs, 
BdrvCheckResult *res,
 return size;
 }
 
+if (s->header_unclean) {
+fprintf(stderr, "%s image was not closed correctly\n",
+fix & BDRV_FIX_ERRORS ? "Repairing" : "ERROR");
+res->corruptions++;
+if (fix & BDRV_FIX_ERRORS) {
+/* parallels_close will do the job right */
+res->corruptions_fixed++;
+s->header_unclean = false;
+}
+}
+
 res->bfi.total_clusters = s->bat_size;
 res->bfi.compressed_clusters = 0; /* compression is not supported */
 
@@ -417,6 +431,17 @@ static int parallels_probe(const uint8_t *buf, int 
buf_size,
 return 0;
 }
 
+static int parallels_update_header(BlockDriverState *bs)
+{
+BDRVParallelsState *s = bs->opaque;
+unsigned size = MAX(bdrv_opt_mem_align(bs->file), sizeof(ParallelsHeader));
+
+if (size > s->header_size) {
+size = s->header_size;
+}
+return bdrv_pwrite_sync(bs->file, 0, s->header, size);
+}
+
 static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
   Error **errp)
 {
@@ -484,6 +509,25 @@ static int parallels_open(BlockDriverState *bs, QDict 
*options, int flags,
 s->has_truncate = bdrv_has_zero_init(bs->file) &&
   bdrv_truncate(bs->file, bdrv_getlength(bs->file)) == 0;
 
+if (le32_to_cpu(ph.inuse) == HEADER_INUSE_MAGIC) {
+/* Image was not closed correctly. The check is mandatory */
+s->header_unclean = true;
+if ((flags & BDRV_O_RDWR) && !(flags & BDRV_O_CHECK)) {
+error_setg(errp, "parallels: Image was not closed correctly; "
+   "cannot be opened read/write");
+ret = -EACCES;
+goto fail;
+}
+}
+
+if (flags & BDRV_O_RDWR) {
+s->header->inuse = cpu_to_le32(HEADER_INUSE_MAGIC);
+ret = parallels_update_header(bs);
+if (ret < 0) {
+goto fail;
+}
+}
+
 qemu_co_mutex_init(&s->lock);
 return 0;
 
@@ -499,6 +543,12 @@ fail:
 static void parallels_close(BlockDriverState *bs)
 {
 BDRVParallelsState *s = bs->opaque;
+
+if (bs->open_flags & BDRV_O_RDWR) {
+s->header->inuse = 0;
+parallels_update_header(bs);
+}
+
 qemu_vfree(s->header);
 }
 
-- 
2.1.0




[Qemu-devel] [PULL 15/38] block/parallels: create bat2sect helper

2015-05-22 Thread Stefan Hajnoczi
From: "Denis V. Lunev" 

deduplicate copy/paste arithmetcs

Signed-off-by: Denis V. Lunev 
Reviewed-by: Roman Kagan 
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Roman Kagan 
Message-id: 1430207220-24458-16-git-send-email-...@openvz.org
CC: Kevin Wolf 
Signed-off-by: Stefan Hajnoczi 
---
 block/parallels.c | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/block/parallels.c b/block/parallels.c
index 16fbdf4..1540c21 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -161,6 +161,12 @@ fail:
 return ret;
 }
 
+
+static int64_t bat2sect(BDRVParallelsState *s, uint32_t idx)
+{
+return (uint64_t)s->bat_bitmap[idx] * s->off_multiplier;
+}
+
 static int64_t seek_to_sector(BDRVParallelsState *s, int64_t sector_num)
 {
 uint32_t index, offset;
@@ -172,7 +178,7 @@ static int64_t seek_to_sector(BDRVParallelsState *s, 
int64_t sector_num)
 if ((index >= s->bat_size) || (s->bat_bitmap[index] == 0)) {
 return -1;
 }
-return (uint64_t)s->bat_bitmap[index] * s->off_multiplier + offset;
+return bat2sect(s, index) + offset;
 }
 
 static int cluster_remainder(BDRVParallelsState *s, int64_t sector_num,
@@ -196,7 +202,7 @@ static int64_t allocate_cluster(BlockDriverState *bs, 
int64_t sector_num)
 return -EINVAL;
 }
 if (s->bat_bitmap[idx] != 0) {
-return (uint64_t)s->bat_bitmap[idx] * s->off_multiplier + offset;
+return bat2sect(s, idx) + offset;
 }
 
 pos = bdrv_getlength(bs->file) >> BDRV_SECTOR_BITS;
@@ -219,7 +225,7 @@ static int64_t allocate_cluster(BlockDriverState *bs, 
int64_t sector_num)
 s->bat_bitmap[idx] = 0;
 return ret;
 }
-return (uint64_t)s->bat_bitmap[idx] * s->off_multiplier + offset;
+return bat2sect(s, idx) + offset;
 }
 
 static int64_t coroutine_fn parallels_co_get_block_status(BlockDriverState *bs,
-- 
2.1.0




[Qemu-devel] [PULL 22/38] block/parallels: improve image reading performance

2015-05-22 Thread Stefan Hajnoczi
From: "Denis V. Lunev" 

Try to perform IO for the biggest continuous block possible.
The performance for sequential read is increased from 220 Mb/sec to
360 Mb/sec for continous image on my SSD HDD.

Signed-off-by: Denis V. Lunev 
Reviewed-by: Roman Kagan 
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Roman Kagan 
Message-id: 1430207220-24458-23-git-send-email-...@openvz.org
CC: Kevin Wolf 
Signed-off-by: Stefan Hajnoczi 
---
 block/parallels.c | 36 +++-
 1 file changed, 31 insertions(+), 5 deletions(-)

diff --git a/block/parallels.c b/block/parallels.c
index 76e3a4e..5ff74e8 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -103,6 +103,35 @@ static int cluster_remainder(BDRVParallelsState *s, 
int64_t sector_num,
 return MIN(nb_sectors, ret);
 }
 
+static int64_t block_status(BDRVParallelsState *s, int64_t sector_num,
+int nb_sectors, int *pnum)
+{
+int64_t start_off = -2, prev_end_off = -2;
+
+*pnum = 0;
+while (nb_sectors > 0 || start_off == -2) {
+int64_t offset = seek_to_sector(s, sector_num);
+int to_end;
+
+if (start_off == -2) {
+start_off = offset;
+prev_end_off = offset;
+} else if (offset != prev_end_off) {
+break;
+}
+
+to_end = cluster_remainder(s, sector_num, nb_sectors);
+nb_sectors -= to_end;
+sector_num += to_end;
+*pnum += to_end;
+
+if (offset > 0) {
+prev_end_off += to_end;
+}
+}
+return start_off;
+}
+
 static int64_t allocate_cluster(BlockDriverState *bs, int64_t sector_num)
 {
 BDRVParallelsState *s = bs->opaque;
@@ -148,11 +177,9 @@ static int64_t coroutine_fn 
parallels_co_get_block_status(BlockDriverState *bs,
 int64_t offset;
 
 qemu_co_mutex_lock(&s->lock);
-offset = seek_to_sector(s, sector_num);
+offset = block_status(s, sector_num, nb_sectors, pnum);
 qemu_co_mutex_unlock(&s->lock);
 
-*pnum = cluster_remainder(s, sector_num, nb_sectors);
-
 if (offset < 0) {
 return 0;
 }
@@ -218,10 +245,9 @@ static coroutine_fn int 
parallels_co_readv(BlockDriverState *bs,
 int n, nbytes;
 
 qemu_co_mutex_lock(&s->lock);
-position = seek_to_sector(s, sector_num);
+position = block_status(s, sector_num, nb_sectors, &n);
 qemu_co_mutex_unlock(&s->lock);
 
-n = cluster_remainder(s, sector_num, nb_sectors);
 nbytes = n << BDRV_SECTOR_BITS;
 
 if (position < 0) {
-- 
2.1.0




[Qemu-devel] [PULL 31/38] configure: Add workaround for ccache and clang

2015-05-22 Thread Stefan Hajnoczi
From: John Snow 

Test if ccache is interfering with semantic analysis of macros,
disable its habit of trying to compile already pre-processed
versions of code if so. ccache attempts to save time by compiling
pre-processed versions of code, but this disturbs clang's static
analysis enough to produce false positives.

ccache allows us to disable this feature, opting instead to
compile the original version instead of its preprocessed version.
This makes ccache much slower for cache misses, but at least it
becomes usable with QEMU/clang.

This workaround only activates for users using ccache AND clang,
and only if their configuration is observed to be producing warnings.
You may need to clear your ccache for builds started without -Werror,
as those may continue to produce warnings from the cache.

Thanks to Peter Eisentraut for his writeup on the issue:
http://peter.eisentraut.org/blog/2014/12/01/ccache-and-clang-part-3/

Signed-off-by: John Snow 
Reviewed-by: Stefan Hajnoczi 
Message-id: 1427324259-1481-5-git-send-email-js...@redhat.com
Signed-off-by: Stefan Hajnoczi 
---
 configure | 34 +-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/configure b/configure
index 24d7ecc..f758f32 100755
--- a/configure
+++ b/configure
@@ -103,7 +103,8 @@ update_cxxflags() {
 }
 
 compile_object() {
-  do_cc $QEMU_CFLAGS -c -o $TMPO $TMPC
+  local_cflags="$1"
+  do_cc $QEMU_CFLAGS $local_cflags -c -o $TMPO $TMPC
 }
 
 compile_prog() {
@@ -4209,6 +4210,33 @@ if compile_prog "" "" ; then
 getauxval=yes
 fi
 
+
+# check if ccache is interfering with
+# semantic analysis of macros
+
+ccache_cpp2=no
+cat > $TMPC << EOF
+static const int Z = 1;
+#define fn() ({ Z; })
+#define TAUT(X) ((X) == Z)
+#define PAREN(X, Y) (X == Y)
+#define ID(X) (X)
+int main(int argc, char *argv[])
+{
+int x = 0, y = 0;
+x = ID(x);
+x = fn();
+fn();
+if (PAREN(x, y)) return 0;
+if (TAUT(Z)) return 0;
+return 0;
+}
+EOF
+
+if ! compile_object "-Werror"; then
+ccache_cpp2=yes
+fi
+
 ##
 # End of CC checks
 # After here, no more $cc or $ld runs
@@ -5502,6 +5530,10 @@ if test "$numa" = "yes"; then
   echo "CONFIG_NUMA=y" >> $config_host_mak
 fi
 
+if test "$ccache_cpp2" = "yes"; then
+  echo "export CCACHE_CPP2=y" >> $config_host_mak
+fi
+
 # build tree in object directory in case the source is not in the current 
directory
 DIRS="tests tests/tcg tests/tcg/cris tests/tcg/lm32 tests/libqos 
tests/qapi-schema tests/tcg/xtensa tests/qemu-iotests"
 DIRS="$DIRS fsdev"
-- 
2.1.0




[Qemu-devel] [PULL 14/38] block/parallels: rename catalog_ names to bat_

2015-05-22 Thread Stefan Hajnoczi
From: "Denis V. Lunev" 

BAT means 'block allocation table'. Thus this name is clean and shorter
on writing.

Some obvious formatting fixes in the old code were made to make checkpatch
happy.

Signed-off-by: Denis V. Lunev 
Reviewed-by: Roman Kagan 
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Roman Kagan 
Message-id: 1430207220-24458-15-git-send-email-...@openvz.org
CC: Kevin Wolf 
Signed-off-by: Stefan Hajnoczi 
---
 block/parallels.c | 58 ---
 1 file changed, 30 insertions(+), 28 deletions(-)

diff --git a/block/parallels.c b/block/parallels.c
index f615f44..16fbdf4 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -47,7 +47,7 @@ typedef struct ParallelsHeader {
 uint32_t heads;
 uint32_t cylinders;
 uint32_t tracks;
-uint32_t catalog_entries;
+uint32_t bat_entries;
 uint64_t nb_sectors;
 uint32_t inuse;
 uint32_t data_off;
@@ -61,8 +61,8 @@ typedef struct BDRVParallelsState {
  */
 CoMutex lock;
 
-uint32_t *catalog_bitmap;
-unsigned int catalog_size;
+uint32_t *bat_bitmap;
+unsigned int bat_size;
 
 unsigned int tracks;
 
@@ -125,26 +125,27 @@ static int parallels_open(BlockDriverState *bs, QDict 
*options, int flags,
 goto fail;
 }
 
-s->catalog_size = le32_to_cpu(ph.catalog_entries);
-if (s->catalog_size > INT_MAX / sizeof(uint32_t)) {
+s->bat_size = le32_to_cpu(ph.bat_entries);
+if (s->bat_size > INT_MAX / sizeof(uint32_t)) {
 error_setg(errp, "Catalog too large");
 ret = -EFBIG;
 goto fail;
 }
-s->catalog_bitmap = g_try_new(uint32_t, s->catalog_size);
-if (s->catalog_size && s->catalog_bitmap == NULL) {
+s->bat_bitmap = g_try_new(uint32_t, s->bat_size);
+if (s->bat_size && s->bat_bitmap == NULL) {
 ret = -ENOMEM;
 goto fail;
 }
 
 ret = bdrv_pread(bs->file, sizeof(ParallelsHeader),
- s->catalog_bitmap, s->catalog_size * sizeof(uint32_t));
+ s->bat_bitmap, s->bat_size * sizeof(uint32_t));
 if (ret < 0) {
 goto fail;
 }
 
-for (i = 0; i < s->catalog_size; i++)
-le32_to_cpus(&s->catalog_bitmap[i]);
+for (i = 0; i < s->bat_size; i++) {
+le32_to_cpus(&s->bat_bitmap[i]);
+}
 
 s->has_truncate = bdrv_has_zero_init(bs->file) &&
   bdrv_truncate(bs->file, bdrv_getlength(bs->file)) == 0;
@@ -156,7 +157,7 @@ fail_format:
 error_setg(errp, "Image not in Parallels format");
 ret = -EINVAL;
 fail:
-g_free(s->catalog_bitmap);
+g_free(s->bat_bitmap);
 return ret;
 }
 
@@ -168,9 +169,10 @@ static int64_t seek_to_sector(BDRVParallelsState *s, 
int64_t sector_num)
 offset = sector_num % s->tracks;
 
 /* not allocated */
-if ((index >= s->catalog_size) || (s->catalog_bitmap[index] == 0))
+if ((index >= s->bat_size) || (s->bat_bitmap[index] == 0)) {
 return -1;
-return (uint64_t)s->catalog_bitmap[index] * s->off_multiplier + offset;
+}
+return (uint64_t)s->bat_bitmap[index] * s->off_multiplier + offset;
 }
 
 static int cluster_remainder(BDRVParallelsState *s, int64_t sector_num,
@@ -190,11 +192,11 @@ static int64_t allocate_cluster(BlockDriverState *bs, 
int64_t sector_num)
 idx = sector_num / s->tracks;
 offset = sector_num % s->tracks;
 
-if (idx >= s->catalog_size) {
+if (idx >= s->bat_size) {
 return -EINVAL;
 }
-if (s->catalog_bitmap[idx] != 0) {
-return (uint64_t)s->catalog_bitmap[idx] * s->off_multiplier + offset;
+if (s->bat_bitmap[idx] != 0) {
+return (uint64_t)s->bat_bitmap[idx] * s->off_multiplier + offset;
 }
 
 pos = bdrv_getlength(bs->file) >> BDRV_SECTOR_BITS;
@@ -207,17 +209,17 @@ static int64_t allocate_cluster(BlockDriverState *bs, 
int64_t sector_num)
 return ret;
 }
 
-s->catalog_bitmap[idx] = pos / s->off_multiplier;
+s->bat_bitmap[idx] = pos / s->off_multiplier;
 
-tmp = cpu_to_le32(s->catalog_bitmap[idx]);
+tmp = cpu_to_le32(s->bat_bitmap[idx]);
 
 ret = bdrv_pwrite(bs->file,
 sizeof(ParallelsHeader) + idx * sizeof(tmp), &tmp, sizeof(tmp));
 if (ret < 0) {
-s->catalog_bitmap[idx] = 0;
+s->bat_bitmap[idx] = 0;
 return ret;
 }
-return (uint64_t)s->catalog_bitmap[idx] * s->off_multiplier + offset;
+return (uint64_t)s->bat_bitmap[idx] * s->off_multiplier + offset;
 }
 
 static int64_t coroutine_fn parallels_co_get_block_status(BlockDriverState *bs,
@@ -330,7 +332,7 @@ static int parallels_create(const char *filename, QemuOpts 
*opts, Error **errp)
 uint8_t tmp[BDRV_SECTOR_SIZE];
 Error *local_err = NULL;
 BlockDriverState *file;
-uint32_t cat_entries, cat_sectors;
+uint32_t bat_entries, bat_sectors;
 ParallelsHeader header;
 int ret;
 
@@ -357,10 +359,10 @@ static int parallels_create(const char *filename, 
QemuOpts *opts, Error **errp)
 goto exit;

[Qemu-devel] [PULL 17/38] block/parallels: read parallels image header and BAT into single buffer

2015-05-22 Thread Stefan Hajnoczi
From: "Denis V. Lunev" 

This metadata cache would allow to properly batch BAT updates to disk
in next patches. These updates will be properly aligned to avoid
read-modify-write transactions on block level.

Signed-off-by: Denis V. Lunev 
Reviewed-by: Roman Kagan 
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Roman Kagan 
Message-id: 1430207220-24458-18-git-send-email-...@openvz.org
CC: Kevin Wolf 
Signed-off-by: Stefan Hajnoczi 
---
 block/parallels.c | 24 +---
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/block/parallels.c b/block/parallels.c
index 431adf1..f8a9981 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -61,6 +61,8 @@ typedef struct BDRVParallelsState {
  */
 CoMutex lock;
 
+ParallelsHeader *header;
+uint32_t header_size;
 uint32_t *bat_bitmap;
 unsigned int bat_size;
 
@@ -91,7 +93,7 @@ static int parallels_open(BlockDriverState *bs, QDict 
*options, int flags,
 {
 BDRVParallelsState *s = bs->opaque;
 ParallelsHeader ph;
-int ret;
+int ret, size;
 
 ret = bdrv_pread(bs->file, 0, &ph, sizeof(ph));
 if (ret < 0) {
@@ -130,17 +132,25 @@ static int parallels_open(BlockDriverState *bs, QDict 
*options, int flags,
 ret = -EFBIG;
 goto fail;
 }
-s->bat_bitmap = g_try_new(uint32_t, s->bat_size);
-if (s->bat_size && s->bat_bitmap == NULL) {
+
+size = sizeof(ParallelsHeader) + sizeof(uint32_t) * s->bat_size;
+s->header_size = ROUND_UP(size, bdrv_opt_mem_align(bs->file));
+s->header = qemu_try_blockalign(bs->file, s->header_size);
+if (s->header == NULL) {
 ret = -ENOMEM;
 goto fail;
 }
+if (le32_to_cpu(ph.data_off) < s->header_size) {
+/* there is not enough unused space to fit to block align between BAT
+   and actual data. We can't avoid read-modify-write... */
+s->header_size = size;
+}
 
-ret = bdrv_pread(bs->file, sizeof(ParallelsHeader),
- s->bat_bitmap, s->bat_size * sizeof(uint32_t));
+ret = bdrv_pread(bs->file, 0, s->header, s->header_size);
 if (ret < 0) {
 goto fail;
 }
+s->bat_bitmap = (uint32_t *)(s->header + 1);
 
 s->has_truncate = bdrv_has_zero_init(bs->file) &&
   bdrv_truncate(bs->file, bdrv_getlength(bs->file)) == 0;
@@ -152,7 +162,7 @@ fail_format:
 error_setg(errp, "Image not in Parallels format");
 ret = -EINVAL;
 fail:
-g_free(s->bat_bitmap);
+qemu_vfree(s->header);
 return ret;
 }
 
@@ -400,7 +410,7 @@ exit:
 static void parallels_close(BlockDriverState *bs)
 {
 BDRVParallelsState *s = bs->opaque;
-g_free(s->bat_bitmap);
+qemu_vfree(s->header);
 }
 
 static QemuOptsList parallels_create_opts = {
-- 
2.1.0




[Qemu-devel] [PULL 34/38] block: align bounce buffers to page

2015-05-22 Thread Stefan Hajnoczi
From: "Denis V. Lunev" 

The following sequence
int fd = open(argv[1], O_RDWR | O_CREAT | O_DIRECT, 0644);
for (i = 0; i < 10; i++)
write(fd, buf, 4096);
performs 5% better if buf is aligned to 4096 bytes.

The difference is quite reliable.

On the other hand we do not want at the moment to enforce bounce
buffering if guest request is aligned to 512 bytes.

The patch changes default bounce buffer optimal alignment to
MAX(page size, 4k). 4k is chosen as maximal known sector size on real
HDD.

The justification of the performance improve is quite interesting.
>From the kernel point of view each request to the disk was split
by two. This could be seen by blktrace like this:
  9,0   11  1 0.0 11151  Q  WS 312737792 + 1023 [qemu-img]
  9,0   11  2 0.07938 11151  Q  WS 312738815 + 8 [qemu-img]
  9,0   11  3 0.30735 11151  Q  WS 312738823 + 1016 [qemu-img]
  9,0   11  4 0.32482 11151  Q  WS 312739839 + 8 [qemu-img]
  9,0   11  5 0.41379 11151  Q  WS 312739847 + 1016 [qemu-img]
  9,0   11  6 0.42818 11151  Q  WS 312740863 + 8 [qemu-img]
  9,0   11  7 0.51236 11151  Q  WS 312740871 + 1017 [qemu-img]
  9,05  1 0.169071519 11151  Q  WS 312741888 + 1023 [qemu-img]
After the patch the pattern becomes normal:
  9,06  1 0.0 12422  Q  WS 314834944 + 1024 [qemu-img]
  9,06  2 0.38527 12422  Q  WS 314835968 + 1024 [qemu-img]
  9,06  3 0.72849 12422  Q  WS 314836992 + 1024 [qemu-img]
  9,06  4 0.000106276 12422  Q  WS 314838016 + 1024 [qemu-img]
and the amount of requests sent to disk (could be calculated counting
number of lines in the output of blktrace) is reduced about 2 times.

Both qemu-img and qemu-io are affected while qemu-kvm is not. The guest
does his job well and real requests comes properly aligned (to page).

Signed-off-by: Denis V. Lunev 
Reviewed-by: Kevin Wolf 
Message-id: 1431441056-26198-3-git-send-email-...@openvz.org
CC: Paolo Bonzini 
CC: Kevin Wolf 
CC: Stefan Hajnoczi 
Signed-off-by: Stefan Hajnoczi 
---
 block.c   |  8 
 block/io.c|  2 +-
 block/raw-posix.c | 13 +++--
 3 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/block.c b/block.c
index e293907..325f727 100644
--- a/block.c
+++ b/block.c
@@ -106,8 +106,8 @@ int is_windows_drive(const char *filename)
 size_t bdrv_opt_mem_align(BlockDriverState *bs)
 {
 if (!bs || !bs->drv) {
-/* 4k should be on the safe side */
-return 4096;
+/* page size or 4k (hdd sector size) should be on the safe side */
+return MAX(4096, getpagesize());
 }
 
 return bs->bl.opt_mem_alignment;
@@ -116,8 +116,8 @@ size_t bdrv_opt_mem_align(BlockDriverState *bs)
 size_t bdrv_min_mem_align(BlockDriverState *bs)
 {
 if (!bs || !bs->drv) {
-/* 4k should be on the safe side */
-return 4096;
+/* page size or 4k (hdd sector size) should be on the safe side */
+return MAX(4096, getpagesize());
 }
 
 return bs->bl.min_mem_alignment;
diff --git a/block/io.c b/block/io.c
index e6c3639..b3ea95c 100644
--- a/block/io.c
+++ b/block/io.c
@@ -205,7 +205,7 @@ void bdrv_refresh_limits(BlockDriverState *bs, Error **errp)
 bs->bl.opt_mem_alignment = bs->file->bl.opt_mem_alignment;
 } else {
 bs->bl.min_mem_alignment = 512;
-bs->bl.opt_mem_alignment = 512;
+bs->bl.opt_mem_alignment = getpagesize();
 }
 
 if (bs->backing_hd) {
diff --git a/block/raw-posix.c b/block/raw-posix.c
index 7083924..2990e95 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -301,6 +301,7 @@ static void raw_probe_alignment(BlockDriverState *bs, int 
fd, Error **errp)
 {
 BDRVRawState *s = bs->opaque;
 char *buf;
+size_t max_align = MAX(MAX_BLOCKSIZE, getpagesize());
 
 /* For /dev/sg devices the alignment is not really used.
With buffered I/O, we don't have any restrictions. */
@@ -330,9 +331,9 @@ static void raw_probe_alignment(BlockDriverState *bs, int 
fd, Error **errp)
 /* If we could not get the sizes so far, we can only guess them */
 if (!s->buf_align) {
 size_t align;
-buf = qemu_memalign(MAX_BLOCKSIZE, 2 * MAX_BLOCKSIZE);
-for (align = 512; align <= MAX_BLOCKSIZE; align <<= 1) {
-if (raw_is_io_aligned(fd, buf + align, MAX_BLOCKSIZE)) {
+buf = qemu_memalign(max_align, 2 * max_align);
+for (align = 512; align <= max_align; align <<= 1) {
+if (raw_is_io_aligned(fd, buf + align, max_align)) {
 s->buf_align = align;
 break;
 }
@@ -342,8 +343,8 @@ static void raw_probe_alignment(BlockDriverState *bs, int 
fd, Error **errp)
 
 if (!bs->request_alignment) {
 size_t align;
-buf = qemu_memalign(s->buf_align, MAX_BLOCKSIZE);
-for (align = 512; align <= MAX_BLOCKSIZE; align <<= 1) {
+buf = qemu_memalign(s->buf_align, max_align);
+ 

[Qemu-devel] [PULL 26/38] block/parallels: optimize linear image expansion

2015-05-22 Thread Stefan Hajnoczi
From: "Denis V. Lunev" 

Plain image expansion spends a lot of time to update image file size.
This seriously affects the performance. The following simple test
  qemu_img create -f parallels -o cluster_size=64k ./1.hds 64G
  qemu_io -n -c "write -P 0x11 0 1024M" ./1.hds
could be improved if the format driver will pre-allocate some space
in the image file with a reasonable chunk.

This patch preallocates 128 Mb using bdrv_write_zeroes, which should
normally use fallocate() call inside. Fallback to older truncate()
could be used as a fallback using image open options thanks to the
previous patch.

The benefit is around 15%.

Signed-off-by: Denis V. Lunev 
Reviewed-by: Roman Karan 
Signed-off-by: Roman Kagan 
Message-id: 1430207220-24458-27-git-send-email-...@openvz.org
CC: Kevin Wolf 
CC: Stefan Hajnoczi 
Signed-off-by: Stefan Hajnoczi 
---
 block/parallels.c | 42 --
 1 file changed, 32 insertions(+), 10 deletions(-)

diff --git a/block/parallels.c b/block/parallels.c
index 440938e..e7124d9 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -88,6 +88,7 @@ typedef struct BDRVParallelsState {
 uint32_t *bat_bitmap;
 unsigned int bat_size;
 
+int64_t  data_end;
 uint64_t prealloc_size;
 ParallelsPreallocMode prealloc_mode;
 
@@ -187,7 +188,6 @@ static int64_t allocate_cluster(BlockDriverState *bs, 
int64_t sector_num)
 BDRVParallelsState *s = bs->opaque;
 uint32_t idx, offset;
 int64_t pos;
-int ret;
 
 idx = sector_num / s->tracks;
 offset = sector_num % s->tracks;
@@ -200,14 +200,21 @@ static int64_t allocate_cluster(BlockDriverState *bs, 
int64_t sector_num)
 }
 
 pos = bdrv_getlength(bs->file) >> BDRV_SECTOR_BITS;
-if (s->prealloc_mode == PRL_PREALLOC_MODE_TRUNCATE) {
-ret = bdrv_truncate(bs->file, (pos + s->tracks) << BDRV_SECTOR_BITS);
-} else {
-ret = bdrv_write_zeroes(bs->file, pos, s->tracks, 0);
-}
-if (ret < 0) {
-return ret;
+if (s->data_end + s->tracks > pos) {
+int ret;
+if (s->prealloc_mode == PRL_PREALLOC_MODE_FALLOCATE) {
+ret = bdrv_write_zeroes(bs->file, s->data_end,
+s->prealloc_size, 0);
+} else {
+ret = bdrv_truncate(bs->file,
+(s->data_end + s->prealloc_size) << BDRV_SECTOR_BITS);
+}
+if (ret < 0) {
+return ret;
+}
 }
+pos = s->data_end;
+s->data_end += s->tracks;
 
 s->bat_bitmap[idx] = cpu_to_le32(pos / s->off_multiplier);
 
@@ -549,7 +556,7 @@ static int parallels_open(BlockDriverState *bs, QDict 
*options, int flags,
 {
 BDRVParallelsState *s = bs->opaque;
 ParallelsHeader ph;
-int ret, size;
+int ret, size, i;
 QemuOpts *opts = NULL;
 Error *local_err = NULL;
 char *buf;
@@ -599,7 +606,11 @@ static int parallels_open(BlockDriverState *bs, QDict 
*options, int flags,
 ret = -ENOMEM;
 goto fail;
 }
-if (le32_to_cpu(ph.data_off) < s->header_size) {
+s->data_end = le32_to_cpu(ph.data_off);
+if (s->data_end == 0) {
+s->data_end = ROUND_UP(bat_entry_off(s->bat_size), BDRV_SECTOR_SIZE);
+}
+if (s->data_end < s->header_size) {
 /* there is not enough unused space to fit to block align between BAT
and actual data. We can't avoid read-modify-write... */
 s->header_size = size;
@@ -611,6 +622,13 @@ static int parallels_open(BlockDriverState *bs, QDict 
*options, int flags,
 }
 s->bat_bitmap = (uint32_t *)(s->header + 1);
 
+for (i = 0; i < s->bat_size; i++) {
+int64_t off = bat2sect(s, i);
+if (off >= s->data_end) {
+s->data_end = off + s->tracks;
+}
+}
+
 if (le32_to_cpu(ph.inuse) == HEADER_INUSE_MAGIC) {
 /* Image was not closed correctly. The check is mandatory */
 s->header_unclean = true;
@@ -685,6 +703,10 @@ static void parallels_close(BlockDriverState *bs)
 parallels_update_header(bs);
 }
 
+if (bs->open_flags & BDRV_O_RDWR) {
+bdrv_truncate(bs->file, s->data_end << BDRV_SECTOR_BITS);
+}
+
 g_free(s->bat_dirty_bmap);
 qemu_vfree(s->header);
 }
-- 
2.1.0




[Qemu-devel] [PULL 18/38] block/parallels: move parallels_open/probe to the very end of the file

2015-05-22 Thread Stefan Hajnoczi
From: "Denis V. Lunev" 

This will help to avoid forward declarations for upcoming parallels_check

Some very obvious formatting fixes were made to the moved code to make
checkpatch happy.

Signed-off-by: Denis V. Lunev 
Reviewed-by: Roman Kagan 
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Roman Kagan 
Message-id: 1430207220-24458-19-git-send-email-...@openvz.org
CC: Kevin Wolf 
Signed-off-by: Stefan Hajnoczi 
---
 block/parallels.c | 191 --
 1 file changed, 98 insertions(+), 93 deletions(-)

diff --git a/block/parallels.c b/block/parallels.c
index f8a9981..35ffb6f 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -73,99 +73,6 @@ typedef struct BDRVParallelsState {
 bool has_truncate;
 } BDRVParallelsState;
 
-static int parallels_probe(const uint8_t *buf, int buf_size, const char 
*filename)
-{
-const ParallelsHeader *ph = (const void *)buf;
-
-if (buf_size < sizeof(ParallelsHeader))
-return 0;
-
-if ((!memcmp(ph->magic, HEADER_MAGIC, 16) ||
-!memcmp(ph->magic, HEADER_MAGIC2, 16)) &&
-(le32_to_cpu(ph->version) == HEADER_VERSION))
-return 100;
-
-return 0;
-}
-
-static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
-  Error **errp)
-{
-BDRVParallelsState *s = bs->opaque;
-ParallelsHeader ph;
-int ret, size;
-
-ret = bdrv_pread(bs->file, 0, &ph, sizeof(ph));
-if (ret < 0) {
-goto fail;
-}
-
-bs->total_sectors = le64_to_cpu(ph.nb_sectors);
-
-if (le32_to_cpu(ph.version) != HEADER_VERSION) {
-goto fail_format;
-}
-if (!memcmp(ph.magic, HEADER_MAGIC, 16)) {
-s->off_multiplier = 1;
-bs->total_sectors = 0x & bs->total_sectors;
-} else if (!memcmp(ph.magic, HEADER_MAGIC2, 16)) {
-s->off_multiplier = le32_to_cpu(ph.tracks);
-} else {
-goto fail_format;
-}
-
-s->tracks = le32_to_cpu(ph.tracks);
-if (s->tracks == 0) {
-error_setg(errp, "Invalid image: Zero sectors per track");
-ret = -EINVAL;
-goto fail;
-}
-if (s->tracks > INT32_MAX/513) {
-error_setg(errp, "Invalid image: Too big cluster");
-ret = -EFBIG;
-goto fail;
-}
-
-s->bat_size = le32_to_cpu(ph.bat_entries);
-if (s->bat_size > INT_MAX / sizeof(uint32_t)) {
-error_setg(errp, "Catalog too large");
-ret = -EFBIG;
-goto fail;
-}
-
-size = sizeof(ParallelsHeader) + sizeof(uint32_t) * s->bat_size;
-s->header_size = ROUND_UP(size, bdrv_opt_mem_align(bs->file));
-s->header = qemu_try_blockalign(bs->file, s->header_size);
-if (s->header == NULL) {
-ret = -ENOMEM;
-goto fail;
-}
-if (le32_to_cpu(ph.data_off) < s->header_size) {
-/* there is not enough unused space to fit to block align between BAT
-   and actual data. We can't avoid read-modify-write... */
-s->header_size = size;
-}
-
-ret = bdrv_pread(bs->file, 0, s->header, s->header_size);
-if (ret < 0) {
-goto fail;
-}
-s->bat_bitmap = (uint32_t *)(s->header + 1);
-
-s->has_truncate = bdrv_has_zero_init(bs->file) &&
-  bdrv_truncate(bs->file, bdrv_getlength(bs->file)) == 0;
-
-qemu_co_mutex_init(&s->lock);
-return 0;
-
-fail_format:
-error_setg(errp, "Image not in Parallels format");
-ret = -EINVAL;
-fail:
-qemu_vfree(s->header);
-return ret;
-}
-
 
 static int64_t bat2sect(BDRVParallelsState *s, uint32_t idx)
 {
@@ -407,6 +314,104 @@ exit:
 goto done;
 }
 
+
+static int parallels_probe(const uint8_t *buf, int buf_size,
+   const char *filename)
+{
+const ParallelsHeader *ph = (const void *)buf;
+
+if (buf_size < sizeof(ParallelsHeader)) {
+return 0;
+}
+
+if ((!memcmp(ph->magic, HEADER_MAGIC, 16) ||
+   !memcmp(ph->magic, HEADER_MAGIC2, 16)) &&
+   (le32_to_cpu(ph->version) == HEADER_VERSION)) {
+return 100;
+}
+
+return 0;
+}
+
+static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
+  Error **errp)
+{
+BDRVParallelsState *s = bs->opaque;
+ParallelsHeader ph;
+int ret, size;
+
+ret = bdrv_pread(bs->file, 0, &ph, sizeof(ph));
+if (ret < 0) {
+goto fail;
+}
+
+bs->total_sectors = le64_to_cpu(ph.nb_sectors);
+
+if (le32_to_cpu(ph.version) != HEADER_VERSION) {
+goto fail_format;
+}
+if (!memcmp(ph.magic, HEADER_MAGIC, 16)) {
+s->off_multiplier = 1;
+bs->total_sectors = 0x & bs->total_sectors;
+} else if (!memcmp(ph.magic, HEADER_MAGIC2, 16)) {
+s->off_multiplier = le32_to_cpu(ph.tracks);
+} else {
+goto fail_format;
+}
+
+s->tracks = le32_to_cpu(ph.tracks);
+if (s->tracks == 0) {
+error_setg(errp, "Invalid image: Zero sectors per track");
+ret = -EINVAL;
+

[Qemu-devel] [PULL 36/38] block: Fix NULL deference for unaligned write if qiov is NULL

2015-05-22 Thread Stefan Hajnoczi
From: Fam Zheng 

For zero write, callers pass in NULL qiov (qemu-io "write -z" or
scsi-disk "write same").

Commit fc3959e466 fixed bdrv_co_write_zeroes which is the common case
for this bug, but it still exists in bdrv_aio_write_zeroes. A simpler
fix would be in bdrv_co_do_pwritev which is the NULL dereference point
and covers both cases.

So don't access it in bdrv_co_do_pwritev in this case, use three aligned
writes.

[Initialize ret to 0 in bdrv_co_do_zero_pwritev() to avoid uninitialized
variable warning with gcc 4.9.2.
--Stefan]

Signed-off-by: Fam Zheng 
Message-id: 1431522721-3266-3-git-send-email-f...@redhat.com
Signed-off-by: Stefan Hajnoczi 
---
 block/io.c | 97 --
 1 file changed, 95 insertions(+), 2 deletions(-)

diff --git a/block/io.c b/block/io.c
index ad877b0..284784e 100644
--- a/block/io.c
+++ b/block/io.c
@@ -1179,6 +1179,94 @@ static int coroutine_fn 
bdrv_aligned_pwritev(BlockDriverState *bs,
 return ret;
 }
 
+static int coroutine_fn bdrv_co_do_zero_pwritev(BlockDriverState *bs,
+int64_t offset,
+unsigned int bytes,
+BdrvRequestFlags flags,
+BdrvTrackedRequest *req)
+{
+uint8_t *buf = NULL;
+QEMUIOVector local_qiov;
+struct iovec iov;
+uint64_t align = MAX(BDRV_SECTOR_SIZE, bs->request_alignment);
+unsigned int head_padding_bytes, tail_padding_bytes;
+int ret = 0;
+
+head_padding_bytes = offset & (align - 1);
+tail_padding_bytes = align - ((offset + bytes) & (align - 1));
+
+
+assert(flags & BDRV_REQ_ZERO_WRITE);
+if (head_padding_bytes || tail_padding_bytes) {
+buf = qemu_blockalign(bs, align);
+iov = (struct iovec) {
+.iov_base   = buf,
+.iov_len= align,
+};
+qemu_iovec_init_external(&local_qiov, &iov, 1);
+}
+if (head_padding_bytes) {
+uint64_t zero_bytes = MIN(bytes, align - head_padding_bytes);
+
+/* RMW the unaligned part before head. */
+mark_request_serialising(req, align);
+wait_serialising_requests(req);
+BLKDBG_EVENT(bs, BLKDBG_PWRITEV_RMW_HEAD);
+ret = bdrv_aligned_preadv(bs, req, offset & ~(align - 1), align,
+  align, &local_qiov, 0);
+if (ret < 0) {
+goto fail;
+}
+BLKDBG_EVENT(bs, BLKDBG_PWRITEV_RMW_AFTER_HEAD);
+
+memset(buf + head_padding_bytes, 0, zero_bytes);
+ret = bdrv_aligned_pwritev(bs, req, offset & ~(align - 1), align,
+   &local_qiov,
+   flags & ~BDRV_REQ_ZERO_WRITE);
+if (ret < 0) {
+goto fail;
+}
+offset += zero_bytes;
+bytes -= zero_bytes;
+}
+
+assert(!bytes || (offset & (align - 1)) == 0);
+if (bytes >= align) {
+/* Write the aligned part in the middle. */
+uint64_t aligned_bytes = bytes & ~(align - 1);
+ret = bdrv_aligned_pwritev(bs, req, offset, aligned_bytes,
+   NULL, flags);
+if (ret < 0) {
+goto fail;
+}
+bytes -= aligned_bytes;
+offset += aligned_bytes;
+}
+
+assert(!bytes || (offset & (align - 1)) == 0);
+if (bytes) {
+assert(align == tail_padding_bytes + bytes);
+/* RMW the unaligned part after tail. */
+mark_request_serialising(req, align);
+wait_serialising_requests(req);
+BLKDBG_EVENT(bs, BLKDBG_PWRITEV_RMW_TAIL);
+ret = bdrv_aligned_preadv(bs, req, offset, align,
+  align, &local_qiov, 0);
+if (ret < 0) {
+goto fail;
+}
+BLKDBG_EVENT(bs, BLKDBG_PWRITEV_RMW_AFTER_TAIL);
+
+memset(buf, 0, bytes);
+ret = bdrv_aligned_pwritev(bs, req, offset, align,
+   &local_qiov, flags & ~BDRV_REQ_ZERO_WRITE);
+}
+fail:
+qemu_vfree(buf);
+return ret;
+
+}
+
 /*
  * Handle a write request in coroutine context
  */
@@ -1219,6 +1307,11 @@ static int coroutine_fn 
bdrv_co_do_pwritev(BlockDriverState *bs,
  */
 tracked_request_begin(&req, bs, offset, bytes, true);
 
+if (!qiov) {
+ret = bdrv_co_do_zero_pwritev(bs, offset, bytes, flags, &req);
+goto out;
+}
+
 if (offset & (align - 1)) {
 QEMUIOVector head_qiov;
 struct iovec head_iov;
@@ -1292,14 +1385,14 @@ static int coroutine_fn 
bdrv_co_do_pwritev(BlockDriverState *bs,
flags);
 
 fail:
-tracked_request_end(&req);
 
 if (use_local_qiov) {
 qemu_iovec_destroy(&local_qiov);
 }
 qemu_vfree(head_buf);
 qemu_vfree(tail_buf);
-
+out:
+tracked_request_end(&req);
 return ret;
 }
 
-- 
2.1.0




[Qemu-devel] [PULL 19/38] block/parallels: implement parallels_check method of block driver

2015-05-22 Thread Stefan Hajnoczi
From: "Denis V. Lunev" 

The check is very simple at the moment. It calculates necessary stats
and fix only the following errors:
- space leak at the end of the image. This would happens due to
  preallocation
- clusters outside the image are zeroed. Nothing else could be done here

Signed-off-by: Denis V. Lunev 
Reviewed-by: Roman Kagan 
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Roman Kagan 
Message-id: 1430207220-24458-20-git-send-email-...@openvz.org
CC: Kevin Wolf 
Signed-off-by: Stefan Hajnoczi 
---
 block/parallels.c | 85 +++
 1 file changed, 85 insertions(+)

diff --git a/block/parallels.c b/block/parallels.c
index 35ffb6f..35f231a 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -242,6 +242,90 @@ static coroutine_fn int 
parallels_co_readv(BlockDriverState *bs,
 return ret;
 }
 
+
+static int parallels_check(BlockDriverState *bs, BdrvCheckResult *res,
+   BdrvCheckMode fix)
+{
+BDRVParallelsState *s = bs->opaque;
+int64_t size, prev_off, high_off;
+int ret;
+uint32_t i;
+bool flush_bat = false;
+int cluster_size = s->tracks << BDRV_SECTOR_BITS;
+
+size = bdrv_getlength(bs->file);
+if (size < 0) {
+res->check_errors++;
+return size;
+}
+
+res->bfi.total_clusters = s->bat_size;
+res->bfi.compressed_clusters = 0; /* compression is not supported */
+
+high_off = 0;
+prev_off = 0;
+for (i = 0; i < s->bat_size; i++) {
+int64_t off = bat2sect(s, i) << BDRV_SECTOR_BITS;
+if (off == 0) {
+prev_off = 0;
+continue;
+}
+
+/* cluster outside the image */
+if (off > size) {
+fprintf(stderr, "%s cluster %u is outside image\n",
+fix & BDRV_FIX_ERRORS ? "Repairing" : "ERROR", i);
+res->corruptions++;
+if (fix & BDRV_FIX_ERRORS) {
+prev_off = 0;
+s->bat_bitmap[i] = 0;
+res->corruptions_fixed++;
+flush_bat = true;
+continue;
+}
+}
+
+res->bfi.allocated_clusters++;
+if (off > high_off) {
+high_off = off;
+}
+
+if (prev_off != 0 && (prev_off + cluster_size) != off) {
+res->bfi.fragmented_clusters++;
+}
+prev_off = off;
+}
+
+if (flush_bat) {
+ret = bdrv_pwrite_sync(bs->file, 0, s->header, s->header_size);
+if (ret < 0) {
+res->check_errors++;
+return ret;
+}
+}
+
+res->image_end_offset = high_off + cluster_size;
+if (size > res->image_end_offset) {
+int64_t count;
+count = DIV_ROUND_UP(size - res->image_end_offset, cluster_size);
+fprintf(stderr, "%s space leaked at the end of the image %" PRId64 
"\n",
+fix & BDRV_FIX_LEAKS ? "Repairing" : "ERROR",
+size - res->image_end_offset);
+res->leaks += count;
+if (fix & BDRV_FIX_LEAKS) {
+ret = bdrv_truncate(bs->file, res->image_end_offset);
+if (ret < 0) {
+res->check_errors++;
+return ret;
+}
+res->leaks_fixed += count;
+}
+}
+
+return 0;
+}
+
+
 static int parallels_create(const char *filename, QemuOpts *opts, Error **errp)
 {
 int64_t total_size, cl_size;
@@ -449,6 +533,7 @@ static BlockDriver bdrv_parallels = {
 .bdrv_co_writev = parallels_co_writev,
 
 .bdrv_create= parallels_create,
+.bdrv_check = parallels_check,
 .create_opts= ¶llels_create_opts,
 };
 
-- 
2.1.0




[Qemu-devel] [PULL 28/38] configure: handle clang -nopie argument warning

2015-05-22 Thread Stefan Hajnoczi
gcc 4.9.2 treats -nopie as an error:

  cc: error: unrecognized command line option ‘-nopie’

clang 3.5.0 treats -nopie as a warning:

  clang: warning: argument unused during compilation: '-nopie'

The causes ./configure to fail with clang:

  ERROR: configure test passed without -Werror but failed with -Werror.

Make the -nopie test use -Werror so that compile_prog works for both gcc
and clang.

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: John Snow 
Reviewed-by: Stefan Hajnoczi 
Message-id: 1427324259-1481-2-git-send-email-js...@redhat.com
Signed-off-by: Stefan Hajnoczi 
---
 configure | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configure b/configure
index 1f0f485..770f4c6 100755
--- a/configure
+++ b/configure
@@ -1607,7 +1607,7 @@ EOF
 fi
   fi
 
-  if compile_prog "-fno-pie" "-nopie"; then
+  if compile_prog "-Werror -fno-pie" "-nopie"; then
 CFLAGS_NOPIE="-fno-pie"
 LDFLAGS_NOPIE="-nopie"
   fi
-- 
2.1.0




[Qemu-devel] [PULL 21/38] iotests, parallels: check for incorrectly closed image in tests

2015-05-22 Thread Stefan Hajnoczi
From: "Denis V. Lunev" 

Signed-off-by: Denis V. Lunev 
Reviewed-by: Roman Kagan 
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Roman Kagan 
Message-id: 1430207220-24458-22-git-send-email-...@openvz.org
CC: Kevin Wolf 
Signed-off-by: Stefan Hajnoczi 
---
 tests/qemu-iotests/131 |  9 +
 tests/qemu-iotests/131.out | 17 +
 2 files changed, 26 insertions(+)

diff --git a/tests/qemu-iotests/131 b/tests/qemu-iotests/131
index f45afa7..4873f40 100755
--- a/tests/qemu-iotests/131
+++ b/tests/qemu-iotests/131
@@ -42,6 +42,8 @@ _supported_fmt parallels
 _supported_proto file
 _supported_os Linux
 
+inuse_offset=$((0x2c))
+
 size=64M
 CLUSTER_SIZE=64k
 IMGFMT=parallels
@@ -62,6 +64,13 @@ echo == check that there is no trash after written ==
 echo == check that there is no trash before written ==
 { $QEMU_IO -c "read -P 0 0 32k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | 
_filter_testdir
 
+echo "== Corrupt image =="
+poke_file "$TEST_IMG" "$inuse_offset" "\x59\x6e\x6f\x74"
+{ $QEMU_IO -c "read -P 0x11 64k 64k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | 
_filter_testdir
+_check_test_img
+_check_test_img -r all
+{ $QEMU_IO -c "read -P 0x11 64k 64k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | 
_filter_testdir
+
 # success, all done
 echo "*** done"
 rm -f $seq.full
diff --git a/tests/qemu-iotests/131.out b/tests/qemu-iotests/131.out
index 4158a2f..021a04c 100644
--- a/tests/qemu-iotests/131.out
+++ b/tests/qemu-iotests/131.out
@@ -21,4 +21,21 @@ read 32768/32768 bytes at offset 163840
 == check that there is no trash before written ==
 read 32768/32768 bytes at offset 0
 32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+== Corrupt image ==
+qemu-io: can't open device TEST_DIR/t.parallels: parallels: Image was not 
closed correctly; cannot be opened read/write
+no file open, try 'help open'
+ERROR image was not closed correctly
+
+1 errors were found on the image.
+Data may be corrupted, or further writes to the image may corrupt it.
+Repairing image was not closed correctly
+The following inconsistencies were found and repaired:
+
+0 leaked clusters
+1 corruptions
+
+Double checking the fixed image now...
+No errors were found on the image.
+read 65536/65536 bytes at offset 65536
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 *** done
-- 
2.1.0




Re: [Qemu-devel] [PATCH 06/10] crypto: add a nettle cipher implementation

2015-05-22 Thread Daniel P. Berrange
On Thu, May 21, 2015 at 12:38:01PM -0700, Richard Henderson wrote:
> On 05/21/2015 03:56 AM, Daniel P. Berrange wrote:
> > +static uint8_t *qcrypto_cipher_munge_des_rfb_key(const uint8_t *key,
> > + size_t nkey)
> > +{
> > +uint8_t *ret = g_new0(uint8_t, nkey);
> > +size_t i;
> > +for (i = 0; i < nkey; i++) {
> > +uint8_t r = key[i];
> > +r = (r & 0xf0)>>4 | (r & 0x0f)<<4;
> > +r = (r & 0xcc)>>2 | (r & 0x33)<<2;
> > +r = (r & 0xaa)>>1 | (r & 0x55)<<1;
> > +ret[i] = r;
> > +}
> > +return ret;
> > +}
> > +
> 
> Surely you can share this between the gcrypt and nettle files and not 
> duplicate
> it...

Potentially, but it was small enough that I felt it not worth the bother
of introducing another file for sharing it. The copyright header on a
new file would be larger than the amount of code shared in a new file.

Regards,
Daniel
-- 
|: http://berrange.com  -o-http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org  -o- http://virt-manager.org :|
|: http://autobuild.org   -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org   -o-   http://live.gnome.org/gtk-vnc :|



[Qemu-devel] [PULL 29/38] configure: factor out supported flag check

2015-05-22 Thread Stefan Hajnoczi
From: John Snow 

Factor out the function that checks if a compiler
flag is supported or not.

Signed-off-by: John Snow 
Reviewed-by: Stefan Hajnoczi 
Message-id: 1427324259-1481-3-git-send-email-js...@redhat.com
Signed-off-by: Stefan Hajnoczi 
---
 configure | 33 +++--
 1 file changed, 19 insertions(+), 14 deletions(-)

diff --git a/configure b/configure
index 770f4c6..f744266 100755
--- a/configure
+++ b/configure
@@ -436,6 +436,12 @@ EOF
   compile_object
 }
 
+write_c_skeleton() {
+cat > $TMPC < $TMPC << EOF
-int main(void) { return 0; }
-EOF
+  write_c_skeleton;
   if compile_prog "" "-liberty" ; then
 LIBS="-liberty $LIBS"
   fi
@@ -1445,10 +1449,7 @@ if test -z "$werror" ; then
 fi
 
 # check that the C compiler works.
-cat > $TMPC < $TMPC << EOF
-int main(void) { return 0; }
-EOF
-for flag in $gcc_flags; do
+
+cc_has_warning_flag() {
+write_c_skeleton;
+
 # Use the positive sense of the flag when testing for -Wno-wombat
 # support (gcc will happily accept the -Wno- form of unknown
 # warning options).
-optflag="$(echo $flag | sed -e 's/^-Wno-/-W/')"
-if compile_prog "-Werror $optflag" "" ; then
-   QEMU_CFLAGS="$QEMU_CFLAGS $flag"
+optflag="$(echo $1 | sed -e 's/^-Wno-/-W/')"
+compile_prog "-Werror $optflag" ""
+}
+
+for flag in $gcc_flags; do
+if cc_has_warning_flag $flag ; then
+QEMU_CFLAGS="$QEMU_CFLAGS $flag"
 fi
 done
 
-- 
2.1.0




[Qemu-devel] [PULL 27/38] block/parallels: improve image writing performance further

2015-05-22 Thread Stefan Hajnoczi
From: "Denis V. Lunev" 

Try to perform IO for the biggest continuous block possible.
All blocks abscent in the image are accounted in the same type
and preallocation is made for all of them at once.

The performance for sequential write is increased from 200 Mb/sec to
235 Mb/sec on my SSD HDD.

Signed-off-by: Denis V. Lunev 
Reviewed-by: Roman Kagan 
Signed-off-by: Roman Kagan 
Message-id: 1430207220-24458-28-git-send-email-...@openvz.org
CC: Kevin Wolf 
CC: Stefan Hajnoczi 
Signed-off-by: Stefan Hajnoczi 
---
 block/parallels.c | 43 +++
 1 file changed, 23 insertions(+), 20 deletions(-)

diff --git a/block/parallels.c b/block/parallels.c
index e7124d9..046b568 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -183,43 +183,47 @@ static int64_t block_status(BDRVParallelsState *s, 
int64_t sector_num,
 return start_off;
 }
 
-static int64_t allocate_cluster(BlockDriverState *bs, int64_t sector_num)
+static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num,
+ int nb_sectors, int *pnum)
 {
 BDRVParallelsState *s = bs->opaque;
-uint32_t idx, offset;
-int64_t pos;
+uint32_t idx, to_allocate, i;
+int64_t pos, space;
+
+pos = block_status(s, sector_num, nb_sectors, pnum);
+if (pos > 0) {
+return pos;
+}
 
 idx = sector_num / s->tracks;
-offset = sector_num % s->tracks;
-
 if (idx >= s->bat_size) {
 return -EINVAL;
 }
-if (s->bat_bitmap[idx] != 0) {
-return bat2sect(s, idx) + offset;
-}
 
-pos = bdrv_getlength(bs->file) >> BDRV_SECTOR_BITS;
-if (s->data_end + s->tracks > pos) {
+to_allocate = (sector_num + *pnum + s->tracks - 1) / s->tracks - idx;
+space = to_allocate * s->tracks;
+if (s->data_end + space > bdrv_getlength(bs->file) >> BDRV_SECTOR_BITS) {
 int ret;
+space += s->prealloc_size;
 if (s->prealloc_mode == PRL_PREALLOC_MODE_FALLOCATE) {
-ret = bdrv_write_zeroes(bs->file, s->data_end,
-s->prealloc_size, 0);
+ret = bdrv_write_zeroes(bs->file, s->data_end, space, 0);
 } else {
 ret = bdrv_truncate(bs->file,
-(s->data_end + s->prealloc_size) << BDRV_SECTOR_BITS);
+(s->data_end + space) << BDRV_SECTOR_BITS);
 }
 if (ret < 0) {
 return ret;
 }
 }
-pos = s->data_end;
-s->data_end += s->tracks;
 
-s->bat_bitmap[idx] = cpu_to_le32(pos / s->off_multiplier);
+for (i = 0; i < to_allocate; i++) {
+s->bat_bitmap[idx + i] = cpu_to_le32(s->data_end / s->off_multiplier);
+s->data_end += s->tracks;
+bitmap_set(s->bat_dirty_bmap,
+   bat_entry_off(idx) / s->bat_dirty_block, 1);
+}
 
-bitmap_set(s->bat_dirty_bmap, bat_entry_off(idx) / s->bat_dirty_block, 1);
-return bat2sect(s, idx) + offset;
+return bat2sect(s, idx) + sector_num % s->tracks;
 }
 
 
@@ -287,14 +291,13 @@ static coroutine_fn int 
parallels_co_writev(BlockDriverState *bs,
 int n, nbytes;
 
 qemu_co_mutex_lock(&s->lock);
-position = allocate_cluster(bs, sector_num);
+position = allocate_clusters(bs, sector_num, nb_sectors, &n);
 qemu_co_mutex_unlock(&s->lock);
 if (position < 0) {
 ret = (int)position;
 break;
 }
 
-n = cluster_remainder(s, sector_num, nb_sectors);
 nbytes = n << BDRV_SECTOR_BITS;
 
 qemu_iovec_reset(&hd_qiov);
-- 
2.1.0




[Qemu-devel] [PULL 30/38] configure: silence glib unknown attribute __alloc_size__

2015-05-22 Thread Stefan Hajnoczi
From: John Snow 

The glib headers use GCC attributes.  Unfortunately the __GNUC__ and
__GNUC_MINOR__ version macros are also defined by clang, but clang
doesn't support the same attributes as GCC.

clang 3.5.0 does not support the __alloc_size__ attribute:

  
https://github.com/llvm-mirror/clang/commit/c047507a9a79e89fc8339e074fa72822a7e7ea73

The following warning is produced:

  gstrfuncs.h:257:44: warning: unknown attribute '__alloc_size__' ignored 
[-Wunknown-attributes]
G_GNUC_MALLOC G_GNUC_ALLOC_SIZE(2);
  gmacros.h:67:45: note: expanded from macro 'G_GNUC_ALLOC_SIZE'
#define G_GNUC_ALLOC_SIZE(x) __attribute__((__alloc_size__(x)))

This patch checks whether glib headers cause warnings and disables
-Wunknown-attributes if it is able to.

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: John Snow 
Reviewed-by: Stefan Hajnoczi 
Message-id: 1427324259-1481-4-git-send-email-js...@redhat.com
Signed-off-by: Stefan Hajnoczi 
---
 configure | 12 
 1 file changed, 12 insertions(+)

diff --git a/configure b/configure
index f744266..24d7ecc 100755
--- a/configure
+++ b/configure
@@ -2807,6 +2807,18 @@ if ! $pkg_config --atleast-version=2.38 glib-2.0; then
 glib_subprocess=no
 fi
 
+# Silence clang 3.5.0 warnings about glib attribute __alloc_size__ usage
+cat > $TMPC << EOF
+#include 
+int main(void) { return 0; }
+EOF
+if ! compile_prog "$glib_cflags -Werror" "$glib_libs" ; then
+if cc_has_warning_flag "-Wno-unknown-attributes"; then
+glib_cflags="-Wno-unknown-attributes $glib_cflags"
+CFLAGS="-Wno-unknown-attributes $CFLAGS"
+fi
+fi
+
 ##
 # SHA command probe for modules
 if test "$modules" = yes; then
-- 
2.1.0




[Qemu-devel] [PULL 33/38] block: minimal bounce buffer alignment

2015-05-22 Thread Stefan Hajnoczi
From: "Denis V. Lunev" 

The patch introduces new concept: minimal memory alignment for bounce
buffers. Original so called "optimal" value is actually minimal required
value for aligment. It should be used for validation that the IOVec
is properly aligned and bounce buffer is not required.

Though, from the performance point of view, it would be better if
bounce buffer or IOVec allocated by QEMU will be aligned stricter.

The patch does not change any alignment value yet.

Signed-off-by: Denis V. Lunev 
Reviewed-by: Kevin Wolf 
Message-id: 1431441056-26198-2-git-send-email-...@openvz.org
CC: Paolo Bonzini 
Reviewed-by: Kevin Wolf 
CC: Stefan Hajnoczi 
Signed-off-by: Stefan Hajnoczi 
---
 block.c   | 11 +++
 block/io.c|  7 ++-
 block/raw-posix.c |  1 +
 include/block/block.h |  2 ++
 include/block/block_int.h |  3 +++
 5 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/block.c b/block.c
index 7904098..e293907 100644
--- a/block.c
+++ b/block.c
@@ -113,6 +113,16 @@ size_t bdrv_opt_mem_align(BlockDriverState *bs)
 return bs->bl.opt_mem_alignment;
 }
 
+size_t bdrv_min_mem_align(BlockDriverState *bs)
+{
+if (!bs || !bs->drv) {
+/* 4k should be on the safe side */
+return 4096;
+}
+
+return bs->bl.min_mem_alignment;
+}
+
 /* check if the path starts with ":" */
 int path_has_protocol(const char *path)
 {
@@ -890,6 +900,7 @@ static int bdrv_open_common(BlockDriverState *bs, 
BlockDriverState *file,
 }
 
 assert(bdrv_opt_mem_align(bs) != 0);
+assert(bdrv_min_mem_align(bs) != 0);
 assert((bs->request_alignment != 0) || bs->sg);
 return 0;
 
diff --git a/block/io.c b/block/io.c
index a05ad67..e6c3639 100644
--- a/block/io.c
+++ b/block/io.c
@@ -201,8 +201,10 @@ void bdrv_refresh_limits(BlockDriverState *bs, Error 
**errp)
 }
 bs->bl.opt_transfer_length = bs->file->bl.opt_transfer_length;
 bs->bl.max_transfer_length = bs->file->bl.max_transfer_length;
+bs->bl.min_mem_alignment = bs->file->bl.min_mem_alignment;
 bs->bl.opt_mem_alignment = bs->file->bl.opt_mem_alignment;
 } else {
+bs->bl.min_mem_alignment = 512;
 bs->bl.opt_mem_alignment = 512;
 }
 
@@ -221,6 +223,9 @@ void bdrv_refresh_limits(BlockDriverState *bs, Error **errp)
 bs->bl.opt_mem_alignment =
 MAX(bs->bl.opt_mem_alignment,
 bs->backing_hd->bl.opt_mem_alignment);
+bs->bl.min_mem_alignment =
+MAX(bs->bl.min_mem_alignment,
+bs->backing_hd->bl.min_mem_alignment);
 }
 
 /* Then let the driver override it */
@@ -2489,7 +2494,7 @@ void *qemu_try_blockalign0(BlockDriverState *bs, size_t 
size)
 bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov)
 {
 int i;
-size_t alignment = bdrv_opt_mem_align(bs);
+size_t alignment = bdrv_min_mem_align(bs);
 
 for (i = 0; i < qiov->niov; i++) {
 if ((uintptr_t) qiov->iov[i].iov_base % alignment) {
diff --git a/block/raw-posix.c b/block/raw-posix.c
index 24d8582..7083924 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -725,6 +725,7 @@ static void raw_refresh_limits(BlockDriverState *bs, Error 
**errp)
 BDRVRawState *s = bs->opaque;
 
 raw_probe_alignment(bs, s->fd, errp);
+bs->bl.min_mem_alignment = s->buf_align;
 bs->bl.opt_mem_alignment = s->buf_align;
 }
 
diff --git a/include/block/block.h b/include/block/block.h
index 7d1a717..c1c963e 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -440,6 +440,8 @@ 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_min_mem_align(BlockDriverState *bs);
+/* Returns optimal alignment in bytes for bounce buffer */
 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);
diff --git a/include/block/block_int.h b/include/block/block_int.h
index db29b74..f004378 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -313,6 +313,9 @@ typedef struct BlockLimits {
 int max_transfer_length;
 
 /* memory alignment so that no bounce buffer is needed */
+size_t min_mem_alignment;
+
+/* memory alignment for bounce buffer */
 size_t opt_mem_alignment;
 } BlockLimits;
 
-- 
2.1.0




[Qemu-devel] [PULL 35/38] Revert "block: Fix unaligned zero write"

2015-05-22 Thread Stefan Hajnoczi
From: Fam Zheng 

This reverts commit fc3959e4669a1c2149b91ccb05101cfc7ae1fc05.

The core write code already handles the case, so remove this
duplication.

Because commit 61007b316 moved the touched code from block.c to
block/io.c, the change is manually reverted.

Signed-off-by: Fam Zheng 
Reviewed-by: Stefan Hajnoczi 
Reviewed-by: Kevin Wolf 
Message-id: 1431522721-3266-2-git-send-email-f...@redhat.com
Signed-off-by: Stefan Hajnoczi 
---
 block/io.c | 45 ++---
 1 file changed, 6 insertions(+), 39 deletions(-)

diff --git a/block/io.c b/block/io.c
index b3ea95c..ad877b0 100644
--- a/block/io.c
+++ b/block/io.c
@@ -934,19 +934,6 @@ out:
 return ret;
 }
 
-static inline uint64_t bdrv_get_align(BlockDriverState *bs)
-{
-/* TODO Lift BDRV_SECTOR_SIZE restriction in BlockDriver interface */
-return MAX(BDRV_SECTOR_SIZE, bs->request_alignment);
-}
-
-static inline bool bdrv_req_is_aligned(BlockDriverState *bs,
-   int64_t offset, size_t bytes)
-{
-int64_t align = bdrv_get_align(bs);
-return !(offset & (align - 1) || (bytes & (align - 1)));
-}
-
 /*
  * Handle a read request in coroutine context
  */
@@ -957,7 +944,8 @@ static int coroutine_fn bdrv_co_do_preadv(BlockDriverState 
*bs,
 BlockDriver *drv = bs->drv;
 BdrvTrackedRequest req;
 
-uint64_t align = bdrv_get_align(bs);
+/* TODO Lift BDRV_SECTOR_SIZE restriction in BlockDriver interface */
+uint64_t align = MAX(BDRV_SECTOR_SIZE, bs->request_alignment);
 uint8_t *head_buf = NULL;
 uint8_t *tail_buf = NULL;
 QEMUIOVector local_qiov;
@@ -1199,7 +1187,8 @@ static int coroutine_fn 
bdrv_co_do_pwritev(BlockDriverState *bs,
 BdrvRequestFlags flags)
 {
 BdrvTrackedRequest req;
-uint64_t align = bdrv_get_align(bs);
+/* TODO Lift BDRV_SECTOR_SIZE restriction in BlockDriver interface */
+uint64_t align = MAX(BDRV_SECTOR_SIZE, bs->request_alignment);
 uint8_t *head_buf = NULL;
 uint8_t *tail_buf = NULL;
 QEMUIOVector local_qiov;
@@ -1298,10 +1287,6 @@ static int coroutine_fn 
bdrv_co_do_pwritev(BlockDriverState *bs,
 bytes = ROUND_UP(bytes, align);
 }
 
-if (use_local_qiov) {
-/* Local buffer may have non-zero data. */
-flags &= ~BDRV_REQ_ZERO_WRITE;
-}
 ret = bdrv_aligned_pwritev(bs, &req, offset, bytes,
use_local_qiov ? &local_qiov : qiov,
flags);
@@ -1342,32 +1327,14 @@ int coroutine_fn bdrv_co_write_zeroes(BlockDriverState 
*bs,
   int64_t sector_num, int nb_sectors,
   BdrvRequestFlags flags)
 {
-int ret;
-
 trace_bdrv_co_write_zeroes(bs, sector_num, nb_sectors, flags);
 
 if (!(bs->open_flags & BDRV_O_UNMAP)) {
 flags &= ~BDRV_REQ_MAY_UNMAP;
 }
-if (bdrv_req_is_aligned(bs, sector_num << BDRV_SECTOR_BITS,
-nb_sectors << BDRV_SECTOR_BITS)) {
-ret = bdrv_co_do_writev(bs, sector_num, nb_sectors, NULL,
-BDRV_REQ_ZERO_WRITE | flags);
-} else {
-uint8_t *buf;
-QEMUIOVector local_qiov;
-size_t bytes = nb_sectors << BDRV_SECTOR_BITS;
 
-buf = qemu_memalign(bdrv_opt_mem_align(bs), bytes);
-memset(buf, 0, bytes);
-qemu_iovec_init(&local_qiov, 1);
-qemu_iovec_add(&local_qiov, buf, bytes);
-
-ret = bdrv_co_do_writev(bs, sector_num, nb_sectors, &local_qiov,
-BDRV_REQ_ZERO_WRITE | flags);
-qemu_vfree(buf);
-}
-return ret;
+return bdrv_co_do_writev(bs, sector_num, nb_sectors, NULL,
+ BDRV_REQ_ZERO_WRITE | flags);
 }
 
 int bdrv_flush_all(void)
-- 
2.1.0




Re: [Qemu-devel] [PATCH 04/10] crypto: introduce generic cipher API & built-in implementation

2015-05-22 Thread Daniel P. Berrange
On Thu, May 21, 2015 at 12:52:43PM -0700, Richard Henderson wrote:
> On 05/21/2015 03:56 AM, Daniel P. Berrange wrote:
> > +QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
> > +  QCryptoCipherMode mode,
> > +  const uint8_t *key, size_t nkey,
> > +  Error **errp)
> > +{
> > +QCryptoCipher *cipher;
> > +
> > +cipher = g_new0(QCryptoCipher, 1);
> > +cipher->alg = alg;
> > +cipher->mode = mode;
> > +
> > +switch (cipher->alg) {
> > +case QCRYPTO_CIPHER_ALG_DES_RFB:
> > +if (qcrypto_cipher_init_des_rfb(cipher, key, nkey, errp) < 0) {
> > +goto error;
> > +}
> > +break;
> > +case QCRYPTO_CIPHER_ALG_AES:
> > +if (qcrypto_cipher_init_aes(cipher, key, nkey, errp) < 0) {
> > +goto error;
> > +}
> > +break;
> > +default:
> > +error_setg(errp,
> > +   _("Unsupported cipher algorithm %d"), cipher->alg);
> > +goto error;
> > +}
> > +
> > +return cipher;
> > +
> > + error:
> > +g_free(cipher);
> > +return NULL;
> > +}
> 
> Is it really that helpful to have all of these switches, as opposed to having
> one function per cipher and calling it directly?  Similarly for the hashing.

These switches are just an artifact of this default built-in implementation
where we're jumping off to one or our two built-in crypto algorithsm. The
gcrypt backend of these APIs has no such switch, since there is just a
similar looking gcrypt API we directly pass through to.

Similarly, if we add a backend that delegates to the Linux kernel crypto
API, then we'd just be doing a more or less straight passthrough with none
of these switches.

> 
> The uses I pulled out of the later patches are like
> 
> +if (qcrypto_hash_bytesv(QCRYPTO_HASH_ALG_SHA256,
> +qiov->iov, qiov->niov,
> +&data, &len,
> +NULL) < 0) {
> +return -EINVAL;
> 
> +if (qcrypto_hash_base64(QCRYPTO_HASH_ALG_SHA1,
> +combined_key,
> +WS_CLIENT_KEY_LEN + WS_GUID_LEN,
> +&accept,
> +&err) < 0) {
> 
> +cipher = qcrypto_cipher_new(
> +QCRYPTO_CIPHER_ALG_DES_RFB,
> +QCRYPTO_CIPHER_MODE_ECB,
> +key, G_N_ELEMENTS(key),
> +&err);
> 
> +s->cipher = qcrypto_cipher_new(
> +QCRYPTO_CIPHER_ALG_AES,
> +QCRYPTO_CIPHER_MODE_CBC,
> +keybuf, G_N_ELEMENTS(keybuf),
> +&err);
> 
> This one could have explicitly specified AES128, but you hid that behind
> G_N_ELEMENTS.  Which seems like obfuscation to me, but...

In designing the APIs I was looking forward to uses beyond those shown
in this current patch series. In particular with full disk encryption
there will be a wide selection of algorithms that can be used with the
implementation, so the caller of the APIs will not be passing in a
fixed algorithm constant, but instead have it vary according to the
data format. So on balance I think this current design is more future
proof than what you suggest

Regards,
Daniel
-- 
|: http://berrange.com  -o-http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org  -o- http://virt-manager.org :|
|: http://autobuild.org   -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org   -o-   http://live.gnome.org/gtk-vnc :|



[Qemu-devel] [PULL 32/38] block: return EPERM on writes or discards to read-only devices

2015-05-22 Thread Stefan Hajnoczi
From: Paolo Bonzini 

This is the behavior in the operating system, for example Linux's
blkdev_write_iter has the following:

if (bdev_read_only(I_BDEV(bd_inode)))
return -EPERM;

This does not apply to opening a device for read/write, when the
device only supports read-only operation.  In this case any of
EACCES, EPERM or EROFS is acceptable depending on why writing is
not possible.

Signed-off-by: Paolo Bonzini 
Message-id: 1431013548-22492-1-git-send-email-pbonz...@redhat.com
Signed-off-by: Stefan Hajnoczi 
---
 block/io.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/block/io.c b/block/io.c
index 1ce62c4..a05ad67 100644
--- a/block/io.c
+++ b/block/io.c
@@ -1205,7 +1205,7 @@ static int coroutine_fn 
bdrv_co_do_pwritev(BlockDriverState *bs,
 return -ENOMEDIUM;
 }
 if (bs->read_only) {
-return -EACCES;
+return -EPERM;
 }
 
 ret = bdrv_check_byte_request(bs, offset, bytes);
@@ -2340,7 +2340,7 @@ int coroutine_fn bdrv_co_discard(BlockDriverState *bs, 
int64_t sector_num,
 if (ret < 0) {
 return ret;
 } else if (bs->read_only) {
-return -EROFS;
+return -EPERM;
 }
 
 bdrv_reset_dirty(bs, sector_num, nb_sectors);
-- 
2.1.0




[Qemu-devel] [PULL 38/38] block: get_block_status: use "else" when testing the opposite condition

2015-05-22 Thread Stefan Hajnoczi
From: Paolo Bonzini 

A bit of Boolean algebra (and common sense) tells us that the
second "if" here is looking for blocks that are not allocated.
This is the opposite of the "if" that sets BDRV_BLOCK_ALLOCATED,
and thus it can use an "else".

Signed-off-by: Paolo Bonzini 
Reviewed-by: Eric Blake 
Reviewed-by: Fam Zheng 
Message-id: 1431599702-10431-1-git-send-email-pbonz...@redhat.com
Signed-off-by: Stefan Hajnoczi 
---
 block/io.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/block/io.c b/block/io.c
index 284784e..e394d92 100644
--- a/block/io.c
+++ b/block/io.c
@@ -1521,9 +1521,7 @@ static int64_t coroutine_fn 
bdrv_co_get_block_status(BlockDriverState *bs,
 
 if (ret & (BDRV_BLOCK_DATA | BDRV_BLOCK_ZERO)) {
 ret |= BDRV_BLOCK_ALLOCATED;
-}
-
-if (!(ret & BDRV_BLOCK_DATA) && !(ret & BDRV_BLOCK_ZERO)) {
+} else {
 if (bdrv_unallocated_blocks_are_zero(bs)) {
 ret |= BDRV_BLOCK_ZERO;
 } else if (bs->backing_hd) {
-- 
2.1.0




[Qemu-devel] [PULL 37/38] qemu-iotests: Test unaligned sub-block zero write

2015-05-22 Thread Stefan Hajnoczi
From: Fam Zheng 

Test zero write in byte range 512~1024 for 4k alignment.

Signed-off-by: Fam Zheng 
Reviewed-by: Stefan Hajnoczi 
Reviewed-by: Kevin Wolf 
Message-id: 1431522721-3266-4-git-send-email-f...@redhat.com
Signed-off-by: Stefan Hajnoczi 
---
 tests/qemu-iotests/033 | 13 +
 tests/qemu-iotests/033.out | 30 ++
 2 files changed, 43 insertions(+)

diff --git a/tests/qemu-iotests/033 b/tests/qemu-iotests/033
index 4008f10..a61d8ce 100755
--- a/tests/qemu-iotests/033
+++ b/tests/qemu-iotests/033
@@ -78,6 +78,19 @@ for align in 512 4k; do
echo
echo "== verifying patterns (2) =="
do_test $align "read -P 0x0 0x400 0x2" "$TEST_IMG" | _filter_qemu_io
+
+   echo
+   echo "== rewriting unaligned zeroes =="
+   do_test $align "write -P 0xb 0x0 0x1000" "$TEST_IMG" | _filter_qemu_io
+   do_test $align "write -z 0x200 0x200" "$TEST_IMG" | _filter_qemu_io
+
+   echo
+   echo "== verifying patterns (3) =="
+   do_test $align "read -P 0xb 0x0 0x200" "$TEST_IMG" | _filter_qemu_io
+   do_test $align "read -P 0x0 0x200 0x200" "$TEST_IMG" | _filter_qemu_io
+   do_test $align "read -P 0xb 0x400 0xc00" "$TEST_IMG" | _filter_qemu_io
+
+   echo
 done
 
 # success, all done
diff --git a/tests/qemu-iotests/033.out b/tests/qemu-iotests/033.out
index 305949f..c3d18aa 100644
--- a/tests/qemu-iotests/033.out
+++ b/tests/qemu-iotests/033.out
@@ -27,6 +27,21 @@ wrote 65536/65536 bytes at offset 65536
 read 131072/131072 bytes at offset 1024
 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 
+== rewriting unaligned zeroes ==
+wrote 4096/4096 bytes at offset 0
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 512/512 bytes at offset 512
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== verifying patterns (3) ==
+read 512/512 bytes at offset 0
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 512
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 3072/3072 bytes at offset 1024
+3 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+
 == preparing image ==
 wrote 1024/1024 bytes at offset 512
 1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -52,4 +67,19 @@ wrote 65536/65536 bytes at offset 65536
 == verifying patterns (2) ==
 read 131072/131072 bytes at offset 1024
 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== rewriting unaligned zeroes ==
+wrote 4096/4096 bytes at offset 0
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 512/512 bytes at offset 512
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== verifying patterns (3) ==
+read 512/512 bytes at offset 0
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 512
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 3072/3072 bytes at offset 1024
+3 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
 *** done
-- 
2.1.0




Re: [Qemu-devel] [PULL v2 00/18] target-alpha fpu improvements

2015-05-22 Thread Peter Maydell
On 21 May 2015 at 18:39, Richard Henderson  wrote:
> Having fixed the UL vs ULL fiasco in patch 17.
>
>
> r~
>
>
> The following changes since commit 385057cbec9b4a0eb6150330c572e875ed714965:
>
>   Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2015-05-15' 
> into staging (2015-05-15 17:51:20 +0100)
>
> are available in the git repository at:
>
>   git://github.com/rth7680/qemu.git tags/pull-axp-20150521
>
> for you to fetch changes up to 32ad48abd74a997220b841e4e913edeb267aa362:
>
>   target-alpha: Add vector implementation for CMPBGE (2015-05-21 10:34:18 
> -0700)

Applied, thanks.

-- PMM



Re: [Qemu-devel] ABNT2 keys again

2015-05-22 Thread Gerd Hoffmann
On Mi, 2015-05-20 at 14:44 +0300, Michael Tokarev wrote:
> A (friendly) ping? :)
> 
> > The solution appears to be trivial (see also some background
> > at http://blog.nielshorn.net/2011/03/qemu-and-brazilian-keyboards/ ),
> > but the problem is definitely still here.
> > 
> > Maybe it's a time to address this finally? :)
> > 
> > I don't pretend to understand any significant bit of input
> > handling, so am asking people who are more knowlegeable in
> > this area to take a look ;)

Anyone having such a keyboard and willing to run some tests?

thanks,
  Gerd





[Qemu-devel] [PATCH 1/3] target-tricore: fix OPC2_32_RR_DVINIT_HU having write before use on the result

2015-05-22 Thread Bastian Koppelmann
If the argument r1 was the same as the extended result register r3+1, we would
overwrite r1 and then use it.

Signed-off-by: Bastian Koppelmann 
---
 target-tricore/translate.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 663b2a0..4b935fd 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -6321,8 +6321,8 @@ static void decode_rr_divide(CPUTriCoreState *env, 
DisasContext *ctx)
 /* sv */
 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
 /* write result */
-tcg_gen_mov_tl(cpu_gpr_d[r3+1], temp3);
 tcg_gen_shli_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], 16);
+tcg_gen_mov_tl(cpu_gpr_d[r3+1], temp3);
 tcg_temp_free(temp);
 tcg_temp_free(temp2);
 tcg_temp_free(temp3);
-- 
2.4.1




[Qemu-devel] [PATCH 3/3] target-tricore: fix BOL_ST_H_LONGOFF using ld

2015-05-22 Thread Bastian Koppelmann
Signed-off-by: Bastian Koppelmann 
---
 target-tricore/translate.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 2d886e6..bf11ed4 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -5150,7 +5150,7 @@ static void decode_bol_opc(CPUTriCoreState *env, 
DisasContext *ctx, int32_t op1)
 break;
 case OPC1_32_BOL_ST_H_LONGOFF:
 if (tricore_feature(env, TRICORE_FEATURE_16)) {
-gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LESW);
+gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LESW);
 } else {
 /* raise illegal opcode trap */
 }
-- 
2.4.1




[Qemu-devel] [PATCH 2/3] target-tricore: fix msub32_q producing the wrong overflow bit

2015-05-22 Thread Bastian Koppelmann
The inversion of the overflow bit as a special case, which was needed for the
madd32_q instructions, does not apply for msub32_q instructions. So remove it.

Signed-off-by: Bastian Koppelmann 
---
 target-tricore/translate.c | 11 ---
 1 file changed, 11 deletions(-)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 4b935fd..2d886e6 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -1938,17 +1938,6 @@ gen_msub32_q(TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3, 
uint32_t n,
 tcg_gen_or_i64(t1, t1, t2);
 tcg_gen_trunc_i64_i32(cpu_PSW_V, t1);
 tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
-/* We produce an overflow on the host if the mul before was
-   (0x8000 * 0x8000) << 1). If this is the
-   case, we negate the ovf. */
-if (n == 1) {
-tcg_gen_setcondi_tl(TCG_COND_EQ, temp, arg2, 0x8000);
-tcg_gen_setcond_tl(TCG_COND_EQ, temp2, arg2, arg3);
-tcg_gen_and_tl(temp, temp, temp2);
-tcg_gen_shli_tl(temp, temp, 31);
-/* negate v bit, if special condition */
-tcg_gen_xor_tl(cpu_PSW_V, cpu_PSW_V, temp);
-}
 /* Calc SV bit */
 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
 /* Calc AV/SAV bits */
-- 
2.4.1




[Qemu-devel] [PATCH 0/3] TriCore bugfixes

2015-05-22 Thread Bastian Koppelmann
Hi,

while testing the new v1.6.1 instructions I found three bugs in the old
instructions.

Cheers,
Bastian 

Bastian Koppelmann (3):
  target-tricore: fix OPC2_32_RR_DVINIT_HU having write before use on
the result
  target-tricore: fix msub32_q producing the wrong overflow bit
  target-tricore: fix BOL_ST_H_LONGOFF using ld

 target-tricore/translate.c | 15 ++-
 1 file changed, 2 insertions(+), 13 deletions(-)

-- 
2.4.1




Re: [Qemu-devel] [PULL v2 00/18] target-alpha fpu improvements

2015-05-22 Thread Peter Maydell
On 22 May 2015 at 11:00, Peter Maydell  wrote:
> On 21 May 2015 at 18:39, Richard Henderson  wrote:
>> for you to fetch changes up to 32ad48abd74a997220b841e4e913edeb267aa362:
>>
>>   target-alpha: Add vector implementation for CMPBGE (2015-05-21 10:34:18 
>> -0700)
>
> Applied, thanks.

Except I failed to notice a test failure from one of my builds
before pushing:

target-alpha/int_helper.c: In function 'helper_cmpbge':
target-alpha/int_helper.c:77: error: invalid operands to binary >=
target-alpha/int_helper.c:79: error: subscripted value is neither
array nor pointer

That's in the Centos5 build, which is
gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-55)

Any suggestions?

I do note that this build target is basically obsolete anyway, because
we're about to move to requiring glib 2.22, at which point Centos5 is
officially Too Old. So maybe we just say "yeah, you need a newer gcc" ?

-- PMM



[Qemu-devel] [PATCH] Use Aff1 with mpidr

2015-05-22 Thread Pavel Fedin
 This is an improved and KVM-aware alternative to
https://lists.gnu.org/archive/html/qemu-devel/2015-05/msg00942.html. Changes 
are:
1. MPIDR value (minus feature bits) is now directly stored in CPU instance.
2. Default assignment is based on original rule (8 CPUs per cluster).
3. If KVM is used, MPIDR values are overridden with those from KVM. This is 
necessary for
proper KVM PSCI functioning.
4. Some cosmetic changes which would make further expansion of this code easier.
5. Added some debugging macros because CPU ID assignment is tricky part, and if 
there are
some problems, i think there should be a quick way to make sure they are 
correct.
 This does not have an RFC mark because it is perfectly okay to be committed 
alone, it
does not break anything. Commit message follows. Cc'ed to all interested 
parties because i
really hope to get things going somewhere this time.

In order to support up to 128 cores with GIC-500 (GICv3 implementation)
affinity1 must be used. GIC-500 support up to 32 clusters with up to
8 cores in a cluster. So for example, if one wishes to have 16 cores,
the options are: 2 clusters of 8 cores each, 4 clusters with 4 cores each
Currently only the first option is supported for TCG. However, KVM expects
to have the same clusters layout as host machine has. Therefore, if we use
64-bit KVM we override CPU IDs with those provided by the KVM. For 32-bit
systems it is OK to leave the default because so far we do not have more
than 8 CPUs on any of them.
This implementation has a potential to be extended with some methods which
would define cluster layout instead of hardcoded CPUS_PER_CLUSTER
definition. This would allow to emulate real machines with different
layouts. However, in case of KVM we would still have to inherit IDs from
the host.

Signed-off-by: Shlomo Pongratz 
Signed-off-by: Pavel Fedin 
---
 hw/arm/virt.c|  6 +-
 target-arm/cpu-qom.h |  3 +++
 target-arm/cpu.c | 17 +
 target-arm/helper.c  |  9 +++--
 target-arm/kvm64.c   | 25 +
 target-arm/psci.c| 20 ++--
 6 files changed, 71 insertions(+), 9 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index a7f9a10..a1186c5 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -317,7 +317,11 @@ static void fdt_add_cpu_nodes(const VirtBoardInfo *vbi)
 "enable-method", "psci");
 }
 
-qemu_fdt_setprop_cell(vbi->fdt, nodename, "reg", cpu);
+/*
+ * If cpus node's #address-cells property is set to 1
+ * The reg cell bits [23:0] must be set to bits [23:0] of MPIDR_EL1.
+ */
+qemu_fdt_setprop_cell(vbi->fdt, nodename, "reg", armcpu->mpidr);
 g_free(nodename);
 }
 }
diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
index ed5a644..a382a09 100644
--- a/target-arm/cpu-qom.h
+++ b/target-arm/cpu-qom.h
@@ -159,6 +159,7 @@ typedef struct ARMCPU {
 uint64_t id_aa64mmfr1;
 uint32_t dbgdidr;
 uint32_t clidr;
+uint64_t mpidr; /* Without feature bits */
 /* The elements of this array are the CCSIDR values for each cache,
  * in the order L1DCache, L1ICache, L2DCache, L2ICache, etc.
  */
@@ -171,6 +172,8 @@ typedef struct ARMCPU {
 uint64_t rvbar;
 } ARMCPU;
 
+#define CPUS_PER_CLUSTER 8
+
 #define TYPE_AARCH64_CPU "aarch64-cpu"
 #define AARCH64_CPU_CLASS(klass) \
 OBJECT_CLASS_CHECK(AArch64CPUClass, (klass), TYPE_AARCH64_CPU)
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 3ca3fa8..7dc2595 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -31,6 +31,12 @@
 #include "sysemu/kvm.h"
 #include "kvm_arm.h"
 
+#ifdef DEBUG
+# define DPRINTF(format, ...) printf("armcpu: " format , ## __VA_ARGS__)
+#else
+# define DPRINTF(format, ...) do { } while (0)
+#endif
+
 static void arm_cpu_set_pc(CPUState *cs, vaddr value)
 {
 ARMCPU *cpu = ARM_CPU(cs);
@@ -367,12 +373,23 @@ static void arm_cpu_initfn(Object *obj)
 CPUState *cs = CPU(obj);
 ARMCPU *cpu = ARM_CPU(obj);
 static bool inited;
+uint32_t Aff1, Aff0;
 
 cs->env_ptr = &cpu->env;
 cpu_exec_init(&cpu->env);
 cpu->cp_regs = g_hash_table_new_full(g_int_hash, g_int_equal,
  g_free, g_free);
 
+/*
+ * We don't support setting cluster ID ([16..23]) (known as Aff2
+ * in later ARM ARM versions), or any of the higher affinity level fields,
+ * so these bits always RAZ.
+ */
+Aff1 = cs->cpu_index / CPUS_PER_CLUSTER;
+Aff0 = cs->cpu_index % CPUS_PER_CLUSTER;
+cpu->mpidr = (Aff1 << 8) | Aff0;
+DPRINTF("Init(%p): index %d mpidr 0x%jX\n", cpu, cs->cpu_index, 
cpu->mpidr);
+
 #ifndef CONFIG_USER_ONLY
 /* Our inbound IRQ and FIQ lines */
 if (kvm_enabled()) {
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 5d0f011..9535290 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2036,12 +2036,9 @@ static const ARMCPRegInfo strongarm_cp_reginfo[] = {
 

[Qemu-devel] [PATCH RFC 1/4] Add virt-v3 machine that uses GIC-500

2015-05-22 Thread Pavel Fedin
This patch introduces kernel_irqchip_type member in Machine class. Currently it 
it used only by virt machine for its internal purposes, however in future it is 
to be passed to KVM in kvm_irqchip_create(). The variable is defined as int in 
order to be architecture agnostic, for potential future users.

Signed-off-by: Pavel Fedin 

---
 hw/arm/virt.c   | 148 +++-
 include/hw/boards.h |   1 +
 2 files changed, 123 insertions(+), 26 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index a1186c5..15724b2 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -66,6 +66,10 @@ enum {
 VIRT_CPUPERIPHS,
 VIRT_GIC_DIST,
 VIRT_GIC_CPU,
+VIRT_GIC_DIST_SPI = VIRT_GIC_CPU,
+VIRT_ITS_CONTROL,
+VIRT_ITS_TRANSLATION,
+VIRT_LPI,
 VIRT_UART,
 VIRT_MMIO,
 VIRT_RTC,
@@ -107,6 +111,8 @@ typedef struct {
 #define VIRT_MACHINE_CLASS(klass) \
 OBJECT_CLASS_CHECK(VirtMachineClass, klass, TYPE_VIRT_MACHINE)
 
+#define TYPE_VIRTV3_MACHINE   "virt-v3"
+
 /* Addresses and sizes of our components.
  * 0..128MB is space for a flash device so we can run bootrom code such as 
UEFI.
  * 128MB..256MB is used for miscellaneous device I/O.
@@ -121,25 +127,29 @@ typedef struct {
  */
 static const MemMapEntry a15memmap[] = {
 /* Space up to 0x800 is reserved for a boot ROM */
-[VIRT_FLASH] =  {  0, 0x0800 },
-[VIRT_CPUPERIPHS] = { 0x0800, 0x0002 },
+[VIRT_FLASH] =   {  0, 0x0800 },
+[VIRT_CPUPERIPHS] =  { 0x0800, 0x0002 },
 /* GIC distributor and CPU interfaces sit inside the CPU peripheral space 
*/
-[VIRT_GIC_DIST] =   { 0x0800, 0x0001 },
-[VIRT_GIC_CPU] ={ 0x0801, 0x0001 },
-[VIRT_UART] =   { 0x0900, 0x1000 },
-[VIRT_RTC] ={ 0x0901, 0x1000 },
-[VIRT_FW_CFG] = { 0x0902, 0x000a },
-[VIRT_MMIO] =   { 0x0a00, 0x0200 },
+[VIRT_GIC_DIST] ={ 0x0800, 0x0001 },
+[VIRT_GIC_CPU] = { 0x0801, 0x0001 },
+/* On v3 VIRT_GIC_DIST_SPI takes place of VIRT_GIC_CPU */
+[VIRT_ITS_CONTROL] = { 0x0802, 0x0001 },
+[VIRT_ITS_TRANSLATION] = { 0x0803, 0x0001 },
+[VIRT_LPI] = { 0x0804, 0x0080 },
+[VIRT_UART] ={ 0x0900, 0x1000 },
+[VIRT_RTC] = { 0x0901, 0x1000 },
+[VIRT_FW_CFG] =  { 0x0902, 0x000a },
+[VIRT_MMIO] ={ 0x0a00, 0x0200 },
 /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
 /*
  * PCIE verbose map:
  *
- * MMIO window  { 0x1000, 0x2eff },
- * PIO window   { 0x3eff, 0x0001 },
- * ECAM { 0x3f00, 0x0100 },
+ * MMIO window   { 0x1000, 0x2eff },
+ * PIO window{ 0x3eff, 0x0001 },
+ * ECAM  { 0x3f00, 0x0100 },
  */
-[VIRT_PCIE] =   { 0x1000, 0x3000 },
-[VIRT_MEM] ={ 0x4000, 30ULL * 1024 * 1024 * 1024 },
+[VIRT_PCIE] ={ 0x1000, 0x3000 },
+[VIRT_MEM] = { 0x4000, 30ULL * 1024 * 1024 * 1024 },
 };
 
 static const int a15irqmap[] = {
@@ -273,9 +283,11 @@ static void fdt_add_timer_nodes(const VirtBoardInfo *vbi)
  */
 ARMCPU *armcpu;
 uint32_t irqflags = GIC_FDT_IRQ_FLAGS_EDGE_LO_HI;
+/* Argument is 32 bit but 8 bits are reserved for flags */
+uint32_t max = (vbi->smp_cpus >= 24) ? 24 : vbi->smp_cpus;
 
 irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START,
- GIC_FDT_IRQ_PPI_CPU_WIDTH, (1 << vbi->smp_cpus) - 1);
+ GIC_FDT_IRQ_PPI_CPU_WIDTH, (1 << max) - 1);
 
 qemu_fdt_add_subnode(vbi->fdt, "/timer");
 
@@ -299,6 +311,18 @@ static void fdt_add_cpu_nodes(const VirtBoardInfo *vbi)
 {
 int cpu;
 
+/*
+ * From Documentation/devicetree/bindings/arm/cpus.txt
+ *  On ARM v8 64-bit systems value should be set to 2,
+ *  that corresponds to the MPIDR_EL1 register size.
+ *  If MPIDR_EL1[63:32] value is equal to 0 on all CPUs
+ *  in the system, #address-cells can be set to 1, since
+ *  MPIDR_EL1[63:32] bits are not used for CPUs
+ *  identification.
+ *
+ *  Now GIC500 doesn't support affinities 2 & 3 so currently
+ *  #address-cells can stay 1 until future GIC
+ */
 qemu_fdt_add_subnode(vbi->fdt, "/cpus");
 qemu_fdt_setprop_cell(vbi->fdt, "/cpus", "#address-cells", 0x1);
 qemu_fdt_setprop_cell(vbi->fdt, "/cpus", "#size-cells", 0x0);
@@ -326,7 +350,7 @@ static void fdt_add_cpu_nodes(const VirtBoardInfo *vbi)
 }
 }
 
-static uint32_t fdt_add_gic_node(const VirtBoardInfo *vbi)
+static uint32_t fdt_add_gic_node(const VirtBoardInfo *vbi, int type)
 {
 uint32_t gic_phandle;
 
@@ -334,35 +358,65 @@ static uint32_t fdt_add_gic_node(co

[Qemu-devel] [PATCH RFC 0/4] vGICv3 support

2015-05-22 Thread Pavel Fedin
 This is my alternative to Ashok's vGICv3 patch
(https://lists.gnu.org/archive/html/qemu-devel/2015-05/msg03021.html), which
i am currently working on. It addresses vGIC capability verification issue
(kvm_irqchip_create() / kvm_arch_irqchip_create()), as well as offers better
code structure (v3 code separated from v2).
 This patchset applies on top of this:
https://lists.gnu.org/archive/html/qemu-devel/2015-05/msg00943.html. Note that
GIC type selection still relies on machine name (virt-v3 vs virt), and not on
machine option. Since libvirt has recently introduced support for extra options,
i have absolutely nothing against Ashok's approach. I just did not change this
yet because it would affect my testing environment. The aim of this RFC is to
focus on vGICv3 implementation and related changes. And yes, i agree that v2 and
v3 now have some copypasted code, and this is TBD.

Pavel Fedin (4):
  Add virt-v3 machine that uses GIC-500
  Set kernel_irqchip_type for other ARM boards which use GIC
  First bits of vGICv3 support:
  Initial implementation of vGICv3.

 hw/arm/exynos4_boards.c |   1 +
 hw/arm/realview.c   |   1 +
 hw/arm/vexpress.c   |   1 +
 hw/arm/virt.c   | 148 -
 hw/intc/Makefile.objs   |   1 +
 hw/intc/arm_gicv3_kvm.c | 283 
 include/hw/boards.h |   1 +
 include/sysemu/kvm.h|   3 +-
 kvm-all.c   |   2 +-
 stubs/kvm.c |   2 +-
 target-arm/kvm.c|   8 +-
 11 files changed, 419 insertions(+), 32 deletions(-)
 create mode 100644 hw/intc/arm_gicv3_kvm.c

-- 
1.9.5.msysgit.0




[Qemu-devel] [PATCH RFC 2/4] Set kernel_irqchip_type for other ARM boards which use GIC

2015-05-22 Thread Pavel Fedin
Signed-off-by: Pavel Fedin 
---
 hw/arm/exynos4_boards.c | 1 +
 hw/arm/realview.c   | 1 +
 hw/arm/vexpress.c   | 1 +
 3 files changed, 3 insertions(+)

diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
index d644db1..d4136bc 100644
--- a/hw/arm/exynos4_boards.c
+++ b/hw/arm/exynos4_boards.c
@@ -104,6 +104,7 @@ static Exynos4210State 
*exynos4_boards_init_common(MachineState *machine,
 exynos4_machines[board_type].max_cpus);
 }
 
+machine->kernel_irqchip_type = KVM_DEV_TYPE_ARM_VGIC_V2;
 exynos4_board_binfo.ram_size = exynos4_board_ram_size[board_type];
 exynos4_board_binfo.board_id = exynos4_board_id[board_type];
 exynos4_board_binfo.smp_bootreg_addr =
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
index ef2788d..f670d9f 100644
--- a/hw/arm/realview.c
+++ b/hw/arm/realview.c
@@ -74,6 +74,7 @@ static void realview_init(MachineState *machine,
 ram_addr_t ram_size = machine->ram_size;
 hwaddr periphbase = 0;
 
+machine->kernel_irqchip_type = KVM_DEV_TYPE_ARM_VGIC_V2;
 switch (board_type) {
 case BOARD_EB:
 break;
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
index 8f1a5ea..b0a29f1 100644
--- a/hw/arm/vexpress.c
+++ b/hw/arm/vexpress.c
@@ -556,6 +556,7 @@ static void vexpress_common_init(MachineState *machine)
 const hwaddr *map = daughterboard->motherboard_map;
 int i;
 
+machine->kernel_irqchip_type = KVM_DEV_TYPE_ARM_VGIC_V2;
 daughterboard->init(vms, machine->ram_size, machine->cpu_model, pic);
 
 /*
-- 
1.9.5.msysgit.0




[Qemu-devel] [PATCH RFC 3/4] First bits of vGICv3 support:

2015-05-22 Thread Pavel Fedin
- Make use of kernel_irqchip_type in kvm_arch_irqchip_create()
- Instantiate "kvm-arm-gicv3" class (not implemented yet) for GICv3 with KVM 
acceleration

Signed-off-by: Pavel Fedin 
---
 hw/arm/virt.c| 6 ++
 include/sysemu/kvm.h | 3 ++-
 kvm-all.c| 2 +-
 stubs/kvm.c  | 2 +-
 target-arm/kvm.c | 8 ++--
 5 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 15724b2..1e42e59 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -400,11 +400,9 @@ static uint32_t create_gic(const VirtBoardInfo *vbi, 
qemu_irq *pic, int type)
 int i;
 
 if (type == KVM_DEV_TYPE_ARM_VGIC_V3) {
-gictype = "arm_gicv3";
-} else if (kvm_irqchip_in_kernel()) {
-gictype = "kvm-arm-gic";
+gictype = kvm_irqchip_in_kernel() ? "kvm-arm-gicv3" : "arm_gicv3";
 } else {
-gictype = "arm_gic";
+gictype = kvm_irqchip_in_kernel() ? "kvm-arm-gic" : "arm_gic";
 }
 
 gicdev = qdev_create(NULL, gictype);
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 4878959..5d90257 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -424,6 +424,7 @@ void kvm_init_irq_routing(KVMState *s);
 /**
  * kvm_arch_irqchip_create:
  * @KVMState: The KVMState pointer
+ * @type: irqchip type, architecture-specific
  *
  * Allow architectures to create an in-kernel irq chip themselves.
  *
@@ -431,7 +432,7 @@ void kvm_init_irq_routing(KVMState *s);
  *0: irq chip was not created
  *  > 0: irq chip was created
  */
-int kvm_arch_irqchip_create(KVMState *s);
+int kvm_arch_irqchip_create(KVMState *s, int type);
 
 /**
  * kvm_set_one_reg - set a register value in KVM via KVM_SET_ONE_REG ioctl
diff --git a/kvm-all.c b/kvm-all.c
index 17a3771..22e2621 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1393,7 +1393,7 @@ static int kvm_irqchip_create(MachineState *machine, 
KVMState *s)
 
 /* First probe and see if there's a arch-specific hook to create the
  * in-kernel irqchip for us */
-ret = kvm_arch_irqchip_create(s);
+ret = kvm_arch_irqchip_create(s, machine->kernel_irqchip_type);
 if (ret < 0) {
 return ret;
 } else if (ret == 0) {
diff --git a/stubs/kvm.c b/stubs/kvm.c
index e7c60b6..a8505ff 100644
--- a/stubs/kvm.c
+++ b/stubs/kvm.c
@@ -1,7 +1,7 @@
 #include "qemu-common.h"
 #include "sysemu/kvm.h"
 
-int kvm_arch_irqchip_create(KVMState *s)
+int kvm_arch_irqchip_create(KVMState *s, int type)
 {
 return 0;
 }
diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index 16abbf1..65794cf 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -579,7 +579,7 @@ void kvm_arch_init_irq_routing(KVMState *s)
 {
 }
 
-int kvm_arch_irqchip_create(KVMState *s)
+int kvm_arch_irqchip_create(KVMState *s, int type)
 {
 int ret;
 
@@ -587,11 +587,15 @@ int kvm_arch_irqchip_create(KVMState *s)
  * let the device do this when it initializes itself, otherwise we
  * fall back to the old API */
 
-ret = kvm_create_device(s, KVM_DEV_TYPE_ARM_VGIC_V2, true);
+ret = kvm_create_device(s, type, true);
 if (ret == 0) {
 return 1;
 }
 
+/* Fallback will create VGIC v2 */
+if (type != KVM_DEV_TYPE_ARM_VGIC_V2) {
+return ret;
+}
 return 0;
 }
 
-- 
1.9.5.msysgit.0




[Qemu-devel] [PATCH RFC 4/4] Initial implementation of vGICv3.

2015-05-22 Thread Pavel Fedin
Get/put routines are missing. Live migration is not possible.

Signed-off-by: Pavel Fedin 
---
 hw/intc/Makefile.objs   |   1 +
 hw/intc/arm_gicv3_kvm.c | 283 
 2 files changed, 284 insertions(+)
 create mode 100644 hw/intc/arm_gicv3_kvm.c

diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
index 41fe9ec..776f517 100644
--- a/hw/intc/Makefile.objs
+++ b/hw/intc/Makefile.objs
@@ -17,6 +17,7 @@ common-obj-$(CONFIG_OPENPIC) += openpic.o
 
 obj-$(CONFIG_APIC) += apic.o apic_common.o
 obj-$(CONFIG_ARM_GIC_KVM) += arm_gic_kvm.o
+obj-$(CONFIG_ARM_GIC_KVM) += arm_gicv3_kvm.o
 obj-$(CONFIG_STELLARIS) += armv7m_nvic.o
 obj-$(CONFIG_EXYNOS4) += exynos4210_gic.o exynos4210_combiner.o
 obj-$(CONFIG_GRLIB) += grlib_irqmp.o
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
new file mode 100644
index 000..6f892ea
--- /dev/null
+++ b/hw/intc/arm_gicv3_kvm.c
@@ -0,0 +1,283 @@
+/*
+ * ARM Generic Interrupt Controller using KVM in-kernel support
+ *
+ * Copyright (c) 2012 Linaro Limited
+ * Written by Peter Maydell
+ * Save/Restore logic added by Christoffer Dall.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see .
+ */
+
+#include "hw/sysbus.h"
+#include "sysemu/kvm.h"
+#include "kvm_arm.h"
+#include "gicv3_internal.h"
+
+//#define DEBUG_GICV3_KVM
+
+#ifdef DEBUG_GICV3_KVM
+static const int debug_gicv3_kvm = 1;
+#else
+static const int debug_gicv3_kvm = 0;
+#endif
+
+#define DPRINTF(fmt, ...) do { \
+if (debug_gicv3_kvm) { \
+printf("kvm_gicv3: " fmt , ## __VA_ARGS__); \
+} \
+} while (0)
+
+#define TYPE_KVM_ARM_GICV3 "kvm-arm-gicv3"
+#define KVM_ARM_GICV3(obj) \
+ OBJECT_CHECK(GICState, (obj), TYPE_KVM_ARM_GICV3)
+#define KVM_ARM_GICV3_CLASS(klass) \
+ OBJECT_CLASS_CHECK(KVMARMGICClass, (klass), TYPE_KVM_ARM_GICV3)
+#define KVM_ARM_GICV3_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(KVMARMGICClass, (obj), TYPE_KVM_ARM_GICV3)
+
+typedef struct KVMARMGICClass {
+ARMGICCommonClass parent_class;
+DeviceRealize parent_realize;
+void (*parent_reset)(DeviceState *dev);
+} KVMARMGICClass;
+
+static void kvm_arm_gicv3_set_irq(void *opaque, int irq, int level)
+{
+/* Meaning of the 'irq' parameter:
+ *  [0..N-1] : external interrupts
+ *  [N..N+31] : PPI (internal) interrupts for CPU 0
+ *  [N+32..N+63] : PPI (internal interrupts for CPU 1
+ *  ...
+ * Convert this to the kernel's desired encoding, which
+ * has separate fields in the irq number for type,
+ * CPU number and interrupt number.
+ */
+GICState *s = (GICState *)opaque;
+int kvm_irq, irqtype, cpu;
+
+if (irq < (s->num_irq - GICV3_INTERNAL)) {
+/* External interrupt. The kernel numbers these like the GIC
+ * hardware, with external interrupt IDs starting after the
+ * internal ones.
+ */
+irqtype = KVM_ARM_IRQ_TYPE_SPI;
+cpu = 0;
+irq += GICV3_INTERNAL;
+} else {
+/* Internal interrupt: decode into (cpu, interrupt id) */
+irqtype = KVM_ARM_IRQ_TYPE_PPI;
+irq -= (s->num_irq - GICV3_INTERNAL);
+cpu = irq / GICV3_INTERNAL;
+irq %= GICV3_INTERNAL;
+}
+kvm_irq = (irqtype << KVM_ARM_IRQ_TYPE_SHIFT)
+| (cpu << KVM_ARM_IRQ_VCPU_SHIFT) | irq;
+
+kvm_set_irq(kvm_state, kvm_irq, !!level);
+}
+
+static bool kvm_gic_supports_attr(GICState *s, int group, int attrnum)
+{
+struct kvm_device_attr attr = {
+.group = group,
+.attr = attrnum,
+.flags = 0,
+};
+
+if (s->dev_fd == -1) {
+return false;
+}
+
+return kvm_device_ioctl(s->dev_fd, KVM_HAS_DEVICE_ATTR, &attr) == 0;
+}
+
+static void kvm_gic_access(GICState *s, int group, int offset,
+   int cpu, uint32_t *val, bool write)
+{
+struct kvm_device_attr attr;
+int type;
+int err;
+
+cpu = cpu & 0xff;
+
+attr.flags = 0;
+attr.group = group;
+attr.attr = (((uint64_t)cpu << KVM_DEV_ARM_VGIC_CPUID_SHIFT) &
+ KVM_DEV_ARM_VGIC_CPUID_MASK) |
+(((uint64_t)offset << KVM_DEV_ARM_VGIC_OFFSET_SHIFT) &
+ KVM_DEV_ARM_VGIC_OFFSET_MASK);
+attr.addr = (uintptr_t)val;
+
+if (write) {
+type = KVM_SET_DEVICE_ATTR;
+} else {
+type = KVM_GET_DEVICE_ATTR;
+}
+
+err = kvm_device_ioctl(s->dev_f

Re: [Qemu-devel] Announcing qboot, a minimal x86 firmware for QEMU

2015-05-22 Thread Daniel P. Berrange
On Thu, May 21, 2015 at 03:51:43PM +0200, Paolo Bonzini wrote:
> Some of you may have heard about the "Clear Containers" initiative from
> Intel, which couple KVM with various kernel tricks to create extremely
> lightweight virtual machines.  The experimental Clear Containers setup
> requires only 18-20 MB to launch a virtual machine, and needs about 60
> ms to boot.
> 
> Now, as all of you probably know, "QEMU is great for running Windows or
> legacy Linux guests, but that flexibility comes at a hefty price. Not
> only does all of the emulation consume memory, it also requires some
> form of low-level firmware in the guest as well. All of this adds quite
> a bit to virtual-machine startup times (500 to 700 milliseconds is not
> unusual)".
> 
> Right?  In fact, it's for this reason that Clear Containers uses kvmtool
> instead of QEMU.
> 
> No, wrong!  In fact, reporting bad performance is pretty much the same
> as throwing down the gauntlet.

On the QEMU side of things I wonder if there is scope for taking AArch64's
'virt' machine type concept and duplicating it on all architectures. It
would be nice to have a common minimal machine type on all architectures
that discards all legacy platform stuff and focuses on the minimum needed
to run modern virtual machine optimized guest OS. People would always know
that a machine type called 'virt' was the minimal virtualization platform,
while the others all target emulation of realworld (legacy) baremetal
platforms.

Regards,
Daniel
-- 
|: http://berrange.com  -o-http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org  -o- http://virt-manager.org :|
|: http://autobuild.org   -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org   -o-   http://live.gnome.org/gtk-vnc :|



Re: [Qemu-devel] Announcing qboot, a minimal x86 firmware for QEMU

2015-05-22 Thread Peter Maydell
On 22 May 2015 at 12:01, Daniel P. Berrange  wrote:
> On the QEMU side of things I wonder if there is scope for taking AArch64's
> 'virt' machine type concept and duplicating it on all architectures.

Experience suggests that holding the line on "minimal" is really
quite tricky, though -- there's always one more thing that
somebody really wants to add...

-- PMM



Re: [Qemu-devel] Announcing qboot, a minimal x86 firmware for QEMU

2015-05-22 Thread Daniel P. Berrange
On Fri, May 22, 2015 at 12:04:54PM +0100, Peter Maydell wrote:
> On 22 May 2015 at 12:01, Daniel P. Berrange  wrote:
> > On the QEMU side of things I wonder if there is scope for taking AArch64's
> > 'virt' machine type concept and duplicating it on all architectures.
> 
> Experience suggests that holding the line on "minimal" is really
> quite tricky, though -- there's always one more thing that
> somebody really wants to add...

Yep, it is hard saying no - but I'd think as long as it was possible to add
the extra features using -device, it ought to be practical to keep a "virt"
machine types "-nodefaults -nodefconfig" base setup pretty minimal. In
particular I don't see why we need to have a SATA controller and ISA/LPC
bridge in every virt machine - root PCI bus only should be possible, as you
can provide disks via virtio-blk or virtio-scsi and serial, parallel, mouse,
floppy via PCI devices and/or by adding a USB bus in the cases where you
really need one.

Regards,
Daniel
-- 
|: http://berrange.com  -o-http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org  -o- http://virt-manager.org :|
|: http://autobuild.org   -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org   -o-   http://live.gnome.org/gtk-vnc :|



Re: [Qemu-devel] Announcing qboot, a minimal x86 firmware for QEMU

2015-05-22 Thread Peter Maydell
On 22 May 2015 at 12:12, Daniel P. Berrange  wrote:
> Yep, it is hard saying no - but I'd think as long as it was possible to add
> the extra features using -device, it ought to be practical to keep a "virt"
> machine types "-nodefaults -nodefconfig" base setup pretty minimal.

Mmm, but -device only works for pluggable devices really. We don't
have a coherent mechanism for saying "put the PS/2 keyboard controller
into the system at its usual IO ports" on the command line.

-- PMM



Re: [Qemu-devel] [PATCH 00/10] Consolidate crypto APIs & implementations

2015-05-22 Thread Gonglei
On 2015/5/21 18:56, Daniel P. Berrange wrote:
> This small series covers the crypto consolidation patches
> I previously posted as part of a larger RFC for the TLS work
> 
>   https://lists.nongnu.org/archive/html/qemu-devel/2015-04/msg02038.html
> 
> Currently there are a 5 main places in QEMU which use some
> form of cryptographic hash or cipher algorithm. These are
> the quorum block driver (hash), qcow[2] block driver (cipher),
> VNC password auth (cipher), VNC websockets (hash) and some
> of the CPU instruction emulation (cipher).
> 
> For ciphers the code is using the in-tree implementations
> of AES and/or the RFB cripple-DES. While there is nothing
> broken about these implementations, it is none the less
> desirable to be able to use the GNUTLS provided impls in
> cases whre we are already linking to GNUTLS. This will
> allow QEMU to use FIPS certified implementations, which
> have been well audited, have some protection against
> side-channel leakage and are generally actively maintained
> by people knowledgable about encryption.
> 
Can we use OpenSSL library in Qemu? If not, that's because of the license?

> For hash digests the code is already using GNUTLS APIs.
> 
> With the TLS work, and possible future improved block device
> encryption, there will be more general purpose crypto APIs
> needed in QEMU.
> 
> It is undesirable to continue to litter the code with
> countless #ifdef WITH_GNUTLS conditionals, as it makes
> it increasingly hard to understand the code.
> 
> The goal of this series is to thus consolidate all the
> crypto code into a single logical place in QEMU - the
> source in $GIT/crypto and heads in $GIT/include/crypto
> The code in this location will provide QEMU internal
> APIs for hash digests, ciphers, and later TLS and block
> encryption primitives. The implementations will be
> backed by GNUTLS, and either libgcrypt or nettle depending
> on which of these GNUTLS is linking to. In the case where
> GNUTLS is disabled at build time, we'll still keep the
> built-in AES & RFB-cripple-DES implementations available
> so we have no regression vs today's level of support.
> 
> The callers of the crypto code can now be unconditionally
> compiled and, if needed, they can check the availability
> of algorithms they want at runtime and report clear errors
> to the CLI or QMP if not available. This is a minor
> difference in behaviour for the quorum block driver which
> would previously be disabled at compile time if gnutls
> was not available.
> 
> A future posting will include the TLS crypto APIs.
> 
> I have not attempted to convert the CPU emulation code to
> use the new crypto APIs, since that code appears to have
> quite specific need for access to the low level internal
> stages of the AES algorithm. So I've left it using the
> QEMU built-in AES code.
> 
> I've added myself in the MAINTAINERS file for the new
> directories, since it was't clear if anyone else on the
> existing QEMU maintainer list had any interest / knowledge
> in maintaining the crypto related pieces.
> 
Good job :)
Recently, My colleague and I do some work about cryptography,
maybe we can discuss them if possible.

Regards,
-Gonglei

> Daniel P. Berrange (10):
>   crypto: introduce new module for computing hash digests
>   crypto: move built-in AES implementation into crypto/
>   crypto: move built-in D3DES implementation into crypto/
>   crypto: introduce generic cipher API & built-in implementation
>   crypto: add a gcrypt cipher implementation
>   crypto: add a nettle cipher implementation
>   block: convert quorum blockdrv to use crypto APIs
>   ui: convert VNC websockets to use crypto APIs
>   block: convert qcow/qcow2 to use generic cipher API
>   ui: convert VNC to use generic cipher API
> 
>  MAINTAINERS   |   7 +
>  Makefile.objs |   1 +
>  block/Makefile.objs   |   2 +-
>  block/qcow.c  | 100 ++---
>  block/qcow2-cluster.c |  46 +++-
>  block/qcow2.c |  95 +
>  block/qcow2.h |  13 +-
>  block/quorum.c|  38 ++--
>  configure | 162 +-
>  crypto/Makefile.objs  |   5 +
>  {util => crypto}/aes.c|   2 +-
>  crypto/cipher-builtin.c   | 391 
> ++
>  crypto/cipher-gcrypt.c| 203 ++
>  crypto/cipher-nettle.c| 226 
>  crypto/cipher.c   |  31 +++
>  ui/d3des.c => crypto/desrfb.c |   2 +-
>  crypto/hash.c | 202 ++
>  crypto/init.c | 152 +
>  include/{qemu => crypto}/aes.h|   0
>  include/crypto/cipher.h   | 208 ++
>  ui/d3des.h => include/crypto/desrfb.h |   0
>  include/crypto/hash.h | 189 +++

Re: [Qemu-devel] [PULL v2 00/18] target-alpha fpu improvements

2015-05-22 Thread Peter Maydell
On 22 May 2015 at 11:22, Peter Maydell  wrote:
> On 22 May 2015 at 11:00, Peter Maydell  wrote:
>> On 21 May 2015 at 18:39, Richard Henderson  wrote:
>>> for you to fetch changes up to 32ad48abd74a997220b841e4e913edeb267aa362:
>>>
>>>   target-alpha: Add vector implementation for CMPBGE (2015-05-21 10:34:18 
>>> -0700)
>>
>> Applied, thanks.
>
> Except I failed to notice a test failure from one of my builds
> before pushing:
>
> target-alpha/int_helper.c: In function 'helper_cmpbge':
> target-alpha/int_helper.c:77: error: invalid operands to binary >=
> target-alpha/int_helper.c:79: error: subscripted value is neither
> array nor pointer
>
> That's in the Centos5 build, which is
> gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-55)
>
> Any suggestions?
>
> I do note that this build target is basically obsolete anyway, because
> we're about to move to requiring glib 2.22, at which point Centos5 is
> officially Too Old. So maybe we just say "yeah, you need a newer gcc" ?

Hmm. This fails on some of the travis builds too, with slightly
different warnings:

gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
target-alpha/int_helper.c:77:24: error: invalid operands to binary >=
(have '__vector(16) unsigned char' and '__vector(16) unsigned char')

I think the best thing to do for the moment is to revert commit
32ad48abd74a9 so we can get trunk building again, so I'm going to
do that.

thanks
-- PMM



Re: [Qemu-devel] Announcing qboot, a minimal x86 firmware for QEMU

2015-05-22 Thread Daniel P. Berrange
On Fri, May 22, 2015 at 12:21:27PM +0100, Peter Maydell wrote:
> On 22 May 2015 at 12:12, Daniel P. Berrange  wrote:
> > Yep, it is hard saying no - but I'd think as long as it was possible to add
> > the extra features using -device, it ought to be practical to keep a "virt"
> > machine types "-nodefaults -nodefconfig" base setup pretty minimal.
> 
> Mmm, but -device only works for pluggable devices really. We don't
> have a coherent mechanism for saying "put the PS/2 keyboard controller
> into the system at its usual IO ports" on the command line.

Oh, I didn't neccessarily mean that we'd need the ability to add a
ps/2 keyboard via -device. I meant that there just need to be able
to add /some/ kind of keyboard. eg we have a usb-kbd device that
could potentially fill that role. Likewise for mouse pointer. Serial
ports, etc.

Regards,
Daniel
-- 
|: http://berrange.com  -o-http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org  -o- http://virt-manager.org :|
|: http://autobuild.org   -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org   -o-   http://live.gnome.org/gtk-vnc :|



Re: [Qemu-devel] Announcing qboot, a minimal x86 firmware for QEMU

2015-05-22 Thread Gerd Hoffmann
On Fr, 2015-05-22 at 12:21 +0100, Peter Maydell wrote:
> On 22 May 2015 at 12:12, Daniel P. Berrange  wrote:
> > Yep, it is hard saying no - but I'd think as long as it was possible to add
> > the extra features using -device, it ought to be practical to keep a "virt"
> > machine types "-nodefaults -nodefconfig" base setup pretty minimal.
> 
> Mmm, but -device only works for pluggable devices really. We don't
> have a coherent mechanism for saying "put the PS/2 keyboard controller
> into the system at its usual IO ports" on the command line.

Do we need that in the first place?
You can plugin a usb keyboard today.
You'll be able to plugin a virtio keyboard soon.

I think alot of hardware where this applies to is the legacy stuff we
want to get rid of for '-M virt' ...

cheers,
  Gerd





[Qemu-devel] [PATCH 10/20] monitor: Propagate errors through qmp_check_input_obj()

2015-05-22 Thread Markus Armbruster
Signed-off-by: Markus Armbruster 
---
 monitor.c | 19 ++-
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/monitor.c b/monitor.c
index 01b1a5f..1d7ad0a 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4929,14 +4929,14 @@ out:
  * 5. If the "id" key exists, it can be anything (ie. json-value)
  * 6. Any argument not listed above is considered invalid
  */
-static QDict *qmp_check_input_obj(QObject *input_obj)
+static QDict *qmp_check_input_obj(QObject *input_obj, Error **errp)
 {
 const QDictEntry *ent;
 int has_exec_key = 0;
 QDict *input_dict;
 
 if (qobject_type(input_obj) != QTYPE_QDICT) {
-qerror_report(QERR_QMP_BAD_INPUT_OBJECT, "object");
+error_set(errp, QERR_QMP_BAD_INPUT_OBJECT, "object");
 return NULL;
 }
 
@@ -4948,27 +4948,27 @@ static QDict *qmp_check_input_obj(QObject *input_obj)
 
 if (!strcmp(arg_name, "execute")) {
 if (qobject_type(arg_obj) != QTYPE_QSTRING) {
-qerror_report(QERR_QMP_BAD_INPUT_OBJECT_MEMBER, "execute",
-  "string");
+error_set(errp, QERR_QMP_BAD_INPUT_OBJECT_MEMBER,
+  "execute", "string");
 return NULL;
 }
 has_exec_key = 1;
 } else if (!strcmp(arg_name, "arguments")) {
 if (qobject_type(arg_obj) != QTYPE_QDICT) {
-qerror_report(QERR_QMP_BAD_INPUT_OBJECT_MEMBER, "arguments",
-  "object");
+error_set(errp, QERR_QMP_BAD_INPUT_OBJECT_MEMBER,
+  "arguments", "object");
 return NULL;
 }
 } else if (!strcmp(arg_name, "id")) {
 /* FIXME: check duplicated IDs for async commands */
 } else {
-qerror_report(QERR_QMP_EXTRA_MEMBER, arg_name);
+error_set(errp, QERR_QMP_EXTRA_MEMBER, arg_name);
 return NULL;
 }
 }
 
 if (!has_exec_key) {
-qerror_report(QERR_QMP_BAD_INPUT_OBJECT, "execute");
+error_set(errp, QERR_QMP_BAD_INPUT_OBJECT, "execute");
 return NULL;
 }
 
@@ -4994,8 +4994,9 @@ static void handle_qmp_command(JSONMessageParser *parser, 
QList *tokens)
 goto err_out;
 }
 
-input = qmp_check_input_obj(obj);
+input = qmp_check_input_obj(obj, &local_err);
 if (!input) {
+qerror_report_err(local_err);
 qobject_decref(obj);
 goto err_out;
 }
-- 
1.9.3




[Qemu-devel] [PATCH 03/20] monitor: Improve and document client_migrate_info protocol error

2015-05-22 Thread Markus Armbruster
Protocol must be spice, vnc isn't implemented.  Fix up documentation.

Attempts to use vnc or any other unknown protocol yield the misleading
error message "Invalid parameter 'protocol'".  Improve it to
"Parameter 'protocol' expects spice".

Signed-off-by: Markus Armbruster 
---
 hmp-commands.hx | 1 +
 monitor.c   | 2 +-
 qmp-commands.hx | 3 ++-
 3 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index e864a6c..a8be73a 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1022,6 +1022,7 @@ STEXI
 Set the spice/vnc connection info for the migration target.  The spice/vnc
 server will ask the spice/vnc client to automatically reconnect using the
 new parameters (if specified) once the vm migration finished successfully.
+Not yet implemented for VNC.
 ETEXI
 
 {
diff --git a/monitor.c b/monitor.c
index 5330e61..b507ee3 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1063,7 +1063,7 @@ static int client_migrate_info(Monitor *mon, const QDict 
*qdict,
 return 0;
 }
 
-qerror_report(QERR_INVALID_PARAMETER, "protocol");
+qerror_report(QERR_INVALID_PARAMETER_VALUE, "protocol", "spice");
 return -1;
 }
 
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 14e109e..c267c89 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -795,10 +795,11 @@ client_migrate_info
 Set the spice/vnc connection info for the migration target.  The spice/vnc
 server will ask the spice/vnc client to automatically reconnect using the
 new parameters (if specified) once the vm migration finished successfully.
+Not yet implemented for VNC.
 
 Arguments:
 
-- "protocol": protocol: "spice" or "vnc" (json-string)
+- "protocol": must be "spice" (json-string)
 - "hostname": migration target hostname (json-string)
 - "port": spice/vnc tcp port for plaintext channels (json-int, 
optional)
 - "tls-port": spice tcp port for tls-secured channels (json-int, optional)
-- 
1.9.3




[Qemu-devel] [PATCH 08/20] monitor: Drop unused "new" HMP command interface

2015-05-22 Thread Markus Armbruster
Signed-off-by: Markus Armbruster 
---
 monitor.c | 22 +-
 1 file changed, 1 insertion(+), 21 deletions(-)

diff --git a/monitor.c b/monitor.c
index 64e7bd3..3a7e625 100644
--- a/monitor.c
+++ b/monitor.c
@@ -123,7 +123,6 @@ typedef struct mon_cmd_t {
 const char *args_type;
 const char *params;
 const char *help;
-void (*user_print)(Monitor *mon, const QObject *data);
 union {
 void (*cmd)(Monitor *mon, const QDict *qdict);
 int  (*cmd_new)(Monitor *mon, const QDict *params, QObject **ret_data);
@@ -378,11 +377,6 @@ static int GCC_FMT_ATTR(2, 3) monitor_fprintf(FILE *stream,
 return 0;
 }
 
-static inline int handler_is_qobject(const mon_cmd_t *cmd)
-{
-return cmd->user_print != NULL;
-}
-
 static inline int monitor_has_error(const Monitor *mon)
 {
 return mon->error != NULL;
@@ -4045,24 +4039,10 @@ static void handle_user_command(Monitor *mon, const 
char *cmdline)
 qdict = qdict_new();
 
 cmd = monitor_parse_command(mon, cmdline, 0, mon->cmd_table, qdict);
-if (!cmd)
-goto out;
-
-if (handler_is_qobject(cmd)) {
-QObject *data = NULL;
-
-/* XXX: ignores the error code */
-cmd->mhandler.cmd_new(mon, qdict, &data);
-assert(!monitor_has_error(mon));
-if (data) {
-cmd->user_print(mon, data);
-qobject_decref(data);
-}
-} else {
+if (cmd) {
 cmd->mhandler.cmd(mon, qdict);
 }
 
-out:
 QDECREF(qdict);
 }
 
-- 
1.9.3




[Qemu-devel] [PATCH 00/20] monitor: Wean core off QError, and other cleanups

2015-05-22 Thread Markus Armbruster
Command handlers still use QError.  Left for another day.

Markus Armbruster (20):
  monitor: Drop broken, unused asynchronous command interface
  monitor: Clean up after previous commit
  monitor: Improve and document client_migrate_info protocol error
  monitor: Convert client_migrate_info to QAPI
  monitor: Use traditional command interface for HMP drive_del
  monitor: Use traditional command interface for HMP device_add
  monitor: Use trad. command interface for HMP pcie_aer_inject_error
  monitor: Drop unused "new" HMP command interface
  monitor: Propagate errors through qmp_check_client_args()
  monitor: Propagate errors through qmp_check_input_obj()
  monitor: Wean monitor_protocol_emitter() off mon->error
  monitor: Inline monitor_has_error() into its only caller
  monitor: Limit QError use to command handlers
  monitor: Rename handle_user_command() to handle_hmp_command()
  monitor: Rename monitor_control_read(), monitor_control_event()
  monitor: Unbox Monitor member mc and rename to qmp
  monitor: Drop do_qmp_capabilities()'s superfluous QMP check
  monitor: Turn int command_mode into bool in_command_mode
  monitor: Rename monitor_ctrl_mode() to monitor_is_qmp()
  monitor: Change return type of monitor_cur_is_qmp() to bool

 blockdev.c|   9 +-
 hmp-commands.hx   |  13 +-
 hmp.c |  23 +++
 hmp.h |   2 +
 hw/pci/pci-stub.c |  14 +-
 hw/pci/pcie_aer.c |  39 ++---
 include/monitor/monitor.h |   7 +-
 include/sysemu/blockdev.h |   2 +-
 include/sysemu/sysemu.h   |   4 +-
 monitor.c | 378 --
 qapi-schema.json  |  20 +++
 qmp-commands.hx   |   5 +-
 stubs/mon-is-qmp.c|   2 +-
 13 files changed, 214 insertions(+), 304 deletions(-)

-- 
1.9.3




[Qemu-devel] [PATCH 14/20] monitor: Rename handle_user_command() to handle_hmp_command()

2015-05-22 Thread Markus Armbruster
Signed-off-by: Markus Armbruster 
---
 monitor.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/monitor.c b/monitor.c
index 65ef400..ecadda7 100644
--- a/monitor.c
+++ b/monitor.c
@@ -574,7 +574,7 @@ static int do_qmp_capabilities(Monitor *mon, const QDict 
*params,
 return 0;
 }
 
-static void handle_user_command(Monitor *mon, const char *cmdline);
+static void handle_hmp_command(Monitor *mon, const char *cmdline);
 
 static void monitor_data_init(Monitor *mon)
 {
@@ -613,7 +613,7 @@ char *qmp_human_monitor_command(const char *command_line, 
bool has_cpu_index,
 }
 }
 
-handle_user_command(&hmp, command_line);
+handle_hmp_command(&hmp, command_line);
 cur_mon = old_mon;
 
 qemu_mutex_lock(&hmp.out_lock);
@@ -4025,7 +4025,7 @@ void monitor_set_error(Monitor *mon, QError *qerror)
 }
 }
 
-static void handle_user_command(Monitor *mon, const char *cmdline)
+static void handle_hmp_command(Monitor *mon, const char *cmdline)
 {
 QDict *qdict;
 const mon_cmd_t *cmd;
@@ -5071,7 +5071,7 @@ static void monitor_read(void *opaque, const uint8_t 
*buf, int size)
 if (size == 0 || buf[size - 1] != 0)
 monitor_printf(cur_mon, "corrupted command\n");
 else
-handle_user_command(cur_mon, (char *)buf);
+handle_hmp_command(cur_mon, (char *)buf);
 }
 
 cur_mon = old_mon;
@@ -5083,7 +5083,7 @@ static void monitor_command_cb(void *opaque, const char 
*cmdline,
 Monitor *mon = opaque;
 
 monitor_suspend(mon);
-handle_user_command(mon, cmdline);
+handle_hmp_command(mon, cmdline);
 monitor_resume(mon);
 }
 
-- 
1.9.3




[Qemu-devel] [PATCH 12/20] monitor: Inline monitor_has_error() into its only caller

2015-05-22 Thread Markus Armbruster
Signed-off-by: Markus Armbruster 
---
 monitor.c | 7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/monitor.c b/monitor.c
index c732203..71ca03f 100644
--- a/monitor.c
+++ b/monitor.c
@@ -377,11 +377,6 @@ static int GCC_FMT_ATTR(2, 3) monitor_fprintf(FILE *stream,
 return 0;
 }
 
-static inline int monitor_has_error(const Monitor *mon)
-{
-return mon->error != NULL;
-}
-
 static void monitor_json_emitter(Monitor *mon, const QObject *data)
 {
 QString *json;
@@ -5031,7 +5026,7 @@ static void handle_qmp_command(JSONMessageParser *parser, 
QList *tokens)
 
 if (cmd->mhandler.cmd_new(mon, args, &data)) {
 /* Command failed... */
-if (!monitor_has_error(mon)) {
+if (!mon->error) {
 /* ... without setting an error, so make one up */
 qerror_report(QERR_UNDEFINED_ERROR);
 }
-- 
1.9.3




[Qemu-devel] [PATCH 02/20] monitor: Clean up after previous commit

2015-05-22 Thread Markus Armbruster
Signed-off-by: Markus Armbruster 
---
 monitor.c | 40 +++-
 1 file changed, 11 insertions(+), 29 deletions(-)

diff --git a/monitor.c b/monitor.c
index 9a0c3b7..5330e61 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4045,18 +4045,6 @@ void monitor_set_error(Monitor *mon, QError *qerror)
 }
 }
 
-static void handler_audit(Monitor *mon, const mon_cmd_t *cmd, int ret)
-{
-if (ret && !monitor_has_error(mon)) {
-/*
- * If it returns failure, it must have passed on error.
- *
- * Action: Report an internal error to the client if in QMP.
- */
-qerror_report(QERR_UNDEFINED_ERROR);
-}
-}
-
 static void handle_user_command(Monitor *mon, const char *cmdline)
 {
 QDict *qdict;
@@ -5015,28 +5003,17 @@ static QDict *qmp_check_input_obj(QObject *input_obj)
 return input_dict;
 }
 
-static void qmp_call_cmd(Monitor *mon, const mon_cmd_t *cmd,
- const QDict *params)
-{
-int ret;
-QObject *data = NULL;
-
-ret = cmd->mhandler.cmd_new(mon, params, &data);
-handler_audit(mon, cmd, ret);
-monitor_protocol_emitter(mon, data);
-qobject_decref(data);
-}
-
 static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
 {
 int err;
-QObject *obj;
+QObject *obj, *data;
 QDict *input, *args;
 const mon_cmd_t *cmd;
 const char *cmd_name;
 Monitor *mon = cur_mon;
 
 args = input = NULL;
+data = NULL;
 
 obj = json_parser_parse(tokens, NULL);
 if (!obj) {
@@ -5079,12 +5056,17 @@ static void handle_qmp_command(JSONMessageParser 
*parser, QList *tokens)
 goto err_out;
 }
 
-qmp_call_cmd(mon, cmd, args);
-goto out;
+if (cmd->mhandler.cmd_new(mon, args, &data)) {
+/* Command failed... */
+if (!monitor_has_error(mon)) {
+/* ... without setting an error, so make one up */
+qerror_report(QERR_UNDEFINED_ERROR);
+}
+}
 
 err_out:
-monitor_protocol_emitter(mon, NULL);
-out:
+monitor_protocol_emitter(mon, data);
+qobject_decref(data);
 QDECREF(input);
 QDECREF(args);
 }
-- 
1.9.3




[Qemu-devel] [PATCH 04/20] monitor: Convert client_migrate_info to QAPI

2015-05-22 Thread Markus Armbruster
Signed-off-by: Markus Armbruster 
---
 hmp-commands.hx  |  3 +--
 hmp.c| 17 +
 hmp.h|  1 +
 monitor.c| 42 ++
 qapi-schema.json | 20 
 qmp-commands.hx  |  2 +-
 6 files changed, 58 insertions(+), 27 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index a8be73a..480b8b9 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1012,8 +1012,7 @@ ETEXI
 .args_type  = 
"protocol:s,hostname:s,port:i?,tls-port:i?,cert-subject:s?",
 .params = "protocol hostname port tls-port cert-subject",
 .help   = "send migration info to spice/vnc client",
-.user_print = monitor_user_noop,
-.mhandler.cmd_new = client_migrate_info,
+.mhandler.cmd = hmp_client_migrate_info,
 },
 
 STEXI
diff --git a/hmp.c b/hmp.c
index e17852d..5a43f9d 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1250,6 +1250,23 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict 
*qdict)
 }
 }
 
+void hmp_client_migrate_info(Monitor *mon, const QDict *qdict)
+{
+Error *err = NULL;
+const char *protocol = qdict_get_str(qdict, "protocol");
+const char *hostname = qdict_get_str(qdict, "hostname");
+bool has_port= qdict_haskey(qdict, "port");
+int port = qdict_get_try_int(qdict, "port", -1);
+bool has_tls_port= qdict_haskey(qdict, "tls-port");
+int tls_port = qdict_get_try_int(qdict, "tls-port", -1);
+const char *cert_subject = qdict_get_try_str(qdict, "cert-subject");
+
+qmp_client_migrate_info(protocol, hostname,
+has_port, port, has_tls_port, tls_port,
+!!cert_subject, cert_subject, &err);
+hmp_handle_error(mon, &err);
+}
+
 void hmp_set_password(Monitor *mon, const QDict *qdict)
 {
 const char *protocol  = qdict_get_str(qdict, "protocol");
diff --git a/hmp.h b/hmp.h
index a158e3f..b81439c 100644
--- a/hmp.h
+++ b/hmp.h
@@ -67,6 +67,7 @@ void hmp_migrate_set_speed(Monitor *mon, const QDict *qdict);
 void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict);
 void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict);
 void hmp_migrate_set_cache_size(Monitor *mon, const QDict *qdict);
+void hmp_client_migrate_info(Monitor *mon, const QDict *qdict);
 void hmp_set_password(Monitor *mon, const QDict *qdict);
 void hmp_expire_password(Monitor *mon, const QDict *qdict);
 void hmp_eject(Monitor *mon, const QDict *qdict);
diff --git a/monitor.c b/monitor.c
index b507ee3..4c37203 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1032,39 +1032,33 @@ static void hmp_info_trace_events(Monitor *mon, const 
QDict *qdict)
 qapi_free_TraceEventInfoList(events);
 }
 
-static int client_migrate_info(Monitor *mon, const QDict *qdict,
-   QObject **ret_data)
+void qmp_client_migrate_info(const char *protocol, const char *hostname,
+ bool has_port, int64_t port,
+ bool has_tls_port, int64_t tls_port,
+ bool has_cert_subject, const char *cert_subject,
+ Error **errp)
 {
-const char *protocol = qdict_get_str(qdict, "protocol");
-const char *hostname = qdict_get_str(qdict, "hostname");
-const char *subject  = qdict_get_try_str(qdict, "cert-subject");
-int port = qdict_get_try_int(qdict, "port", -1);
-int tls_port = qdict_get_try_int(qdict, "tls-port", -1);
-Error *err = NULL;
-int ret;
-
 if (strcmp(protocol, "spice") == 0) {
-if (!qemu_using_spice(&err)) {
-qerror_report_err(err);
-error_free(err);
-return -1;
+if (!qemu_using_spice(errp)) {
+return;
 }
 
-if (port == -1 && tls_port == -1) {
-qerror_report(QERR_MISSING_PARAMETER, "port/tls-port");
-return -1;
+if (!has_port && !has_tls_port) {
+error_set(errp, QERR_MISSING_PARAMETER, "port/tls-port");
+return;
 }
 
-ret = qemu_spice_migrate_info(hostname, port, tls_port, subject);
-if (ret != 0) {
-qerror_report(QERR_UNDEFINED_ERROR);
-return -1;
+if (qemu_spice_migrate_info(hostname,
+has_port ? port : -1,
+has_tls_port ? tls_port : -1,
+cert_subject)) {
+error_set(errp, QERR_UNDEFINED_ERROR);
+return;
 }
-return 0;
+return;
 }
 
-qerror_report(QERR_INVALID_PARAMETER_VALUE, "protocol", "spice");
-return -1;
+error_set(errp, QERR_INVALID_PARAMETER_VALUE, "protocol", "spice");
 }
 
 static void hmp_logfile(Monitor *mon, const QDict *qdict)
diff --git a/qapi-schema.json b/qapi-schema.json
index f97ffa1..b8bac9c 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -638,6 +6

[Qemu-devel] [PATCH 05/20] monitor: Use traditional command interface for HMP drive_del

2015-05-22 Thread Markus Armbruster
All QMP commands use the "new" handler interface (mhandler.cmd_new).
Most HMP commands still use the traditional interface (mhandler.cmd),
but a few use the "new" one.  Complicates handle_user_command() for no
gain, so I'm converting these to the traditional interface.

For drive_del, that's easy: hmp_drive_del() sheds its unused last
parameter, and its return value, which the caller ignored anyway.

Signed-off-by: Markus Armbruster 
---
 blockdev.c| 9 -
 hmp-commands.hx   | 3 +--
 include/sysemu/blockdev.h | 2 +-
 3 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 5eaf77e..de94a8b 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2113,7 +2113,7 @@ void qmp_block_dirty_bitmap_clear(const char *node, const 
char *name,
 aio_context_release(aio_context);
 }
 
-int hmp_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
+void hmp_drive_del(Monitor *mon, const QDict *qdict)
 {
 const char *id = qdict_get_str(qdict, "id");
 BlockBackend *blk;
@@ -2124,14 +2124,14 @@ int hmp_drive_del(Monitor *mon, const QDict *qdict, 
QObject **ret_data)
 blk = blk_by_name(id);
 if (!blk) {
 error_report("Device '%s' not found", id);
-return -1;
+return;
 }
 bs = blk_bs(blk);
 
 if (!blk_legacy_dinfo(blk)) {
 error_report("Deleting device added with blockdev-add"
  " is not supported");
-return -1;
+return;
 }
 
 aio_context = bdrv_get_aio_context(bs);
@@ -2140,7 +2140,7 @@ int hmp_drive_del(Monitor *mon, const QDict *qdict, 
QObject **ret_data)
 if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_DRIVE_DEL, &local_err)) {
 error_report_err(local_err);
 aio_context_release(aio_context);
-return -1;
+return;
 }
 
 /* quiesce block driver; prevent further io */
@@ -2163,7 +2163,6 @@ int hmp_drive_del(Monitor *mon, const QDict *qdict, 
QObject **ret_data)
 }
 
 aio_context_release(aio_context);
-return 0;
 }
 
 void qmp_block_resize(bool has_device, const char *device,
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 480b8b9..9939656 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -178,8 +178,7 @@ ETEXI
 .args_type  = "id:B",
 .params = "device",
 .help   = "remove host block device",
-.user_print = monitor_user_noop,
-.mhandler.cmd_new = hmp_drive_del,
+.mhandler.cmd = hmp_drive_del,
 },
 
 STEXI
diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
index 7ca59b5..3104150 100644
--- a/include/sysemu/blockdev.h
+++ b/include/sysemu/blockdev.h
@@ -66,5 +66,5 @@ DriveInfo *drive_new(QemuOpts *arg, BlockInterfaceType 
block_default_type);
 void qmp_change_blockdev(const char *device, const char *filename,
  const char *format, Error **errp);
 void hmp_commit(Monitor *mon, const QDict *qdict);
-int hmp_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data);
+void hmp_drive_del(Monitor *mon, const QDict *qdict);
 #endif
-- 
1.9.3




[Qemu-devel] [PATCH 17/20] monitor: Drop do_qmp_capabilities()'s superfluous QMP check

2015-05-22 Thread Markus Armbruster
Superfluous since commit 30f5041 removed it from HMP.

Signed-off-by: Markus Armbruster 
---
 monitor.c | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/monitor.c b/monitor.c
index 4b397e6..6e9cc8c 100644
--- a/monitor.c
+++ b/monitor.c
@@ -566,11 +566,7 @@ static void monitor_qapi_event_init(void)
 static int do_qmp_capabilities(Monitor *mon, const QDict *params,
QObject **ret_data)
 {
-/* Will setup QMP capabilities in the future */
-if (monitor_ctrl_mode(mon)) {
-mon->qmp.command_mode = 1;
-}
-
+mon->qmp.command_mode = 1;
 return 0;
 }
 
-- 
1.9.3




[Qemu-devel] [PATCH 01/20] monitor: Drop broken, unused asynchronous command interface

2015-05-22 Thread Markus Armbruster
The asynchronous monitor command interface goes back to commit 940cc30
(Jan 2010).  Added a third case to command execution.  The hope back
then according to the commit message was that all commands get
converted to the asynchronous interface, killing off the other two
cases.  Didn't happen.

The initial asynchronous commands balloon and info balloon were
converted back to synchronous long ago (commit 96637bc and d72f32),
with commit messages calling the asynchronous interface "not fully
working" and "deprecated".  The only other user went away in commit
3b5704b.

New code generally uses synchronous commands and asynchronous events.

What exactly is still "not fully working" with asynchronous commands?
Well, here's a bug that defeats actual asynchronous use pretty
reliably: the reply's ID is wrong (and has always been wrong) unless
you use the command synchronously!  To reproduce, we need an
asynchronous command, so we have to go back before the commit 3b5704b.
Run QEMU with spice:

$ qemu-system-x86_64 -nodefaults -S -spice port=5900,disable-ticketing -qmp 
stdio
{"QMP": {"version": {"qemu": {"micro": 50, "minor": 2, "major":
2}, "package": ""}, "capabilities": []}}

Connect a spice client in another terminal:

$ remote-viewer spice://localhost:5900

Set up a migration destination dummy in a third terminal:

$ socat TCP-LISTEN:12345 STDIO

Now paste the following into the QMP monitor:

{ "execute": "qmp_capabilities" }
{ "execute": "client_migrate_info", "id": "i1", "arguments": { "protocol": 
"spice", "hostname": "localhost", "port": 12345 } }
{ "execute": "query-kvm", "id": "i2" }

Produces two replies immediately, one to qmp_capabilities, and one to
query-kvm:

{"return": {}}
{"return": {"enabled": false, "present": true}, "id": "i2"}

Both are correct.  Two lines of debug output from libspice-server not
shown.

Now EOF socat's standard input to make it close the connection.  This
makes the asynchronous client_migrate_info complete.  It replies:

{"return": {}}

Bug: "id": "i1" is missing.  Two lines of debug output from
libspice-server not shown.  Cherry on top: storage for the missing ID
is leaked.

Get rid of this stuff before somebody hurts himself with it.

Signed-off-by: Markus Armbruster 
---
 include/monitor/monitor.h |  5 
 monitor.c | 68 ++-
 2 files changed, 2 insertions(+), 71 deletions(-)

diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
index df67d56..d409b6a 100644
--- a/include/monitor/monitor.h
+++ b/include/monitor/monitor.h
@@ -16,9 +16,6 @@ extern Monitor *default_mon;
 #define MONITOR_USE_CONTROL   0x04
 #define MONITOR_USE_PRETTY0x08
 
-/* flags for monitor commands */
-#define MONITOR_CMD_ASYNC   0x0001
-
 int monitor_cur_is_qmp(void);
 
 void monitor_init(CharDriverState *chr, int flags);
@@ -43,8 +40,6 @@ void monitor_flush(Monitor *mon);
 int monitor_set_cpu(int cpu_index);
 int monitor_get_cpu_index(void);
 
-typedef void (MonitorCompletion)(void *opaque, QObject *ret_data);
-
 void monitor_set_error(Monitor *mon, QError *qerror);
 void monitor_read_command(Monitor *mon, int show_prompt);
 int monitor_read_password(Monitor *mon, ReadLineFunc *readline_func,
diff --git a/monitor.c b/monitor.c
index b2561e1..9a0c3b7 100644
--- a/monitor.c
+++ b/monitor.c
@@ -118,12 +118,6 @@
  *
  */
 
-typedef struct MonitorCompletionData MonitorCompletionData;
-struct MonitorCompletionData {
-Monitor *mon;
-void (*user_print)(Monitor *mon, const QObject *data);
-};
-
 typedef struct mon_cmd_t {
 const char *name;
 const char *args_type;
@@ -133,10 +127,7 @@ typedef struct mon_cmd_t {
 union {
 void (*cmd)(Monitor *mon, const QDict *qdict);
 int  (*cmd_new)(Monitor *mon, const QDict *params, QObject **ret_data);
-int  (*cmd_async)(Monitor *mon, const QDict *params,
-  MonitorCompletion *cb, void *opaque);
 } mhandler;
-int flags;
 /* @sub_table is a list of 2nd level of commands. If it do not exist,
  * mhandler should be used. If it exist, sub_table[?].mhandler should be
  * used, and mhandler of 1st level plays the role of help function.
@@ -394,11 +385,6 @@ static inline int handler_is_qobject(const mon_cmd_t *cmd)
 return cmd->user_print != NULL;
 }
 
-static inline bool handler_is_async(const mon_cmd_t *cmd)
-{
-return cmd->flags & MONITOR_CMD_ASYNC;
-}
-
 static inline int monitor_has_error(const Monitor *mon)
 {
 return mon->error != NULL;
@@ -917,45 +903,6 @@ static void hmp_trace_file(Monitor *mon, const QDict 
*qdict)
 }
 #endif
 
-static void user_monitor_complete(void *opaque, QObject *ret_data)
-{
-MonitorCompletionData *data = (MonitorCompletionData *)opaque; 
-
-if (ret_data) {
-data->user_print(data->mon, ret_data);
-}
-monitor_resume(data->mon);
-g_free(data);
-}
-
-static void qmp_monitor_complete(void *opaque, QObject *re

[Qemu-devel] [PATCH 06/20] monitor: Use traditional command interface for HMP device_add

2015-05-22 Thread Markus Armbruster
All QMP commands use the "new" handler interface (mhandler.cmd_new).
Most HMP commands still use the traditional interface (mhandler.cmd),
but a few use the "new" one.  Complicates handle_user_command() for no
gain, so I'm converting these to the traditional interface.

For device_add, that's easy: just wrap the obvious hmp_device_add()
around do_device_add().

monitor_user_noop() is now unused, drop it.

Signed-off-by: Markus Armbruster 
---
 hmp-commands.hx | 3 +--
 hmp.c   | 6 ++
 hmp.h   | 1 +
 monitor.c   | 2 --
 4 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 9939656..7776f16 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -653,8 +653,7 @@ ETEXI
 .args_type  = "device:O",
 .params = "driver[,prop=value][,...]",
 .help   = "add device, like -device on the command line",
-.user_print = monitor_user_noop,
-.mhandler.cmd_new = do_device_add,
+.mhandler.cmd = hmp_device_add,
 .command_completion = device_add_completion,
 },
 
diff --git a/hmp.c b/hmp.c
index 5a43f9d..514f22f 100644
--- a/hmp.c
+++ b/hmp.c
@@ -22,6 +22,7 @@
 #include "qmp-commands.h"
 #include "qemu/sockets.h"
 #include "monitor/monitor.h"
+#include "monitor/qdev.h"
 #include "qapi/opts-visitor.h"
 #include "qapi/string-output-visitor.h"
 #include "qapi-visit.h"
@@ -1499,6 +1500,11 @@ void hmp_migrate(Monitor *mon, const QDict *qdict)
 }
 }
 
+void hmp_device_add(Monitor *mon, const QDict *qdict)
+{
+do_device_add(mon, qdict, NULL);
+}
+
 void hmp_device_del(Monitor *mon, const QDict *qdict)
 {
 const char *id = qdict_get_str(qdict, "id");
diff --git a/hmp.h b/hmp.h
index b81439c..a70ac4f 100644
--- a/hmp.h
+++ b/hmp.h
@@ -80,6 +80,7 @@ void hmp_block_job_pause(Monitor *mon, const QDict *qdict);
 void hmp_block_job_resume(Monitor *mon, const QDict *qdict);
 void hmp_block_job_complete(Monitor *mon, const QDict *qdict);
 void hmp_migrate(Monitor *mon, const QDict *qdict);
+void hmp_device_add(Monitor *mon, const QDict *qdict);
 void hmp_device_del(Monitor *mon, const QDict *qdict);
 void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict);
 void hmp_netdev_add(Monitor *mon, const QDict *qdict);
diff --git a/monitor.c b/monitor.c
index 4c37203..64e7bd3 100644
--- a/monitor.c
+++ b/monitor.c
@@ -378,8 +378,6 @@ static int GCC_FMT_ATTR(2, 3) monitor_fprintf(FILE *stream,
 return 0;
 }
 
-static void monitor_user_noop(Monitor *mon, const QObject *data) { }
-
 static inline int handler_is_qobject(const mon_cmd_t *cmd)
 {
 return cmd->user_print != NULL;
-- 
1.9.3




Re: [Qemu-devel] Announcing qboot, a minimal x86 firmware for QEMU

2015-05-22 Thread Markus Armbruster
Peter Maydell  writes:

> On 22 May 2015 at 12:12, Daniel P. Berrange  wrote:
>> Yep, it is hard saying no - but I'd think as long as it was possible to add
>> the extra features using -device, it ought to be practical to keep a "virt"
>> machine types "-nodefaults -nodefconfig" base setup pretty minimal.
>
> Mmm, but -device only works for pluggable devices really. We don't
> have a coherent mechanism for saying "put the PS/2 keyboard controller
> into the system at its usual IO ports" on the command line.

... yet.

The qdev long-term vision has always been to support starting with an
empty board, then add device models and their wiring.  Unfortunately,
progress towards that goal has been slow.



[Qemu-devel] [PATCH 15/20] monitor: Rename monitor_control_read(), monitor_control_event()

2015-05-22 Thread Markus Armbruster
... to monitor_qmp_read(), monitor_qmp_event().

Signed-off-by: Markus Armbruster 
---
 monitor.c | 14 --
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/monitor.c b/monitor.c
index ecadda7..977c0fd 100644
--- a/monitor.c
+++ b/monitor.c
@@ -5043,10 +5043,7 @@ err_out:
 QDECREF(args);
 }
 
-/**
- * monitor_control_read(): Read and handle QMP input
- */
-static void monitor_control_read(void *opaque, const uint8_t *buf, int size)
+static void monitor_qmp_read(void *opaque, const uint8_t *buf, int size)
 {
 Monitor *old_mon = cur_mon;
 
@@ -5111,10 +5108,7 @@ static QObject *get_qmp_greeting(void)
 return qobject_from_jsonf("{'QMP':{'version': %p,'capabilities': 
[]}}",ver);
 }
 
-/**
- * monitor_control_event(): Print QMP gretting
- */
-static void monitor_control_event(void *opaque, int event)
+static void monitor_qmp_event(void *opaque, int event)
 {
 QObject *data;
 Monitor *mon = opaque;
@@ -5264,8 +5258,8 @@ void monitor_init(CharDriverState *chr, int flags)
 if (monitor_ctrl_mode(mon)) {
 mon->mc = g_malloc0(sizeof(MonitorControl));
 /* Control mode requires special handlers */
-qemu_chr_add_handlers(chr, monitor_can_read, monitor_control_read,
-  monitor_control_event, mon);
+qemu_chr_add_handlers(chr, monitor_can_read, monitor_qmp_read,
+  monitor_qmp_event, mon);
 qemu_chr_fe_set_echo(chr, true);
 
 json_message_parser_init(&mon->mc->parser, handle_qmp_command);
-- 
1.9.3




[Qemu-devel] [PATCH 18/20] monitor: Turn int command_mode into bool in_command_mode

2015-05-22 Thread Markus Armbruster
Signed-off-by: Markus Armbruster 
---
 monitor.c | 23 ---
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/monitor.c b/monitor.c
index 6e9cc8c..f31a05d 100644
--- a/monitor.c
+++ b/monitor.c
@@ -164,7 +164,12 @@ struct MonFdset {
 typedef struct {
 QObject *id;
 JSONMessageParser parser;
-int command_mode;
+/*
+ * When a client connects, we're in capabilities negotiation mode.
+ * When command qmp_capabilities succeeds, we go into command
+ * mode.
+ */
+bool in_command_mode;   /* are we in command mode? */
 } MonitorQMP;
 
 /*
@@ -226,11 +231,6 @@ Monitor *default_mon;
 static void monitor_command_cb(void *opaque, const char *cmdline,
void *readline_opaque);
 
-static inline int qmp_cmd_mode(const Monitor *mon)
-{
-return mon->qmp.command_mode;
-}
-
 /* Return true if in control mode, false otherwise */
 static inline int monitor_ctrl_mode(const Monitor *mon)
 {
@@ -446,7 +446,7 @@ static void monitor_qapi_event_emit(QAPIEvent event, 
QObject *data)
 
 trace_monitor_protocol_event_emit(event, data);
 QLIST_FOREACH(mon, &mon_list, entry) {
-if (monitor_ctrl_mode(mon) && qmp_cmd_mode(mon)) {
+if (monitor_ctrl_mode(mon) && mon->qmp.in_command_mode) {
 monitor_json_emitter(mon, data);
 }
 }
@@ -566,7 +566,7 @@ static void monitor_qapi_event_init(void)
 static int do_qmp_capabilities(Monitor *mon, const QDict *params,
QObject **ret_data)
 {
-mon->qmp.command_mode = 1;
+mon->qmp.in_command_mode = true;
 return 0;
 }
 
@@ -4701,13 +4701,14 @@ static int monitor_can_read(void *opaque)
 static bool invalid_qmp_mode(const Monitor *mon, const mon_cmd_t *cmd)
 {
 bool is_cap = cmd->mhandler.cmd_new == do_qmp_capabilities;
-if (is_cap && qmp_cmd_mode(mon)) {
+
+if (is_cap && mon->qmp.in_command_mode) {
 qerror_report(ERROR_CLASS_COMMAND_NOT_FOUND,
   "Capabilities negotiation is already complete, command "
   "'%s' ignored", cmd->name);
 return true;
 }
-if (!is_cap && !qmp_cmd_mode(mon)) {
+if (!is_cap && !mon->qmp.in_command_mode) {
 qerror_report(ERROR_CLASS_COMMAND_NOT_FOUND,
   "Expecting capabilities negotiation with "
   "'qmp_capabilities' before command '%s'", cmd->name);
@@ -5111,7 +5112,7 @@ static void monitor_qmp_event(void *opaque, int event)
 
 switch (event) {
 case CHR_EVENT_OPENED:
-mon->qmp.command_mode = 0;
+mon->qmp.in_command_mode = false;
 data = get_qmp_greeting();
 monitor_json_emitter(mon, data);
 qobject_decref(data);
-- 
1.9.3




[Qemu-devel] [PATCH 19/20] monitor: Rename monitor_ctrl_mode() to monitor_is_qmp()

2015-05-22 Thread Markus Armbruster
... and change return type to bool.

Signed-off-by: Markus Armbruster 
---
 monitor.c | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/monitor.c b/monitor.c
index f31a05d..2bdde35 100644
--- a/monitor.c
+++ b/monitor.c
@@ -231,8 +231,10 @@ Monitor *default_mon;
 static void monitor_command_cb(void *opaque, const char *cmdline,
void *readline_opaque);
 
-/* Return true if in control mode, false otherwise */
-static inline int monitor_ctrl_mode(const Monitor *mon)
+/**
+ * Is @mon a QMP monitor?
+ */
+static inline bool monitor_is_qmp(const Monitor *mon)
 {
 return (mon->flags & MONITOR_USE_CONTROL);
 }
@@ -240,7 +242,7 @@ static inline int monitor_ctrl_mode(const Monitor *mon)
 /* Return non-zero iff we have a current monitor, and it is in QMP mode.  */
 int monitor_cur_is_qmp(void)
 {
-return cur_mon && monitor_ctrl_mode(cur_mon);
+return cur_mon && monitor_is_qmp(cur_mon);
 }
 
 void monitor_read_command(Monitor *mon, int show_prompt)
@@ -350,7 +352,7 @@ void monitor_vprintf(Monitor *mon, const char *fmt, va_list 
ap)
 if (!mon)
 return;
 
-if (monitor_ctrl_mode(mon)) {
+if (monitor_is_qmp(mon)) {
 return;
 }
 
@@ -446,7 +448,7 @@ static void monitor_qapi_event_emit(QAPIEvent event, 
QObject *data)
 
 trace_monitor_protocol_event_emit(event, data);
 QLIST_FOREACH(mon, &mon_list, entry) {
-if (monitor_ctrl_mode(mon) && mon->qmp.in_command_mode) {
+if (monitor_is_qmp(mon) && mon->qmp.in_command_mode) {
 monitor_json_emitter(mon, data);
 }
 }
-- 
1.9.3




[Qemu-devel] [PATCH 07/20] monitor: Use trad. command interface for HMP pcie_aer_inject_error

2015-05-22 Thread Markus Armbruster
All QMP commands use the "new" handler interface (mhandler.cmd_new).
Most HMP commands still use the traditional interface (mhandler.cmd),
but a few use the "new" one.  Complicates handle_user_command() for no
gain, so I'm converting these to the traditional interface.

pcie_aer_inject_error's implementation is split into the
hmp_pcie_aer_inject_error() and pcie_aer_inject_error_print().  The
former is a peculiar crossbreed between HMP and QMP handler.  On
success, it works like a QMP handler: store QDict through ret_data
parameter, return 0.  Printing the QDict is left to
pcie_aer_inject_error_print().  On failure, it works more like an HMP
handler: print error to monitor, return negative number.

To convert to the traditional interface, turn
pcie_aer_inject_error_print() into a command handler wrapping around
hmp_pcie_aer_inject_error().  By convention, this command handler
should be called hmp_pcie_aer_inject_error(), so rename the existing
hmp_pcie_aer_inject_error() to do_pcie_aer_inject_error().

Signed-off-by: Markus Armbruster 
---
 hmp-commands.hx |  3 +--
 hw/pci/pci-stub.c   | 14 +-
 hw/pci/pcie_aer.c   | 39 ++-
 include/sysemu/sysemu.h |  4 +---
 4 files changed, 25 insertions(+), 35 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 7776f16..0084114 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1184,8 +1184,7 @@ ETEXI
   " = error string or 32bit\n\t\t\t"
   " = 32bit x 4\n\t\t\t"
   " = 32bit x 4",
-.user_print  = pcie_aer_inject_error_print,
-.mhandler.cmd_new = hmp_pcie_aer_inject_error,
+.mhandler.cmd = hmp_pcie_aer_inject_error,
 },
 
 STEXI
diff --git a/hw/pci/pci-stub.c b/hw/pci/pci-stub.c
index 5e564c3..f8f237e 100644
--- a/hw/pci/pci-stub.c
+++ b/hw/pci/pci-stub.c
@@ -29,19 +29,7 @@ PciInfoList *qmp_query_pci(Error **errp)
 return NULL;
 }
 
-static void pci_error_message(Monitor *mon)
+void hmp_pcie_aer_inject_error(Monitor *mon, const QDict *qdict)
 {
 monitor_printf(mon, "PCI devices not supported\n");
 }
-
-int hmp_pcie_aer_inject_error(Monitor *mon,
- const QDict *qdict, QObject **ret_data)
-{
-pci_error_message(mon);
-return -ENOSYS;
-}
-
-void pcie_aer_inject_error_print(Monitor *mon, const QObject *data)
-{
-pci_error_message(mon);
-}
diff --git a/hw/pci/pcie_aer.c b/hw/pci/pcie_aer.c
index b48c09c..c8dea8e 100644
--- a/hw/pci/pcie_aer.c
+++ b/hw/pci/pcie_aer.c
@@ -815,21 +815,6 @@ const VMStateDescription vmstate_pcie_aer_log = {
 }
 };
 
-void pcie_aer_inject_error_print(Monitor *mon, const QObject *data)
-{
-QDict *qdict;
-int devfn;
-assert(qobject_type(data) == QTYPE_QDICT);
-qdict = qobject_to_qdict(data);
-
-devfn = (int)qdict_get_int(qdict, "devfn");
-monitor_printf(mon, "OK id: %s root bus: %s, bus: %x devfn: %x.%x\n",
-   qdict_get_str(qdict, "id"),
-   qdict_get_str(qdict, "root_bus"),
-   (int) qdict_get_int(qdict, "bus"),
-   PCI_SLOT(devfn), PCI_FUNC(devfn));
-}
-
 typedef struct PCIEAERErrorName {
 const char *name;
 uint32_t val;
@@ -962,8 +947,8 @@ static int pcie_aer_parse_error_string(const char 
*error_name,
 return -EINVAL;
 }
 
-int hmp_pcie_aer_inject_error(Monitor *mon,
- const QDict *qdict, QObject **ret_data)
+static int do_pcie_aer_inject_error(Monitor *mon,
+const QDict *qdict, QObject **ret_data)
 {
 const char *id = qdict_get_str(qdict, "id");
 const char *error_name;
@@ -1035,3 +1020,23 @@ int hmp_pcie_aer_inject_error(Monitor *mon,
 
 return 0;
 }
+
+void hmp_pcie_aer_inject_error(Monitor *mon, const QDict *qdict)
+{
+QObject *data;
+int devfn;
+
+if (do_pcie_aer_inject_error(mon, qdict, &data) < 0) {
+return;
+}
+
+assert(qobject_type(data) == QTYPE_QDICT);
+qdict = qobject_to_qdict(data);
+
+devfn = (int)qdict_get_int(qdict, "devfn");
+monitor_printf(mon, "OK id: %s root bus: %s, bus: %x devfn: %x.%x\n",
+   qdict_get_str(qdict, "id"),
+   qdict_get_str(qdict, "root_bus"),
+   (int) qdict_get_int(qdict, "bus"),
+   PCI_SLOT(devfn), PCI_FUNC(devfn));
+}
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 8a52934..e10c2c5 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -161,9 +161,7 @@ extern unsigned int nb_prom_envs;
 void hmp_drive_add(Monitor *mon, const QDict *qdict);
 
 /* pcie aer error injection */
-void pcie_aer_inject_error_print(Monitor *mon, const QObject *data);
-int hmp_pcie_aer_inject_error(Monitor *mon,
- const QDict *qdict, QObject **ret_data);
+void hmp_pcie_aer_inject_error(Monitor *mon, const QDict *qdict);
 
 /* serial ports */
 
-- 
1.9.3




  1   2   3   >