Re: [Qemu-devel] qemu qmp [info usb] and [info hostusb]

2014-07-14 Thread Markus Armbruster
Pascal Heinrich  writes:

> Hi,
>
> I am trying to implement a qtprogram to bind and unbind usb devices from
> an qemu instance.
>
> Via device_add I am able to bind a device to the vm but there is no
> command in qmp to list binded devices or I do not find them.
>
> I am searching for something like >"query-usb"<
>
> Is there something implemented like that?

In the human monitor, there's "info qtree", but programs really should
use QMP.  It provides qom-list and qom-get, but that's rather low level.
Andreas, any further advice?



Re: [Qemu-devel] [PULL 3/3] cirrus: Fix host CPU blits

2014-07-14 Thread Peter Lieven

Hi Benjamin,

On 11.07.2014 12:24, Gerd Hoffmann wrote:

From: Benjamin Herrenschmidt 

Commit b2eb849d4b1fdb6f35d5c46958c7f703cf64cfef
"CVE-2007-1320 - Cirrus LGD-54XX "bitblt" heap overflow" broke
cpu to video blits.

When the ROP function is called from cirrus_bitblt_cputovideo_next(),
we pass 0 for the pitch but only operate on one line at a time. The
added test was tripping because after the initial substraction, the
pitch becomes negative. Make the test only trip when the height is
larger than one (ie. the pitch is actually used).

This fixes HW cursor support in Windows NT4.0 (which otherwise was
a white rectangle) and general display of icons in that OS when using
8bpp mode.

Signed-off-by: Benjamin Herrenschmidt 
Signed-off-by: Gerd Hoffmann 
---
  hw/display/cirrus_vga_rop.h | 3 +--
  1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/hw/display/cirrus_vga_rop.h b/hw/display/cirrus_vga_rop.h
index 9c7bb09..0925a00 100644
--- a/hw/display/cirrus_vga_rop.h
+++ b/hw/display/cirrus_vga_rop.h
@@ -52,8 +52,7 @@ glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *s,
  dstpitch -= bltwidth;
  srcpitch -= bltwidth;
  
-if (dstpitch < 0 || srcpitch < 0) {

-/* is 0 valid? srcpitch == 0 could be useful */
+if (bltheight > 1 && (dstpitch < 0 || srcpitch < 0)) {
  return;
  }
  


it seems you have digged into the cirrus code recently. Have you an idea how to
fix the issue with the graphics corruption for cirrus vga and recent X Server 
versions?

E.g. take an Ubuntu 14.04 Desktop CD, boot it into live mode and open terminal.

I have tried to debug it a little, but I have no clue how to solve this. I 
tried to get
hands on a real hardware Cirrus Logic Graphics card and test if this happens 
there as well,
but I had no chance to get one.

Peter




[Qemu-devel] [PULL for-2.1 1/1] s390x/kvm: synchronize guest floating point registers

2014-07-14 Thread Cornelia Huck
From: "Jason J. Herne" 

Add code to kvm_arch_get_registers and kvm_arch_put_registers to
save/restore floating point registers. This missing sync was
unnoticed until migration of userspace that uses fprs.

Signed-off-by: Jason J. Herne 
Signed-off-by: Christian Borntraeger 
[Update patch to latest upstream]
Cc: qemu-sta...@nongnu.org
Reviewed-by: Alexander Graf 
Signed-off-by: Cornelia Huck 
---
 target-s390x/kvm.c |   23 +++
 1 file changed, 23 insertions(+)

diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index a6e587b..a32d91a 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -207,6 +207,7 @@ int kvm_arch_put_registers(CPUState *cs, int level)
 CPUS390XState *env = &cpu->env;
 struct kvm_sregs sregs;
 struct kvm_regs regs;
+struct kvm_fpu fpu;
 int r;
 int i;
 
@@ -229,6 +230,17 @@ int kvm_arch_put_registers(CPUState *cs, int level)
 }
 }
 
+/* Floating point */
+for (i = 0; i < 16; i++) {
+fpu.fprs[i] = env->fregs[i].ll;
+}
+fpu.fpc = env->fpc;
+
+r = kvm_vcpu_ioctl(cs, KVM_SET_FPU, &fpu);
+if (r < 0) {
+return r;
+}
+
 /* Do we need to save more than that? */
 if (level == KVM_PUT_RUNTIME_STATE) {
 return 0;
@@ -296,6 +308,7 @@ int kvm_arch_get_registers(CPUState *cs)
 CPUS390XState *env = &cpu->env;
 struct kvm_sregs sregs;
 struct kvm_regs regs;
+struct kvm_fpu fpu;
 int i, r;
 
 /* get the PSW */
@@ -336,6 +349,16 @@ int kvm_arch_get_registers(CPUState *cs)
 }
 }
 
+/* Floating point */
+r = kvm_vcpu_ioctl(cs, KVM_GET_FPU, &fpu);
+if (r < 0) {
+return r;
+}
+for (i = 0; i < 16; i++) {
+env->fregs[i].ll = fpu.fprs[i];
+}
+env->fpc = fpu.fpc;
+
 /* The prefix */
 if (cap_sync_regs && cs->kvm_run->kvm_valid_regs & KVM_SYNC_PREFIX) {
 env->psa = cs->kvm_run->s.regs.prefix;
-- 
1.7.9.5




[Qemu-devel] [PULL for-2.1 0/1] s390x/kvm: bugfix

2014-07-14 Thread Cornelia Huck
The following changes since commit ab6d3749c4915cd5692633e321f7745dce06fe77:

  Merge remote-tracking branch 'remotes/kraxel/tags/pull-vga-20140711-1' into 
staging (2014-07-11 17:50:38 +0100)

are available in the git repository at:


  git://github.com/cohuck/qemu.git tags/s390x-20140714

for you to fetch changes up to 85ad6230b3af048109b3e949ca95ade4dd9a0bfa:

  s390x/kvm: synchronize guest floating point registers (2014-07-14 09:15:38 
+0200)


A s390x/kvm bugfix for missing floating point register synchronization.


Jason J. Herne (1):
  s390x/kvm: synchronize guest floating point registers

 target-s390x/kvm.c |   23 +++
 1 file changed, 23 insertions(+)

-- 
1.7.9.5




Re: [Qemu-devel] [PULL 3/3] cirrus: Fix host CPU blits

2014-07-14 Thread Benjamin Herrenschmidt
On Mon, 2014-07-14 at 09:24 +0200, Peter Lieven wrote:
> it seems you have digged into the cirrus code recently. Have you an idea how 
> to
> fix the issue with the graphics corruption for cirrus vga and recent X Server 
> versions?
> 
> E.g. take an Ubuntu 14.04 Desktop CD, boot it into live mode and open 
> terminal.
> 
> I have tried to debug it a little, but I have no clue how to solve this. I 
> tried to get
> hands on a real hardware Cirrus Logic Graphics card and test if this happens 
> there as well,
> but I had no chance to get one.

I *think* it is a X server side bug. They broke 24bpp packed pixel
format. I've seen patches submitted to the Xorg list fairly recently by
somebody from canonical.

You can test by creating an xorg.conf to force the display to 16bpp
instead of 24 and see if that helps.

Cheers,
Ben.





Re: [Qemu-devel] [PULL 3/3] cirrus: Fix host CPU blits

2014-07-14 Thread Benjamin Herrenschmidt
On Mon, 2014-07-14 at 17:29 +1000, Benjamin Herrenschmidt wrote:
> On Mon, 2014-07-14 at 09:24 +0200, Peter Lieven wrote:
> > it seems you have digged into the cirrus code recently. Have you an idea 
> > how to
> > fix the issue with the graphics corruption for cirrus vga and recent X 
> > Server versions?
> > 
> > E.g. take an Ubuntu 14.04 Desktop CD, boot it into live mode and open 
> > terminal.
> > 
> > I have tried to debug it a little, but I have no clue how to solve this. I 
> > tried to get
> > hands on a real hardware Cirrus Logic Graphics card and test if this 
> > happens there as well,
> > but I had no chance to get one.
> 
> I *think* it is a X server side bug. They broke 24bpp packed pixel
> format. I've seen patches submitted to the Xorg list fairly recently by
> somebody from canonical.
> 
> You can test by creating an xorg.conf to force the display to 16bpp
> instead of 24 and see if that helps.

Look for patches from "Robert Ancell " on
the xorg-devel list. In fact I'd suggest you test and report if that
works for you, that might give Keithp an incentive for actually merging
them :-)

Cheers,
Ben.





[Qemu-devel] [Bug 1307473] Re: guest hang due to missing clock interrupt

2014-07-14 Thread Ondergetekende
We've resolved our issues by disabling KSM on the affected nodes. All of
the non-affected nodes didn't have KSM enabled (due to a packaging bug
elsewhere). After disabling KSM, our problems went away gradually in ~3
days.

This means we're no longer affected by this issue (and given the other
reports, probably never were).

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

Title:
  guest hang due to missing clock interrupt

Status in QEMU:
  New
Status in “linux” package in Ubuntu:
  Confirmed
Status in “qemu” package in Ubuntu:
  Confirmed

Bug description:
  
  I noticed on 2 different systems that after upgrade from precise to latest 
trusty VMs are crashing:

  - in case of Windows VMs I'm getting BSOD with error message: "A clock 
interrupt was not received on a secondary processor within the allocated time 
interval."
  - On linux VMs I'm noticing "hrtimer: interrupt took 2992229 ns" messages 
  - On some proprietary virtual appliances I'm noticing crashes an due to 
missing timer interrupts

  QEMU version is:
  QEMU emulator version 1.7.91 (Debian 2.0.0~rc1+dfsg-0ubuntu3)

  Full command line:

  qemu-system-x86_64 -enable-kvm -name win7eval -S -machine pc-
  i440fx-1.7,accel=kvm,usb=off -cpu host -m 4096 -realtime mlock=off
  -smp 4,sockets=1,cores=4,threads=1 -uuid 05e5089a-
  4aa1-6bb2-ef06-ab4d020a -no-user-config -nodefaults -chardev
  
socket,id=charmonitor,path=/var/lib/libvirt/qemu/win7eval.monitor,server,nowait
  -mon chardev=charmonitor,id=monitor,mode=control -rtc base=localtime
  -no-shutdown -boot strict=on -device piix3-usb-
  uhci,id=usb,bus=pci.0,addr=0x1.0x2 -drive
  file=/var/vm/win7eval.qcow2,if=none,id=drive-virtio-disk0,format=qcow2
  -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x4,drive=drive-virtio-
  disk0,id=virtio-disk0,bootindex=1 -drive
  file=/home/damarion/iso/7600.16385.090713-1255_x86fre_enterprise_en-
  us_EVAL_Eval_Enterprise-GRMCENEVAL_EN_DVD.iso,if=none,id=drive-
  ide0-0-0,readonly=on,format=raw -device ide-cd,bus=ide.0,unit=0,drive
  =drive-ide0-0-0,id=ide0-0-0 -drive file=/home/damarion/iso/virtio-
  win-0.1-74.iso,if=none,id=drive-ide0-1-0,readonly=on,format=raw
  -device ide-cd,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0
  -netdev tap,fd=24,id=hostnet0 -device
  e1000,netdev=hostnet0,id=net0,mac=52:54:00:38:31:0a,bus=pci.0,addr=0x3
  -chardev pty,id=charserial0 -device isa-
  serial,chardev=charserial0,id=serial0 -device usb-tablet,id=input0
  -vnc 127.0.0.1:1 -device VGA,id=video0,bus=pci.0,addr=0x2 -device
  virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5

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



Re: [Qemu-devel] [PATCH v2 for-2.1] linux-aio: Fix laio resource leak

2014-07-14 Thread Stefan Hajnoczi
On Sat, Jul 12, 2014 at 11:43:37AM +0800, arei.gong...@huawei.com wrote:
> From: Gonglei 
> 
> when hotplug virtio-scsi disks using laio, the aio_nr will
> increase in laio_init() by io_setup(), we can see the number by
>   # cat /proc/sys/fs/aio-nr
>   128
> if the aio_nr attach the maxnum, which found from
>   # cat /proc/sys/fs/aio-max-nr
>   65536
> the hotplug process will fail because of aio context leak.
> 
> Fix it by io_destroy in laio_cleanup().
> 
> Reported-by: daifulai 
> Signed-off-by: Gonglei 
> ---
>  v2: small spelling fixes.
> ---
>  block/linux-aio.c | 5 +
>  1 file changed, 5 insertions(+)

Thanks, applied to my block tree:
https://github.com/stefanha/qemu/commits/block

Stefan


pgppA2FWXDw6U.pgp
Description: PGP signature


Re: [Qemu-devel] [PATCH] qom: Make object_child_foreach safe for objects removal

2014-07-14 Thread Paolo Bonzini

Il 13/07/2014 16:41, Alexey Kardashevskiy ha scritto:

Current object_child_foreach() uses QTAILQ_FOREACH() to walk
through children and that makes children removal from the callback
impossible.

This makes object_child_foreach() use QTAILQ_FOREACH_SAFE().

Signed-off-by: Alexey Kardashevskiy 
---

The problem I am trying to solve is:
there is a PHB with multiple DMA windows a.k.a. sPAPRTCETable's which are
QOM children of PHB. One of RTAS functions is "reset" which is supposed to
remove all windows (now just one) except the default one.

I could call QTAILQ_FOREACH_SAFE in sPAPR PHB code but 
object_property_is_child()
is static and we probably do not want to make it public.


---
 qom/object.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/qom/object.c b/qom/object.c
index 0e8267b..4a814dc 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -678,10 +678,10 @@ void object_class_foreach(void (*fn)(ObjectClass *klass, 
void *opaque),
 int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque),
  void *opaque)
 {
-ObjectProperty *prop;
+ObjectProperty *prop, *next;
 int ret = 0;

-QTAILQ_FOREACH(prop, &obj->properties, node) {
+QTAILQ_FOREACH_SAFE(prop, &obj->properties, node, next) {
 if (object_property_is_child(prop)) {
 ret = fn(prop->opaque, opaque);
 if (ret != 0) {



The patch is certainly okay, do you need it in 2.1?

Paolo



Re: [Qemu-devel] [PULL 3/3] cirrus: Fix host CPU blits

2014-07-14 Thread Peter Lieven

On 14.07.2014 09:29, Benjamin Herrenschmidt wrote:

On Mon, 2014-07-14 at 09:24 +0200, Peter Lieven wrote:

it seems you have digged into the cirrus code recently. Have you an idea how to
fix the issue with the graphics corruption for cirrus vga and recent X Server 
versions?

E.g. take an Ubuntu 14.04 Desktop CD, boot it into live mode and open terminal.

I have tried to debug it a little, but I have no clue how to solve this. I 
tried to get
hands on a real hardware Cirrus Logic Graphics card and test if this happens 
there as well,
but I had no chance to get one.

I *think* it is a X server side bug. They broke 24bpp packed pixel
format. I've seen patches submitted to the Xorg list fairly recently by
somebody from canonical.

You can test by creating an xorg.conf to force the display to 16bpp
instead of 24 and see if that helps.


Will do, thanks for the pointer.

Do you see a way to work around this in the graphics driver. E.g. blacklisting 
24bpp modes
etc. Even if X.Org people actually merge the fixes there are 2 years of Linux 
releases out
there that have corrupted graphics.

Peter




Re: [Qemu-devel] [PATCH v1 resend 0/2] virtio-blk: dataplane: one fix plus one optimization

2014-07-14 Thread Stefan Hajnoczi
On Sat, Jul 12, 2014 at 12:08:51PM +0800, Ming Lei wrote:
> Hi,
> 
> The first one fixes one problem introduced recently.
> 
> The second one suppresses notifications to guest a lot.
> 
> V1:
>   - use BH to suppress notifications to guest as suggested by Paolo

Thanks, applied to my block tree:
https://github.com/stefanha/qemu/commits/block

Stefan


pgpqQCaCyt07s.pgp
Description: PGP signature


Re: [Qemu-devel] [PATCH for-2.1? 2/2] thread-pool: avoid deadlock in nested aio_poll() calls

2014-07-14 Thread Paolo Bonzini

Il 11/07/2014 13:20, Stefan Hajnoczi ha scritto:

The thread pool has a race condition if two elements complete before
thread_pool_completion_bh() runs:

  If element A's callback waits for element B using aio_poll() it will
  deadlock since pool->completion_bh is not marked scheduled when the
  nested aio_poll() runs.

Fix this by marking the BH scheduled while thread_pool_completion_bh()
is executing.  This way any nested aio_poll() loops will enter
thread_pool_completion_bh() and complete the remaining elements.

Signed-off-by: Stefan Hajnoczi 
---
 thread-pool.c | 27 +--
 1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/thread-pool.c b/thread-pool.c
index 4cfd078..0ede168 100644
--- a/thread-pool.c
+++ b/thread-pool.c
@@ -65,6 +65,9 @@ struct ThreadPool {
 int max_threads;
 QEMUBH *new_thread_bh;

+/* Atomic counter to detect completions while completion handler runs */
+uint32_t completion_token;
+
 /* The following variables are only accessed from one AioContext. */
 QLIST_HEAD(, ThreadPoolElement) head;

@@ -118,6 +121,7 @@ static void *worker_thread(void *opaque)
 qemu_cond_broadcast(&pool->check_cancel);
 }

+atomic_inc(&pool->completion_token);
 qemu_bh_schedule(pool->completion_bh);
 }

@@ -167,9 +171,8 @@ static void spawn_thread(ThreadPool *pool)
 }
 }

-static void thread_pool_completion_bh(void *opaque)
+static void thread_pool_complete_elements(ThreadPool *pool)
 {
-ThreadPool *pool = opaque;
 ThreadPoolElement *elem, *next;

 restart:
@@ -196,6 +199,26 @@ restart:
 }
 }

+static void thread_pool_completion_bh(void *opaque)
+{
+ThreadPool *pool = opaque;
+uint32_t token;
+
+do {
+token = atomic_mb_read(&pool->completion_token);
+
+/* Stay scheduled in case elem->common.cb() makes a nested aio_poll()
+ * call.  This avoids deadlock if element A's callback waits for
+ * element B and both completed at the same time.
+ */
+qemu_bh_schedule(pool->completion_bh);
+
+thread_pool_complete_elements(pool);
+
+qemu_bh_cancel(pool->completion_bh);
+} while (token != pool->completion_token);
+}
+
 static void thread_pool_cancel(BlockDriverAIOCB *acb)
 {
 ThreadPoolElement *elem = (ThreadPoolElement *)acb;



I am not sure I understand this patch.

The simplest way to fix deadlock is to change this in 
thread_pool_completion_bh:


elem->common.cb(elem->common.opaque, elem->ret);
qemu_aio_release(elem);
goto restart;

to

/* In case elem->common.cb() makes a nested aio_poll() call,
 * next may become invalid as well.  Instead of just
 * restarting the QLIST_FOREACH_SAFE, go through the BH
 * once more, which also avoids deadlock if element A's
 * callback waits for element B and both completed at the
 * same time.
 */
qemu_bh_schedule(pool->completion_bh);
elem->common.cb(elem->common.opaque, elem->ret);
qemu_aio_release(elem);

There is no change in logic, it's just that the goto is switched to a BH 
representing a continuation.  I am then not sure why 
pool->completion_token is necessary?


Perhaps it is just an optimization to avoid going multiple times around 
aio_poll()?


Paolo



Re: [Qemu-devel] [PATCH] Tap: fix vcpu long time io blocking on tap

2014-07-14 Thread Stefan Hajnoczi
On Mon, Jul 14, 2014 at 01:55:05AM +, Wangkai (Kevin,C) wrote:
> 
> 
> > -Original Message-
> > From: Stefan Hajnoczi [mailto:stefa...@redhat.com]
> > Sent: Friday, July 11, 2014 9:04 PM
> > To: Wangkai (Kevin,C)
> > Cc: qemu-devel@nongnu.org; aligu...@amazon.com; Lee yang
> > Subject: Re: [PATCH] Tap: fix vcpu long time io blocking on tap
> > 
> > On Fri, Jul 11, 2014 at 01:05:30AM +, Wangkai (Kevin,C) wrote:
> > > When used a tap as net driver for vm, if too many packets was
> > > delivered to the guest os via tap interface, the guest os will be
> > > blocked on io events for a long time, while tap driver was busying
> > process packets.
> > >
> > > kvm vcpu thread block on io lock call trace:
> > >   __lll_lock_wait
> > >   _L_lock_1004
> > >   __pthread_mutex_lock
> > >   qemu_mutex_lock
> > >   kvm_cpu_exec
> > >   qemu_kvm_cpu_thread_fn
> > >   start_thread
> > >
> > > qemu io thread call trace:
> > >   ...
> > >   qemu_net_queue_send
> > >   tap_send
> > >   qemu_iohandler_poll
> > >   main_loop_wait
> > >   main_loop
> > >
> > >
> > > I think the qemu io lock time should be as small as possible, and the
> > > io work slice should be limited at a particular ration or time.
> > >
> > > ---
> > > Signed-off-by: Wangkai 
> > 
> > How many packets are you seeing in a single tap_send() call?
> > 
> > Have you profiled the tap_send() code path?  Maybe it is performing
> > some operation that is very slow.
> > 
> > By the way, if you want good performance you should use vhost_net
> > instead of userspace vhost_net.  Userspace virtio-net is not very
> > optimized.
> > 
> > Stefan
> 
> 
> Hi Stefan,
> 
> I am not use profile, just debug with gdb and code review.

It's worth understanding the root cause for this behavior because
something is probably wrong.

> When packets delivered, I found the VM was hung, and I check qemu run
> 
> State by gdb, I see the call trace for IO thread and vcpu thread, and
> 
> I add debug info to check how many packets within tap_send, the info below:
> 
> total recv 393520 time 1539821 us 
> total recv 1270 time 4931 us
> total recv 257872 time 995828 us 
> total recv 10745 time 41438 us
> total recv 505387 time 2000925 us

505387 packets or 505387 bytes?

If that's packets, then even with small 64-byte packets that would mean
32 MB of pending data!

Are you running a networking benchmark where you'd expect lots of
packets?

Have you checked how lot the time between tap_send() calls is?  Perhaps
something else in QEMU is blocking the event loop so packets accumulate
in the host kernel.

Stefan


pgpuAR_aSa7hS.pgp
Description: PGP signature


Re: [Qemu-devel] [PATCH 3/4 v7] ppc: Add software breakpoint support

2014-07-14 Thread bharat.bhus...@freescale.com


> -Original Message-
> From: Madhavan Srinivasan [mailto:ma...@linux.vnet.ibm.com]
> Sent: Friday, July 11, 2014 10:51 AM
> To: Bhushan Bharat-R65777; ag...@suse.de
> Cc: qemu-...@nongnu.org; qemu-devel@nongnu.org
> Subject: Re: [PATCH 3/4 v7] ppc: Add software breakpoint support
> 
> On Thursday 10 July 2014 07:49 PM, Bharat Bhushan wrote:
> > This patch allow insert/remove software breakpoint.
> >
> > When QEMU is not able to handle debug exception then we inject program
> > exception to guest because for software breakpoint QEMU uses a
> > ehpriv-1 instruction; So there cannot be any reason that we are in
> > qemu with exit reason KVM_EXIT_DEBUG  for guest set debug exception,
> > only possibility is guest executed ehpriv-1 privilege instruction and
> > that's why we are injecting program exception.
> >
> > Signed-off-by: Bharat Bhushan 
> > ---
> > v6->v7
> >  - Moved exception injection to this patch
> >  - Inject the fault directly
> >
> >  target-ppc/kvm.c | 87
> > +++-
> >  1 file changed, 73 insertions(+), 14 deletions(-)
> >
> > diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c index
> > e00a20f..afa2291 100644
> > --- a/target-ppc/kvm.c
> > +++ b/target-ppc/kvm.c
> > @@ -1275,6 +1275,69 @@ static int kvmppc_handle_dcr_write(CPUPPCState *env,
> uint32_t dcrn, uint32_t dat
> >  return 0;
> >  }
> >
> > +int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct
> > +kvm_sw_breakpoint *bp) {
> > +/* Mixed endian case is not handled */
> > +uint32_t sc = debug_inst_opcode;
> > +
> > +if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn,
> > +sizeof(sc), 0) ||
> > +cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&sc, sizeof(sc), 1)) {
> > +return -EINVAL;
> > +}
> > +
> > +return 0;
> > +}
> > +
> > +int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct
> > +kvm_sw_breakpoint *bp) {
> > +uint32_t sc;
> > +
> > +if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&sc, sizeof(sc), 0) ||
> > +sc != debug_inst_opcode ||
> > +cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn,
> > +sizeof(sc), 1)) {
> > +return -EINVAL;
> > +}
> > +
> > +return 0;
> > +}
> > +
> > +void kvm_arch_update_guest_debug(CPUState *cs, struct kvm_guest_debug
> > +*dbg) {
> > +/* Software Breakpoint updates */
> > +if (kvm_sw_breakpoints_active(cs)) {
> > +dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP;
> > +}
> > +}
> > +
> > +static int kvm_handle_debug(PowerPCCPU *cpu, struct kvm_run *run) {
> > +CPUState *cs = CPU(cpu);
> > +CPUPPCState *env = &cpu->env;
> > +struct kvm_debug_exit_arch *arch_info = &run->debug.arch;
> > +int handle = 0;
> > +
> > +if (kvm_find_sw_breakpoint(cs, arch_info->address)) {
> > +handle = 1;
> > +} else {
> > +/* QEMU is not able to handle debug exception, so inject
> > + * program exception to guest;
> > + * Yes program exception NOT debug exception !!
> > + * For software breakpoint QEMU uses a ehpriv-1 instruction;
> > + * So there cannot be any reason that we are here for guest
> > + * set debug exception, only possibility is guest executed a
> > + * privilege instruction and that's why we are injecting
> > + * program exception.
> > + */
> > + cs->exception_index = POWERPC_EXCP_PROGRAM;
> > + env->error_code = POWERPC_EXCP_INVAL;
> > + ppc_cpu_do_interrupt(cs);
> > +}
> > +
> 
> Excellent. This is the change I had as part of server side patch for no sw
> breakpoint case. Also have one more addition to this, which I found in the
> debug.
> 
> Only issue in here (using TCG for injecting) is that, KVM gives us PC, but
> incase of TCG, it uses nip. So nip gets decremented in ppc_cpu_do_interrupt
> function ending up sending the wrong pc to guest.

This is a good catch, I did not hit this because of some other issue (srr0/1 
not getting sync properly on Booke-hv.

Thanks
-Bharat


> So Alex suggested to increment the nip by 4 before calling the
> ppc_cpu_do_interrupt function. Also kindly add cpu_synchronize_state before
> calling since we are changing the register values.
> 
> Regards
> Maddy
> 
> > +return handle;
> > +}
> > +
> >  int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)  {
> >  PowerPCCPU *cpu = POWERPC_CPU(cs); @@ -1315,6 +1378,16 @@ int
> > kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
> >  ret = 0;
> >  break;
> >
> > +case KVM_EXIT_DEBUG:
> > +DPRINTF("handle debug exception\n");
> > +if (kvm_handle_debug(cpu, run)) {
> > +ret = EXCP_DEBUG;
> > +break;
> > +}
> > +/* re-enter, this exception was guest-internal */
> > +ret = 0;
> > +break;
> > +
> >  default:
> >  fprintf(stderr, "KVM: unknown e

[Qemu-devel] [PATCH 1/4 v8] ppc: debug stub: Get trap instruction opcode from KVM

2014-07-14 Thread Bharat Bhushan
Get trap instruction opcode from KVM and this opcode will
be used for setting software breakpoint in following patch

Signed-off-by: Bharat Bhushan 
---
v7->v8
 - No change

 target-ppc/kvm.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 2d87108..4df23dd 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -72,6 +72,8 @@ static int cap_papr;
 static int cap_htab_fd;
 static int cap_fixup_hcalls;
 
+static uint32_t debug_inst_opcode;
+
 /* XXX We have a race condition where we actually have a level triggered
  * interrupt, but the infrastructure can't expose that yet, so the guest
  * takes but ignores it, goes to sleep and never gets notified that there's
@@ -436,6 +438,8 @@ int kvm_arch_init_vcpu(CPUState *cs)
 break;
 }
 
+kvm_get_one_reg(cs, KVM_REG_PPC_DEBUG_INST, &debug_inst_opcode);
+
 return ret;
 }
 
-- 
1.9.3




[Qemu-devel] [PATCH 2/4 v8] ppc: synchronize excp_vectors for injecting exception

2014-07-14 Thread Bharat Bhushan
This patch synchronizes env->excp_vectors[] with env->iovr[].
This is required for using the existing interrupt injection mechanism
for kvm.

Signed-off-by: Bharat Bhushan 
---
v7->v8
 - No change

 target-ppc/kvm.c | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 4df23dd..e00a20f 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -903,6 +903,11 @@ int kvm_arch_put_registers(CPUState *cs, int level)
 return ret;
 }
 
+static void kvm_sync_excp(CPUPPCState *env, int vector, int ivor)
+{
+ env->excp_vectors[vector] = env->spr[ivor] + env->spr[SPR_BOOKE_IVPR];
+}
+
 int kvm_arch_get_registers(CPUState *cs)
 {
 PowerPCCPU *cpu = POWERPC_CPU(cs);
@@ -985,35 +990,57 @@ int kvm_arch_get_registers(CPUState *cs)
 
 if (sregs.u.e.features & KVM_SREGS_E_IVOR) {
 env->spr[SPR_BOOKE_IVOR0] = sregs.u.e.ivor_low[0];
+kvm_sync_excp(env, POWERPC_EXCP_CRITICAL,  SPR_BOOKE_IVOR0);
 env->spr[SPR_BOOKE_IVOR1] = sregs.u.e.ivor_low[1];
+kvm_sync_excp(env, POWERPC_EXCP_MCHECK,  SPR_BOOKE_IVOR1);
 env->spr[SPR_BOOKE_IVOR2] = sregs.u.e.ivor_low[2];
+kvm_sync_excp(env, POWERPC_EXCP_DSI,  SPR_BOOKE_IVOR2);
 env->spr[SPR_BOOKE_IVOR3] = sregs.u.e.ivor_low[3];
+kvm_sync_excp(env, POWERPC_EXCP_ISI,  SPR_BOOKE_IVOR3);
 env->spr[SPR_BOOKE_IVOR4] = sregs.u.e.ivor_low[4];
+kvm_sync_excp(env, POWERPC_EXCP_EXTERNAL,  SPR_BOOKE_IVOR4);
 env->spr[SPR_BOOKE_IVOR5] = sregs.u.e.ivor_low[5];
+kvm_sync_excp(env, POWERPC_EXCP_ALIGN,  SPR_BOOKE_IVOR5);
 env->spr[SPR_BOOKE_IVOR6] = sregs.u.e.ivor_low[6];
+kvm_sync_excp(env, POWERPC_EXCP_PROGRAM,  SPR_BOOKE_IVOR6);
 env->spr[SPR_BOOKE_IVOR7] = sregs.u.e.ivor_low[7];
+kvm_sync_excp(env, POWERPC_EXCP_FPU,  SPR_BOOKE_IVOR7);
 env->spr[SPR_BOOKE_IVOR8] = sregs.u.e.ivor_low[8];
+kvm_sync_excp(env, POWERPC_EXCP_SYSCALL,  SPR_BOOKE_IVOR8);
 env->spr[SPR_BOOKE_IVOR9] = sregs.u.e.ivor_low[9];
+kvm_sync_excp(env, POWERPC_EXCP_APU,  SPR_BOOKE_IVOR9);
 env->spr[SPR_BOOKE_IVOR10] = sregs.u.e.ivor_low[10];
+kvm_sync_excp(env, POWERPC_EXCP_DECR,  SPR_BOOKE_IVOR10);
 env->spr[SPR_BOOKE_IVOR11] = sregs.u.e.ivor_low[11];
+kvm_sync_excp(env, POWERPC_EXCP_FIT,  SPR_BOOKE_IVOR11);
 env->spr[SPR_BOOKE_IVOR12] = sregs.u.e.ivor_low[12];
+kvm_sync_excp(env, POWERPC_EXCP_WDT,  SPR_BOOKE_IVOR12);
 env->spr[SPR_BOOKE_IVOR13] = sregs.u.e.ivor_low[13];
+kvm_sync_excp(env, POWERPC_EXCP_DTLB,  SPR_BOOKE_IVOR13);
 env->spr[SPR_BOOKE_IVOR14] = sregs.u.e.ivor_low[14];
+kvm_sync_excp(env, POWERPC_EXCP_ITLB,  SPR_BOOKE_IVOR14);
 env->spr[SPR_BOOKE_IVOR15] = sregs.u.e.ivor_low[15];
+kvm_sync_excp(env, POWERPC_EXCP_DEBUG,  SPR_BOOKE_IVOR15);
 
 if (sregs.u.e.features & KVM_SREGS_E_SPE) {
 env->spr[SPR_BOOKE_IVOR32] = sregs.u.e.ivor_high[0];
+kvm_sync_excp(env, POWERPC_EXCP_SPEU,  SPR_BOOKE_IVOR32);
 env->spr[SPR_BOOKE_IVOR33] = sregs.u.e.ivor_high[1];
+kvm_sync_excp(env, POWERPC_EXCP_EFPDI,  SPR_BOOKE_IVOR33);
 env->spr[SPR_BOOKE_IVOR34] = sregs.u.e.ivor_high[2];
+kvm_sync_excp(env, POWERPC_EXCP_EFPRI,  SPR_BOOKE_IVOR34);
 }
 
 if (sregs.u.e.features & KVM_SREGS_E_PM) {
 env->spr[SPR_BOOKE_IVOR35] = sregs.u.e.ivor_high[3];
+kvm_sync_excp(env, POWERPC_EXCP_EPERFM,  SPR_BOOKE_IVOR35);
 }
 
 if (sregs.u.e.features & KVM_SREGS_E_PC) {
 env->spr[SPR_BOOKE_IVOR36] = sregs.u.e.ivor_high[4];
+kvm_sync_excp(env, POWERPC_EXCP_DOORI,  SPR_BOOKE_IVOR36);
 env->spr[SPR_BOOKE_IVOR37] = sregs.u.e.ivor_high[5];
+kvm_sync_excp(env, POWERPC_EXCP_DOORCI, SPR_BOOKE_IVOR37);
 }
 }
 
-- 
1.9.3




[Qemu-devel] [PATCH 3/4 v8] ppc: Add software breakpoint support

2014-07-14 Thread Bharat Bhushan
This patch allow insert/remove software breakpoint.

When QEMU is not able to handle debug exception then we inject
program exception to guest because for software breakpoint QEMU
uses a ehpriv-1 instruction;
So there cannot be any reason that we are in qemu with exit reason
KVM_EXIT_DEBUG  for guest set debug exception, only possibility is
guest executed ehpriv-1 privilege instruction and that's why we are
injecting program exception.

Signed-off-by: Bharat Bhushan 
---
v7->v8
 - Decrement nip by 4 before calling ppc_cpu_do_interrupt()
   as pointed by "Madhavan Srinivasan"
 - Also added missing cpu_sync()

 target-ppc/kvm.c | 93 +++-
 1 file changed, 79 insertions(+), 14 deletions(-)

diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index e00a20f..0f2e8e4 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -1275,6 +1275,75 @@ static int kvmppc_handle_dcr_write(CPUPPCState *env, 
uint32_t dcrn, uint32_t dat
 return 0;
 }
 
+int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
+{
+/* Mixed endian case is not handled */
+uint32_t sc = debug_inst_opcode;
+
+if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn,
+sizeof(sc), 0) ||
+cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&sc, sizeof(sc), 1)) {
+return -EINVAL;
+}
+
+return 0;
+}
+
+int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
+{
+uint32_t sc;
+
+if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&sc, sizeof(sc), 0) ||
+sc != debug_inst_opcode ||
+cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn,
+sizeof(sc), 1)) {
+return -EINVAL;
+}
+
+return 0;
+}
+
+void kvm_arch_update_guest_debug(CPUState *cs, struct kvm_guest_debug *dbg)
+{
+/* Software Breakpoint updates */
+if (kvm_sw_breakpoints_active(cs)) {
+dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP;
+}
+}
+
+static int kvm_handle_debug(PowerPCCPU *cpu, struct kvm_run *run)
+{
+CPUState *cs = CPU(cpu);
+CPUPPCState *env = &cpu->env;
+struct kvm_debug_exit_arch *arch_info = &run->debug.arch;
+int handle = 0;
+
+if (kvm_find_sw_breakpoint(cs, arch_info->address)) {
+handle = 1;
+} else {
+/* QEMU is not able to handle debug exception, so inject
+ * program exception to guest;
+ * Yes program exception NOT debug exception !!
+ * For software breakpoint QEMU uses a ehpriv-1 instruction;
+ * So there cannot be any reason that we are here for guest
+ * set debug exception, only possibility is guest executed a
+ * privilege instruction and that's why we are injecting
+ * program exception.
+ */
+
+cpu_synchronize_state(cs);
+/* env->nip is PC, so increment this by 4 to use
+ * ppc_cpu_do_interrupt(), which set srr0 = env->nip - 4.
+ */
+env->nip += 4;
+cs->exception_index = POWERPC_EXCP_PROGRAM;
+env->error_code = POWERPC_EXCP_INVAL;
+ppc_cpu_do_interrupt(cs);
+}
+
+return handle;
+}
+
 int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
 {
 PowerPCCPU *cpu = POWERPC_CPU(cs);
@@ -1315,6 +1384,16 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run 
*run)
 ret = 0;
 break;
 
+case KVM_EXIT_DEBUG:
+DPRINTF("handle debug exception\n");
+if (kvm_handle_debug(cpu, run)) {
+ret = EXCP_DEBUG;
+break;
+}
+/* re-enter, this exception was guest-internal */
+ret = 0;
+break;
+
 default:
 fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason);
 ret = -1;
@@ -2003,16 +2082,6 @@ void kvm_arch_init_irq_routing(KVMState *s)
 {
 }
 
-int kvm_arch_insert_sw_breakpoint(CPUState *cpu, struct kvm_sw_breakpoint *bp)
-{
-return -EINVAL;
-}
-
-int kvm_arch_remove_sw_breakpoint(CPUState *cpu, struct kvm_sw_breakpoint *bp)
-{
-return -EINVAL;
-}
-
 int kvm_arch_insert_hw_breakpoint(target_ulong addr, target_ulong len, int 
type)
 {
 return -EINVAL;
@@ -2027,10 +2096,6 @@ void kvm_arch_remove_all_hw_breakpoints(void)
 {
 }
 
-void kvm_arch_update_guest_debug(CPUState *cpu, struct kvm_guest_debug *dbg)
-{
-}
-
 struct kvm_get_htab_buf {
 struct kvm_get_htab_header header;
 /*
-- 
1.9.3




[Qemu-devel] [PATCH 0/4 v8] ppc: Add debug stub support

2014-07-14 Thread Bharat Bhushan
This patchset add support for
 - software breakpoint
 - h/w breakpoint
 - h/w watchpoint
  
Please find description in individual patch.
  
v7->v8
 - Decrement nip by 4 before calling ppc_cpu_do_interrupt()
   as pointed by "Madhavan Srinivasan"
 - Also added missing cpu_sync()

v6->v7
 - Removed interrupt injection infrastructure
 - Simplified excp_vector initialization based on comment
 - Moved program check exception to software breakpoint patch
 
v5->v6
 - Added a new patch to synchronize excp_vectors.
 - Inject program exception rather than debug exception if
   guest is not able to handle debug exception. why? detail
   in respective patch.

Bharat Bhushan (4):
  ppc: debug stub: Get trap instruction opcode from KVM
  ppc: synchronize excp_vectors for injecting exception
  ppc: Add software breakpoint support
  ppc: Add hw breakpoint watchpoint support

 target-ppc/kvm.c | 356 ++-
 1 file changed, 328 insertions(+), 28 deletions(-)

-- 
1.9.3




[Qemu-devel] [PATCH 4/4 v8] ppc: Add hw breakpoint watchpoint support

2014-07-14 Thread Bharat Bhushan
This patch adds hardware breakpoint and hardware watchpoint support
for ppc.

On BOOKE architecture we cannot share debug resources between QEMU
and guest because:
When QEMU is using debug resources then debug exception must
be always enabled. To achieve this we set MSR_DE and also set
MSRP_DEP so guest cannot change MSR_DE.

When emulating debug resource for guest we want guest
to control MSR_DE (enable/disable debug interrupt on need).

So above mentioned two configuration cannot be supported
at the same time. So the result is that we cannot share
debug resources between QEMU and Guest on BOOKE architecture.

In the current design QEMU gets priority over guest,
this means that if QEMU is using debug resources then guest
cannot use them and if guest is using debug resource then
qemu can overwrite them.

When QEMU is not able to handle debug exception then we inject program
exception to guest. Yes program exception NOT debug exception and the
reason is:
 1) QEMU and guest not sharing debug resources
 2) For software breakpoint QEMU uses a ehpriv-1 instruction;

 So there cannot be any reason that we are in qemu with exit reason
 KVM_EXIT_DEBUG  for guest set debug exception, only possibility is
 guest executed ehpriv-1 privilege instruction and that's why we are
 injecting program exception.

Signed-off-by: Bharat Bhushan 
---
v7->v8
 - No change

 target-ppc/kvm.c | 234 +++
 1 file changed, 219 insertions(+), 15 deletions(-)

diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 0f2e8e4..a0948ae 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -38,6 +38,7 @@
 #include "hw/ppc/ppc.h"
 #include "sysemu/watchdog.h"
 #include "trace.h"
+#include "exec/gdbstub.h"
 
 //#define DEBUG_KVM
 
@@ -412,6 +413,38 @@ unsigned long kvm_arch_vcpu_id(CPUState *cpu)
 return ppc_get_vcpu_dt_id(POWERPC_CPU(cpu));
 }
 
+/* e500 supports 2 h/w breakpoint and 2 watchpoint.
+ * book3s supports only 1 watchpoint, so array size
+ * of 4 is sufficient for now.
+ */
+#define MAX_HW_BKPTS 4
+
+static struct HWBreakpoint {
+target_ulong addr;
+int type;
+} hw_debug_points[MAX_HW_BKPTS];
+
+static CPUWatchpoint hw_watchpoint;
+
+/* Default there is no breakpoint and watchpoint supported */
+static int max_hw_breakpoint;
+static int max_hw_watchpoint;
+static int nb_hw_breakpoint;
+static int nb_hw_watchpoint;
+
+static void kvmppc_hw_debug_points_init(CPUPPCState *cenv)
+{
+if (cenv->excp_model == POWERPC_EXCP_BOOKE) {
+max_hw_breakpoint = 2;
+max_hw_watchpoint = 2;
+}
+
+if ((max_hw_breakpoint + max_hw_watchpoint) > MAX_HW_BKPTS) {
+fprintf(stderr, "Error initializing h/w breakpoints\n");
+return;
+}
+}
+
 int kvm_arch_init_vcpu(CPUState *cs)
 {
 PowerPCCPU *cpu = POWERPC_CPU(cs);
@@ -439,6 +472,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
 }
 
 kvm_get_one_reg(cs, KVM_REG_PPC_DEBUG_INST, &debug_inst_opcode);
+kvmppc_hw_debug_points_init(cenv);
 
 return ret;
 }
@@ -1303,12 +1337,163 @@ int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct 
kvm_sw_breakpoint *bp)
 return 0;
 }
 
+static int find_hw_breakpoint(target_ulong addr, int type)
+{
+int n;
+
+assert((nb_hw_breakpoint + nb_hw_watchpoint)
+   <= ARRAY_SIZE(hw_debug_points));
+
+for (n = 0; n < nb_hw_breakpoint + nb_hw_watchpoint; n++) {
+if (hw_debug_points[n].addr == addr &&
+ hw_debug_points[n].type == type) {
+return n;
+}
+}
+
+return -1;
+}
+
+static int find_hw_watchpoint(target_ulong addr, int *flag)
+{
+int n;
+
+n = find_hw_breakpoint(addr, GDB_WATCHPOINT_ACCESS);
+if (n >= 0) {
+*flag = BP_MEM_ACCESS;
+return n;
+}
+
+n = find_hw_breakpoint(addr, GDB_WATCHPOINT_WRITE);
+if (n >= 0) {
+*flag = BP_MEM_WRITE;
+return n;
+}
+
+n = find_hw_breakpoint(addr, GDB_WATCHPOINT_READ);
+if (n >= 0) {
+*flag = BP_MEM_READ;
+return n;
+}
+
+return -1;
+}
+
+int kvm_arch_insert_hw_breakpoint(target_ulong addr,
+  target_ulong len, int type)
+{
+if ((nb_hw_breakpoint + nb_hw_watchpoint) >= ARRAY_SIZE(hw_debug_points)) {
+return -ENOBUFS;
+}
+
+hw_debug_points[nb_hw_breakpoint + nb_hw_watchpoint].addr = addr;
+hw_debug_points[nb_hw_breakpoint + nb_hw_watchpoint].type = type;
+
+switch (type) {
+case GDB_BREAKPOINT_HW:
+if (nb_hw_breakpoint >= max_hw_breakpoint) {
+return -ENOBUFS;
+}
+
+if (find_hw_breakpoint(addr, type) >= 0) {
+return -EEXIST;
+}
+
+nb_hw_breakpoint++;
+break;
+
+case GDB_WATCHPOINT_WRITE:
+case GDB_WATCHPOINT_READ:
+case GDB_WATCHPOINT_ACCESS:
+if (nb_hw_watchpoint >= max_hw_watchpoint) {
+return -ENOBUFS;
+}
+
+if (find_hw_breakpoint(addr, type) >= 0) {
+  

Re: [Qemu-devel] [PULL 3/3] cirrus: Fix host CPU blits

2014-07-14 Thread Gerd Hoffmann
  Hi,

> Do you see a way to work around this in the graphics driver. E.g. 
> blacklisting 24bpp modes
> etc. Even if X.Org people actually merge the fixes there are 2 years of Linux 
> releases out
> there that have corrupted graphics.

For anything using kernel 3.14+ IMO the answer to pretty much *any* gfx
issue is "use stdvga instead of cirrus".  3.14 got a kms driver for the
qemu stdvga (bochsdrm), so the modesetting driver and all the modern
stuff such as root-less X server works with the stdvga too.  And the
constrains cirrus has (due to emulating existing, old hardware) are
gone.

cheers,
  Gerd





[Qemu-devel] [PATCH 01/20] target-mips: add MSA defines and data structure

2014-07-14 Thread Yongbok Kim
add defines and data structure for MIPS SIMD Architecture

Signed-off-by: Yongbok Kim 
---
 target-mips/cpu.h   |   79 +--
 target-mips/mips-defs.h |1 +
 target-mips/op_helper.c |1 +
 3 files changed, 78 insertions(+), 3 deletions(-)

diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index c81dfac..9a6b77c 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -51,12 +51,74 @@ struct CPUMIPSTLBContext {
 };
 #endif
 
+/* MSA Context */
+
+#define MSA_WRLEN (128)
+
+typedef union wr_t wr_t;
+union wr_t {
+int8_t  b[MSA_WRLEN/8];
+int16_t h[MSA_WRLEN/16];
+int32_t w[MSA_WRLEN/32];
+int64_t d[MSA_WRLEN/64];
+};
+
+typedef struct CPUMIPSMSAContext CPUMIPSMSAContext;
+struct CPUMIPSMSAContext {
+
+#define MSAIR_REGISTER  0
+#define MSACSR_REGISTER 1
+#define MSAACCESS_REGISTER  2
+#define MSASAVE_REGISTER3
+#define MSAMODIFY_REGISTER  4
+#define MSAREQUEST_REGISTER 5
+#define MSAMAP_REGISTER 6
+#define MSAUNMAP_REGISTER   7
+
+int32_t msair;
+
+#define MSAIR_WRP_POS 16
+#define MSAIR_WRP_BIT (1 << MSAIR_WRP_POS)
+
+int32_t msacsr;
+
+#define MSACSR_RM_POS   0
+#define MSACSR_RM_MASK  (0x3 << MSACSR_RM_POS)
+
+#define MSACSR_CAUSE_ENABLE_FLAGS_POS 2
+#define MSACSR_CAUSE_ENABLE_FLAGS_MASK \
+(0x << MSACSR_CAUSE_ENABLE_FLAGS_POS)
+
+#define MSACSR_NX_POS 18
+#define MSACSR_NX_BIT (1 << MSACSR_NX_POS)
+
+#define MSACSR_FS_POS 24
+#define MSACSR_FS_BIT (1 << MSACSR_FS_POS)
+
+#define MSACSR_BITS \
+(MSACSR_RM_MASK |   \
+ MSACSR_CAUSE_ENABLE_FLAGS_MASK |   \
+ MSACSR_FS_BIT |\
+ MSACSR_NX_BIT)
+
+int32_t msaaccess;
+int32_t msasave;
+int32_t msamodify;
+int32_t msarequest;
+int32_t msamap;
+int32_t msaunmap;
+
+float_status fp_status;
+};
+
 typedef union fpr_t fpr_t;
 union fpr_t {
 float64  fd;   /* ieee double precision */
 float32  fs[2];/* ieee single precision */
 uint64_t d;/* binary double fixed-point */
 uint32_t w[2]; /* binary single fixed-point */
+/* FPU/MSA register mapping is not tested on big-endian hosts. */
+wr_t wr;   /* vector data */
 };
 /* define FP_ENDIAN_IDX to access the same location
  * in the fpr_t union regardless of the host endianness
@@ -175,6 +237,7 @@ typedef struct CPUMIPSState CPUMIPSState;
 struct CPUMIPSState {
 TCState active_tc;
 CPUMIPSFPUContext active_fpu;
+CPUMIPSMSAContext active_msa;
 
 uint32_t current_tc;
 uint32_t current_fpu;
@@ -362,6 +425,7 @@ struct CPUMIPSState {
 #define CP0C2_SA   0
 int32_t CP0_Config3;
 #define CP0C3_M31
+#define CP0C3_MSAP  28
 #define CP0C3_ISA_ON_EXC 16
 #define CP0C3_ULRI 13
 #define CP0C3_DSPP 10
@@ -431,7 +495,7 @@ struct CPUMIPSState {
 int error_code;
 uint32_t hflags;/* CPU State */
 /* TMASK defines different execution modes */
-#define MIPS_HFLAG_TMASK  0x1807FF
+#define MIPS_HFLAG_TMASK  0x5807FF
 #define MIPS_HFLAG_MODE   0x7 /* execution modes*/
 /* The KSU flags must be the lowest bits in hflags. The flag order
must be the same as defined for CP0 Status. This allows to use
@@ -475,6 +539,7 @@ struct CPUMIPSState {
 #define MIPS_HFLAG_DSPR2 0x10  /* Enable access to MIPS DSPR2 resources. */
 /* Extra flag about HWREna register. */
 #define MIPS_HFLAG_HWRENA_ULR 0x20 /* ULR bit from HWREna is set. */
+#define MIPS_HFLAG_MSA   0x40
 target_ulong btarget;/* Jump / branch target   */
 target_ulong bcond;  /* Branch condition (if needed)   */
 
@@ -628,8 +693,10 @@ enum {
 EXCP_C2E,
 EXCP_CACHE, /* 32 */
 EXCP_DSPDIS,
+EXCP_MSADIS,
+EXCP_MSAFPE,
 
-EXCP_LAST = EXCP_DSPDIS,
+EXCP_LAST = EXCP_MSAFPE,
 };
 /* Dummy exception for conditional stores.  */
 #define EXCP_SC 0x100
@@ -726,7 +793,8 @@ static inline void compute_hflags(CPUMIPSState *env)
 {
 env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 |
  MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU |
- MIPS_HFLAG_UX | MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2);
+ MIPS_HFLAG_UX | MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2 |
+ MIPS_HFLAG_MSA);
 if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
 !(env->CP0_Status & (1 << CP0St_ERL)) &&
 !(env->hflags & MIPS_HFLAG_DM)) {
@@ -784,6 +852,11 @@ static inline void compute_hflags(CPUMIPSState *env)
 env->hflags |= MIPS_HFLAG_COP1X;
 }
 }
+if (env->insn_flags & ASE_MSA) {
+if (env->CP0_Config5 & (1 << CP0C5_MSAEn)) {
+env->hflags |= MIPS_HFLAG_MSA;
+}
+}
 }
 
 #endif /* !defined (__MIPS_CPU_H__) */
diff --git a/target-mips/mips-defs.h b/target-mips/mips-defs.h
index 9dfa516..11722bb 100644
--- a/target-mips/mips-defs.h
+++ b/target-mips/mips-defs.h
@@ -41,6 +41,

[Qemu-devel] [PATCH 03/20] target-mips: move common funcs to cpu.h

2014-07-14 Thread Yongbok Kim
move commonly used functions to cpu.h

Signed-off-by: Yongbok Kim 
---
 target-mips/cpu.h   |   72 +++
 target-mips/gdbstub.c   |7 
 target-mips/op_helper.c |   60 +-
 3 files changed, 74 insertions(+), 65 deletions(-)

diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 9a6b77c..68ce383 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -747,6 +747,10 @@ hwaddr cpu_mips_translate_address (CPUMIPSState *env, 
target_ulong address,
 #endif
 target_ulong exception_resume_pc (CPUMIPSState *env);
 
+/* op_helper.c */
+extern unsigned int ieee_rm[];
+int ieee_ex_to_mips(int xcpt);
+
 static inline void cpu_get_tb_cpu_state(CPUMIPSState *env, target_ulong *pc,
 target_ulong *cs_base, int *flags)
 {
@@ -859,4 +863,72 @@ static inline void compute_hflags(CPUMIPSState *env)
 }
 }
 
+#include "exec/cpu_ldst.h"
+
+#if defined(CONFIG_USER_ONLY)
+#define HELPER_LD(name, insn, type) \
+static inline type do_##name(CPUMIPSState *env, target_ulong addr,  \
+ int mem_idx)   \
+{   \
+return (type) insn##_raw(addr); \
+}
+#else
+#define HELPER_LD(name, insn, type) \
+static inline type do_##name(CPUMIPSState *env, target_ulong addr,  \
+ int mem_idx)   \
+{   \
+switch (mem_idx) {  \
+case 0: \
+return (type) cpu_##insn##_kernel(env, addr);   \
+break;  \
+case 1: \
+return (type) cpu_##insn##_super(env, addr);\
+break;  \
+default:\
+case 2: \
+return (type) cpu_##insn##_user(env, addr); \
+break;  \
+}   \
+}
+#endif
+HELPER_LD(lbu, ldub, uint8_t)
+HELPER_LD(lw, ldl, int32_t)
+#ifdef TARGET_MIPS64
+HELPER_LD(ld, ldq, int64_t)
+#endif
+#undef HELPER_LD
+
+#if defined(CONFIG_USER_ONLY)
+#define HELPER_ST(name, insn, type) \
+static inline void do_##name(CPUMIPSState *env, target_ulong addr,  \
+ type val, int mem_idx) \
+{   \
+insn##_raw(addr, val);  \
+}
+#else
+#define HELPER_ST(name, insn, type) \
+static inline void do_##name(CPUMIPSState *env, target_ulong addr,  \
+ type val, int mem_idx) \
+{   \
+switch (mem_idx) {  \
+case 0: \
+cpu_##insn##_kernel(env, addr, val);\
+break;  \
+case 1: \
+cpu_##insn##_super(env, addr, val); \
+break;  \
+default:\
+case 2: \
+cpu_##insn##_user(env, addr, val);  \
+break;  \
+}   \
+}
+#endif
+HELPER_ST(sb, stb, uint8_t)
+HELPER_ST(sw, stl, uint32_t)
+#ifdef TARGET_MIPS64
+HELPER_ST(sd, stq, uint64_t)
+#endif
+#undef HELPER_ST
+
 #endif /* !defined (__MIPS_CPU_H__) */
diff --git a/target-mips/gdbstub.c b/target-mips/gdbstub.c
index 5b72d58..f65fec2 100644
--- a/target-mips/gdbstub.c
+++ b/target-mips/gdbstub.c
@@ -73,13 +73,6 @@ int mips_cpu_gdb_read_register(CPUState *cs, uint8_t 
*mem_buf, int n)
 return 0;
 }
 
-/* convert MIPS rounding mode in FCR31 to IEEE library */
-static unsigned int ieee_rm[] = {
-float_round_nearest_even,
-float_round_to_zero,
-float_round_up,
-float_round_down
-};
 #define RES

[Qemu-devel] [PATCH 00/20] target-mips: add MSA module

2014-07-14 Thread Yongbok Kim
The following patchset implements MIPS SIMD Architecture module.
MSA adds new instructions to MIPS Architecture that allow efficient
parallel processing of vector operations.

For more information refer to:
MIPS Architecture Reference Manual
Volume IV-j: The MIPS32 SIMD Architecture Module
The document (MD00867) is available at:
http://www.imgtec.com/mips/architectures/simd.asp

Note that LSA instruction is not included in this patchset as
Release 6 implements it.

This patchset is on top of the patch:
[PATCH v2] target-mips: fix broken MIPS16 and microMIPS
http://patchwork.ozlabs.org/patch/366146/

The MSA floating-point is compliant with the IEEE Standard for Floating-Point
Arithmetic 754TM-2008. However this patchset is not set up with the IEEE-2008
option as QEMU softfloat for MIPS has not been updated yet.

Yongbok Kim (20):
  target-mips: add MSA defines and data structure
  target-mips: add MSA exceptions
  target-mips: move common funcs to cpu.h
  target-mips: add 8, 16, 32, 64 bits load and store
  target-mips: stop translation after ctc1
  target-mips: add MSA opcode enum
  target-mips: add msa_reset(), global msa register
  target-mips: add msa_helper.c
  target-mips: add MSA branch instructions
  target-mips: add MSA I8 format instructions
  target-mips: add MSA I5 format instructions
  target-mips: add MSA BIT format instructions
  target-mips: add MSA 3R format instructions
  target-mips: add MSA ELM format instructions
  target-mips: add MSA 3RF format instructions
  target-mips: add MSA VEC/2R format instructions
  target-mips: add MSA 2RF format instructions
  target-mips: add MSA MI10 format instructions
  disas/mips.c: disassemble MSA instructions
  target-mips: add MSA support to mips32r5-generic

 disas/mips.c |  721 ++-
 target-mips/Makefile.objs|2 +-
 target-mips/cpu.h|  159 ++-
 target-mips/gdbstub.c|7 -
 target-mips/helper.c |8 +
 target-mips/helper.h |  177 ++
 target-mips/mips-defs.h  |1 +
 target-mips/msa_helper.c | 5423 ++
 target-mips/op_helper.c  |   61 +-
 target-mips/translate.c  | 1576 -
 target-mips/translate_init.c |   49 +-
 11 files changed, 8107 insertions(+), 77 deletions(-)
 create mode 100644 target-mips/msa_helper.c

-- 
1.7.4




[Qemu-devel] [PATCH 19/20] disas/mips.c: disassemble MSA instructions

2014-07-14 Thread Yongbok Kim
disassemble MIPS SIMD Architecture instructions

Signed-off-by: Yongbok Kim 
---
 disas/mips.c |  721 +-
 1 files changed, 719 insertions(+), 2 deletions(-)

diff --git a/disas/mips.c b/disas/mips.c
index 2106b57..65781f7 100644
--- a/disas/mips.c
+++ b/disas/mips.c
@@ -218,6 +218,28 @@ see .  */
 #define OP_SH_MTACC_D  13
 #define OP_MASK_MTACC_D0x3
 
+/* MSA */
+#define OP_MASK_1BIT0x1
+#define OP_SH_1BIT  16
+#define OP_MASK_2BIT0x3
+#define OP_SH_2BIT  16
+#define OP_MASK_3BIT0x7
+#define OP_SH_3BIT  16
+#define OP_MASK_4BIT0xf
+#define OP_SH_4BIT  16
+#define OP_MASK_5BIT0x1f
+#define OP_SH_5BIT  16
+#define OP_MASK_10BIT   0x3ff
+#define OP_SH_10BIT 11
+#define OP_MASK_MSACR11 0x1f
+#define OP_SH_MSACR11   11
+#define OP_MASK_MSACR6  0x1f
+#define OP_SH_MSACR66
+#define OP_MASK_GPR 0x1f
+#define OP_SH_GPR   6
+#define OP_MASK_1_TO_4  0x3
+#define OP_SH_1_TO_46
+
 #defineOP_OP_COP0  0x10
 #defineOP_OP_COP1  0x11
 #defineOP_OP_COP2  0x12
@@ -502,6 +524,9 @@ struct mips_opcode
 /* Instruction writes MDMX accumulator. */
 #define INSN2_WRITE_MDMX_ACC   0x0004
 
+/* Reads the general purpose register in OP_*_RD.  */
+#define INSN2_READ_GPR_D0x0200
+
 /* Instruction is actually a macro.  It should be ignored by the
disassembler, and requires special treatment by the assembler.  */
 #define INSN_MACRO  0x
@@ -557,7 +582,12 @@ struct mips_opcode
 #define INSN_55000x0200
 
 /* MDMX ASE */
-#define INSN_MDMX 0x0400
+#define INSN_MDMX 0x/* Deprecated */
+
+/* MIPS MSA Extension */
+#define INSN_MSA  0x0400
+#define INSN_MSA640x0400
+
 /* MT ASE */
 #define INSN_MT   0x0800
 /* SmartMIPS ASE  */
@@ -1190,6 +1220,17 @@ extern const int bfd_mips16_num_opcodes;
 /* MIPS MT ASE support.  */
 #define MT32   INSN_MT
 
+/* MSA */
+#define MSA INSN_MSA
+#define MSA64   INSN_MSA64
+#define WR_VD   INSN_WRITE_FPR_D/* Reuse INSN_WRITE_FPR_D */
+#define RD_VD   WR_VD   /* Reuse WR_VD */
+#define RD_VT   INSN_READ_FPR_T /* Reuse INSN_READ_FPR_T */
+#define RD_VS   INSN_READ_FPR_S /* Reuse INSN_READ_FPR_S */
+#define RD_dINSN2_READ_GPR_D/* Reuse INSN2_READ_GPR_D */
+
+#define RD_rd6  0
+
 /* The order of overloaded instructions matters.  Label arguments and
register arguments look the same. Instructions that can have either
for arguments must apear in the correct order in this table for the
@@ -1209,6 +1250,538 @@ const struct mips_opcode mips_builtin_opcodes[] =
them first.  The assemblers uses a hash table based on the
instruction name anyhow.  */
 /* name,args,  match,  mask,   pinfo,  
membership */
+/* MSA */
+{"sll.b",   "+d,+e,+f", 0x780d, 0xffe0003f, WR_VD|RD_VS|RD_VT,  0, MSA},
+{"sll.h",   "+d,+e,+f", 0x782d, 0xffe0003f, WR_VD|RD_VS|RD_VT,  0, MSA},
+{"sll.w",   "+d,+e,+f", 0x784d, 0xffe0003f, WR_VD|RD_VS|RD_VT,  0, MSA},
+{"sll.d",   "+d,+e,+f", 0x786d, 0xffe0003f, WR_VD|RD_VS|RD_VT,  0, MSA},
+{"slli.b",  "+d,+e,+7", 0x7879, 0xfff8003f, WR_VD|RD_VS,0, MSA},
+{"slli.h",  "+d,+e,+8", 0x7869, 0xfff0003f, WR_VD|RD_VS,0, MSA},
+{"slli.w",  "+d,+e,+9", 0x7849, 0xffe0003f, WR_VD|RD_VS,0, MSA},
+{"slli.d",  "+d,+e,'",  0x7809, 0xffc0003f, WR_VD|RD_VS,0, MSA},
+{"sra.b",   "+d,+e,+f", 0x788d, 0xffe0003f, WR_VD|RD_VS|RD_VT,  0, MSA},
+{"sra.h",   "+d,+e,+f", 0x78ad, 0xffe0003f, WR_VD|RD_VS|RD_VT,  0, MSA},
+{"sra.w",   "+d,+e,+f", 0x78cd, 0xffe0003f, WR_VD|RD_VS|RD_VT,  0, MSA},
+{"sra.d",   "+d,+e,+f", 0x78ed, 0xffe0003f, WR_VD|RD_VS|RD_VT,  0, MSA},
+{"srai.b",  "+d,+e,+7", 0x78f9, 0xfff8003f, WR_VD|RD_VS,0, MSA},
+{"srai.h",  "+d,+e,+8", 0x78e9, 0xfff0003f, WR_VD|RD_VS,0, MSA},
+{"srai.w",  "+d,+e,+9", 0x78c9, 0xffe0003f, WR_VD|RD_VS,0, MSA},
+{"srai.d",  "+d,+e,'",  0x7889, 0xffc0003f, WR_VD|RD_VS,0, MSA},
+{"srl.b",   "+d,+e,+f", 0x790d, 0xffe0003f, WR_VD|RD_VS|RD_VT,  0, MSA},
+{"srl.h",   "+d,+e,+f", 0x792d, 0xffe0003f, WR_VD|RD_VS|RD_VT,  0, MSA},
+{"srl.w",   "+d,+e,+f", 0x794d, 0xffe0003f, WR_VD|RD_VS|RD_VT,  0, MSA},
+{"srl.d",   "+d,+e,+f", 0x796d, 0xffe0003f, WR_VD|RD_VS|RD_VT,  0, MSA},
+{"srli.b",  "+d,+e,+7", 0x7979, 0xfff8003f, WR_VD|RD_VS,0, MSA},
+{"srli.h",  "+d,+e,+8", 0x7969, 0xfff0003f, WR_VD|RD_VS,0, MSA},
+{"srli.w",  "+d,+e,+9", 0x7949, 0xffe0003f, WR_VD|RD_VS,0, MSA},
+{"srli.d",  "+d,+e

[Qemu-devel] [PATCH 05/20] target-mips: stop translation after ctc1

2014-07-14 Thread Yongbok Kim
stop translation as ctc1 instruction can change hflags

Signed-off-by: Yongbok Kim 
---
 target-mips/translate.c |6 ++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index 994e85d..cccbc44 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -6837,12 +6837,15 @@ static void gen_mttr(CPUMIPSState *env, DisasContext 
*ctx, int rd, int rt,
 break;
 case 3:
 /* XXX: For now we support only a single FPU context. */
+save_cpu_state(ctx, 1);
 {
 TCGv_i32 fs_tmp = tcg_const_i32(rd);
 
 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
 tcg_temp_free_i32(fs_tmp);
 }
+/* Stop translation as we may have changed hflags */
+ctx->bstate = BS_STOP;
 break;
 /* COP2: Not implemented. */
 case 4:
@@ -7278,12 +7281,15 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, 
int rt, int fs)
 break;
 case OPC_CTC1:
 gen_load_gpr(t0, rt);
+save_cpu_state(ctx, 1);
 {
 TCGv_i32 fs_tmp = tcg_const_i32(fs);
 
 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
 tcg_temp_free_i32(fs_tmp);
 }
+/* Stop translation as we may have changed hflags */
+ctx->bstate = BS_STOP;
 opn = "ctc1";
 break;
 #if defined(TARGET_MIPS64)
-- 
1.7.4




[Qemu-devel] [PATCH 04/20] target-mips: add 8, 16, 32, 64 bits load and store

2014-07-14 Thread Yongbok Kim
add 8, 16, 32, 64 bits load and store

Signed-off-by: Yongbok Kim 
---
 target-mips/cpu.h |8 
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 68ce383..51d1c88 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -896,6 +896,10 @@ HELPER_LD(lw, ldl, int32_t)
 #ifdef TARGET_MIPS64
 HELPER_LD(ld, ldq, int64_t)
 #endif
+HELPER_LD(ld8, ldub, uint8_t)
+HELPER_LD(ld16, lduw, uint16_t)
+HELPER_LD(ld32, ldl, int32_t)
+HELPER_LD(ld64, ldq, int64_t)
 #undef HELPER_LD
 
 #if defined(CONFIG_USER_ONLY)
@@ -929,6 +933,10 @@ HELPER_ST(sw, stl, uint32_t)
 #ifdef TARGET_MIPS64
 HELPER_ST(sd, stq, uint64_t)
 #endif
+HELPER_ST(st8, stb, uint8_t)
+HELPER_ST(st16, stw, uint16_t)
+HELPER_ST(st32, stl, int32_t)
+HELPER_ST(st64, stq, int64_t)
 #undef HELPER_ST
 
 #endif /* !defined (__MIPS_CPU_H__) */
-- 
1.7.4




[Qemu-devel] [PATCH 10/20] target-mips: add MSA I8 format instructions

2014-07-14 Thread Yongbok Kim
add MSA I8 format instructions

Signed-off-by: Yongbok Kim 
---
 target-mips/helper.h |   11 
 target-mips/msa_helper.c |  140 ++
 target-mips/translate.c  |   94 ++-
 3 files changed, 243 insertions(+), 2 deletions(-)

diff --git a/target-mips/helper.h b/target-mips/helper.h
index 74ef094..174bc62 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -689,3 +689,14 @@ DEF_HELPER_FLAGS_3(dmthlip, 0, void, tl, tl, env)
 #endif
 DEF_HELPER_FLAGS_3(wrdsp, 0, void, tl, tl, env)
 DEF_HELPER_FLAGS_2(rddsp, 0, tl, tl, env)
+
+/* MIPS SIMD Architecture */
+
+DEF_HELPER_4(msa_andi_b, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_bmnzi_b, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_bmzi_b, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_bseli_b, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_nori_b, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_ori_b, void, env, i32, i32, i32)
+DEF_HELPER_5(msa_shf_df, void, env, i32, i32, i32, i32)
+DEF_HELPER_4(msa_xori_b, void, env, i32, i32, i32)
diff --git a/target-mips/msa_helper.c b/target-mips/msa_helper.c
index 5afc9ae..2355809 100644
--- a/target-mips/msa_helper.c
+++ b/target-mips/msa_helper.c
@@ -194,3 +194,143 @@ static inline void msa_store_wr_elem(CPUMIPSState *env, 
uint64_t val,
 assert(0);
 }
 }
+
+void helper_msa_andi_b(CPUMIPSState *env, uint32_t wd, uint32_t ws,
+uint32_t i8)
+{
+void *pwd = &(env->active_fpu.fpr[wd]);
+void *pws = &(env->active_fpu.fpr[ws]);
+ALL_B_ELEMENTS(i, MSA_WRLEN) {
+B(pwd, i) = B(pws, i) & i8;
+} DONE_ALL_ELEMENTS;
+if (env->active_msa.msair & MSAIR_WRP_BIT) {
+env->active_msa.msamodify |= (1 << wd);
+}
+}
+
+void helper_msa_ori_b(CPUMIPSState *env, uint32_t wd, uint32_t ws,
+uint32_t i8)
+{
+void *pwd = &(env->active_fpu.fpr[wd]);
+void *pws = &(env->active_fpu.fpr[ws]);
+ALL_B_ELEMENTS(i, MSA_WRLEN) {
+B(pwd, i) = B(pws, i) | i8;
+} DONE_ALL_ELEMENTS;
+if (env->active_msa.msair & MSAIR_WRP_BIT) {
+env->active_msa.msamodify |= (1 << wd);
+}
+}
+
+void helper_msa_nori_b(CPUMIPSState *env, uint32_t wd, uint32_t ws,
+uint32_t i8)
+{
+void *pwd = &(env->active_fpu.fpr[wd]);
+void *pws = &(env->active_fpu.fpr[ws]);
+ALL_B_ELEMENTS(i, MSA_WRLEN) {
+B(pwd, i) = ~(B(pws, i) | i8);
+} DONE_ALL_ELEMENTS;
+if (env->active_msa.msair & MSAIR_WRP_BIT) {
+env->active_msa.msamodify |= (1 << wd);
+}
+}
+
+void helper_msa_xori_b(CPUMIPSState *env, uint32_t wd, uint32_t ws,
+uint32_t i8)
+{
+void *pwd = &(env->active_fpu.fpr[wd]);
+void *pws = &(env->active_fpu.fpr[ws]);
+ALL_B_ELEMENTS(i, MSA_WRLEN) {
+B(pwd, i) = B(pws, i) ^ i8;
+} DONE_ALL_ELEMENTS;
+if (env->active_msa.msair & MSAIR_WRP_BIT) {
+env->active_msa.msamodify |= (1 << wd);
+}
+}
+
+#define BIT_MOVE_IF_NOT_ZERO(dest, arg1, arg2, df) \
+dest = UNSIGNED(((dest & (~arg2)) | (arg1 & arg2)), df)
+
+void helper_msa_bmnzi_b(CPUMIPSState *env, uint32_t wd, uint32_t ws,
+uint32_t i8)
+{
+void *pwd = &(env->active_fpu.fpr[wd]);
+void *pws = &(env->active_fpu.fpr[ws]);
+ALL_B_ELEMENTS(i, MSA_WRLEN) {
+BIT_MOVE_IF_NOT_ZERO(B(pwd, i), B(pws, i), i8, DF_BYTE);
+} DONE_ALL_ELEMENTS;
+if (env->active_msa.msair & MSAIR_WRP_BIT) {
+env->active_msa.msamodify |= (1 << wd);
+}
+}
+
+#define BIT_MOVE_IF_ZERO(dest, arg1, arg2, df) \
+dest = UNSIGNED((dest & arg2) | (arg1 & (~arg2)), df)
+
+void helper_msa_bmzi_b(CPUMIPSState *env, uint32_t wd, uint32_t ws,
+uint32_t i8)
+{
+void *pwd = &(env->active_fpu.fpr[wd]);
+void *pws = &(env->active_fpu.fpr[ws]);
+ALL_B_ELEMENTS(i, MSA_WRLEN) {
+BIT_MOVE_IF_ZERO(B(pwd, i), B(pws, i), i8, DF_BYTE);
+} DONE_ALL_ELEMENTS;
+if (env->active_msa.msair & MSAIR_WRP_BIT) {
+env->active_msa.msamodify |= (1 << wd);
+}
+}
+
+#define BIT_SELECT(dest, arg1, arg2, df) \
+dest = UNSIGNED((arg1 & (~dest)) | (arg2 & dest), df)
+
+void helper_msa_bseli_b(CPUMIPSState *env, uint32_t wd, uint32_t ws,
+uint32_t i8)
+{
+void *pwd = &(env->active_fpu.fpr[wd]);
+void *pws = &(env->active_fpu.fpr[ws]);
+ALL_B_ELEMENTS(i, MSA_WRLEN) {
+BIT_SELECT(B(pwd, i), B(pws, i), i8, DF_BYTE);
+} DONE_ALL_ELEMENTS;
+if (env->active_msa.msair & MSAIR_WRP_BIT) {
+env->active_msa.msamodify |= (1 << wd);
+}
+}
+
+#define SHF_POS(i, imm) ((i & 0xfc) + ((imm >> (2 * (i & 0x03))) & 0x03))
+
+static inline void msa_shf_df(CPUMIPSState *env, uint32_t df, void *pwd,
+void *pws, uint32_t imm)
+{
+wr_t wx, *pwx = &wx;
+switch (df) {
+case DF_BYTE:
+  ALL_B_ELEMENTS(i, MSA_WRLEN) {
+B(pwx, i) = B(pws, SHF_POS(i, imm));
+  } DONE_ALL_ELEMENTS;
+  break;
+case DF_HALF:
+  ALL_H_ELEMENTS(i, MSA_WRLEN) {
+H(pwx, i) = H

[Qemu-devel] [PATCH 02/20] target-mips: add MSA exceptions

2014-07-14 Thread Yongbok Kim
add MSA exceptions

Signed-off-by: Yongbok Kim 
---
 target-mips/helper.c |8 
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/target-mips/helper.c b/target-mips/helper.c
index 8a997e4..ed796ff 100644
--- a/target-mips/helper.c
+++ b/target-mips/helper.c
@@ -396,6 +396,8 @@ static const char * const excp_names[EXCP_LAST + 1] = {
 [EXCP_MDMX] = "MDMX",
 [EXCP_C2E] = "precise coprocessor 2",
 [EXCP_CACHE] = "cache error",
+[EXCP_MSADIS] = "MSA disabled",
+[EXCP_MSAFPE] = "MSA floating point",
 };
 
 target_ulong exception_resume_pc (CPUMIPSState *env)
@@ -608,12 +610,18 @@ void mips_cpu_do_interrupt(CPUState *cs)
 case EXCP_TRAP:
 cause = 13;
 goto set_EPC;
+case EXCP_MSAFPE:
+cause = 14;
+goto set_EPC;
 case EXCP_FPE:
 cause = 15;
 goto set_EPC;
 case EXCP_C2E:
 cause = 18;
 goto set_EPC;
+case EXCP_MSADIS:
+cause = 21;
+goto set_EPC;
 case EXCP_MDMX:
 cause = 22;
 goto set_EPC;
-- 
1.7.4




[Qemu-devel] [PATCH 08/20] target-mips: add msa_helper.c

2014-07-14 Thread Yongbok Kim
add msa_helper.c

Signed-off-by: Yongbok Kim 
---
 target-mips/Makefile.objs |2 +-
 target-mips/msa_helper.c  |  196 +
 2 files changed, 197 insertions(+), 1 deletions(-)
 create mode 100644 target-mips/msa_helper.c

diff --git a/target-mips/Makefile.objs b/target-mips/Makefile.objs
index 716244f..108fd9b 100644
--- a/target-mips/Makefile.objs
+++ b/target-mips/Makefile.objs
@@ -1,4 +1,4 @@
 obj-y += translate.o dsp_helper.o op_helper.o lmi_helper.o helper.o cpu.o
-obj-y += gdbstub.o
+obj-y += gdbstub.o msa_helper.o
 obj-$(CONFIG_SOFTMMU) += machine.o
 obj-$(CONFIG_KVM) += kvm.o
diff --git a/target-mips/msa_helper.c b/target-mips/msa_helper.c
new file mode 100644
index 000..5afc9ae
--- /dev/null
+++ b/target-mips/msa_helper.c
@@ -0,0 +1,196 @@
+/*
+ * MIPS SIMD Architecture Module Instruction emulation helpers for QEMU.
+ *
+ * Copyright (c) 2014 Imagination Technologies
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+#include "cpu.h"
+#include "exec/helper-proto.h"
+
+#define DF_BYTE   0
+#define DF_HALF   1
+#define DF_WORD   2
+#define DF_DOUBLE 3
+
+static void msa_check_index(CPUMIPSState *env,
+uint32_t df, uint32_t n) {
+switch (df) {
+case DF_BYTE: /* b */
+if (n > MSA_WRLEN / 8 - 1) {
+helper_raise_exception(env, EXCP_RI);
+}
+break;
+case DF_HALF: /* h */
+if (n > MSA_WRLEN / 16 - 1) {
+helper_raise_exception(env, EXCP_RI);
+}
+break;
+case DF_WORD: /* w */
+if (n > MSA_WRLEN / 32 - 1) {
+helper_raise_exception(env, EXCP_RI);
+}
+break;
+case DF_DOUBLE: /* d */
+if (n > MSA_WRLEN / 64 - 1) {
+helper_raise_exception(env, EXCP_RI);
+}
+break;
+default:
+/* shouldn't get here */
+assert(0);
+}
+}
+
+/* Data format min and max values */
+#define DF_BITS(df) (1 << ((df) + 3))
+
+#define DF_MAX_INT(df)  (int64_t)((1LL << (DF_BITS(df) - 1)) - 1)
+#define M_MAX_INT(m)(int64_t)((1LL << ((m) - 1)) - 1)
+
+#define DF_MIN_INT(df)  (int64_t)(-(1LL << (DF_BITS(df) - 1)))
+#define M_MIN_INT(m)(int64_t)(-(1LL << ((m) - 1)))
+
+#define DF_MAX_UINT(df) (uint64_t)(-1ULL >> (64 - DF_BITS(df)))
+#define M_MAX_UINT(m)   (uint64_t)(-1ULL >> (64 - (m)))
+
+/* Data format bit position and unsigned values */
+#define BIT_POSITION(x, df) ((uint64_t)(x) % DF_BITS(df))
+
+#define UNSIGNED(x, df) ((x) & DF_MAX_UINT(df))
+#define SIGNED(x, df)   \
+int64_t)x) << (64 - DF_BITS(df))) >> (64 - DF_BITS(df)))
+
+/* Element-by-element access macros */
+#define DF_ELEMENTS(df, wrlen) (wrlen / DF_BITS(df))
+
+#define  B(pwr, i) (((wr_t *)pwr)->b[i])
+#define BR(pwr, i) (((wr_t *)pwr)->b[i])
+#define BL(pwr, i) (((wr_t *)pwr)->b[i + MSA_WRLEN/16])
+
+#define ALL_B_ELEMENTS(i, wrlen)\
+do {\
+uint32_t i; \
+for (i = wrlen / 8; i--;)
+
+#define  H(pwr, i) (((wr_t *)pwr)->h[i])
+#define HR(pwr, i) (((wr_t *)pwr)->h[i])
+#define HL(pwr, i) (((wr_t *)pwr)->h[i + MSA_WRLEN/32])
+
+#define ALL_H_ELEMENTS(i, wrlen)\
+do {\
+uint32_t i; \
+for (i = wrlen / 16; i--;)
+
+#define  W(pwr, i) (((wr_t *)pwr)->w[i])
+#define WR(pwr, i) (((wr_t *)pwr)->w[i])
+#define WL(pwr, i) (((wr_t *)pwr)->w[i + MSA_WRLEN/64])
+
+#define ALL_W_ELEMENTS(i, wrlen)\
+do {\
+uint32_t i; \
+for (i = wrlen / 32; i--;)
+
+#define  D(pwr, i) (((wr_t *)pwr)->d[i])
+#define DR(pwr, i) (((wr_t *)pwr)->d[i])
+#define DL(pwr, i) (((wr_t *)pwr)->d[i + MSA_WRLEN/128])
+
+#define ALL_D_ELEMENTS(i, wrlen)\
+do {\
+uint32_t i; \
+for (i = wrlen / 64; i--;)
+
+#define Q(pwr, i) (((wr_t *)pwr)->q[i])
+#define ALL_Q_ELEMENTS(i, wrlen)\
+do {\
+uint32_t i; \
+for (i = wrlen / 128; i--;)
+
+#define DONE_ALL_ELEMENTS   

[Qemu-devel] [PATCH 11/20] target-mips: add MSA I5 format instructions

2014-07-14 Thread Yongbok Kim
add MSA I5 format instructions:

Signed-off-by: Yongbok Kim 
---
 target-mips/helper.h |   12 ++
 target-mips/msa_helper.c |  273 ++
 target-mips/translate.c  |   91 +++
 3 files changed, 376 insertions(+), 0 deletions(-)

diff --git a/target-mips/helper.h b/target-mips/helper.h
index 174bc62..fe0cf48 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -692,11 +692,23 @@ DEF_HELPER_FLAGS_2(rddsp, 0, tl, tl, env)
 
 /* MIPS SIMD Architecture */
 
+DEF_HELPER_5(msa_addvi_df, void, env, i32, i32, i32, s64)
 DEF_HELPER_4(msa_andi_b, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_bmnzi_b, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_bmzi_b, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_bseli_b, void, env, i32, i32, i32)
+DEF_HELPER_5(msa_ceqi_df, void, env, i32, i32, i32, s64)
+DEF_HELPER_5(msa_clei_s_df, void, env, i32, i32, i32, s64)
+DEF_HELPER_5(msa_clei_u_df, void, env, i32, i32, i32, s64)
+DEF_HELPER_5(msa_clti_s_df, void, env, i32, i32, i32, s64)
+DEF_HELPER_5(msa_clti_u_df, void, env, i32, i32, i32, s64)
+DEF_HELPER_4(msa_ldi_df, void, env, i32, i32, i32)
+DEF_HELPER_5(msa_maxi_s_df, void, env, i32, i32, i32, s64)
+DEF_HELPER_5(msa_maxi_u_df, void, env, i32, i32, i32, s64)
+DEF_HELPER_5(msa_mini_s_df, void, env, i32, i32, i32, s64)
+DEF_HELPER_5(msa_mini_u_df, void, env, i32, i32, i32, s64)
 DEF_HELPER_4(msa_nori_b, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_ori_b, void, env, i32, i32, i32)
 DEF_HELPER_5(msa_shf_df, void, env, i32, i32, i32, i32)
+DEF_HELPER_5(msa_subvi_df, void, env, i32, i32, i32, s64)
 DEF_HELPER_4(msa_xori_b, void, env, i32, i32, i32)
diff --git a/target-mips/msa_helper.c b/target-mips/msa_helper.c
index 2355809..00b6e77 100644
--- a/target-mips/msa_helper.c
+++ b/target-mips/msa_helper.c
@@ -195,6 +195,38 @@ static inline void msa_store_wr_elem(CPUMIPSState *env, 
uint64_t val,
 }
 }
 
+void helper_msa_addvi_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
+uint32_t ws, int64_t u5)
+{
+int64_t td, ts;
+int i;
+int df_bits = 8 * (1 << df);
+for (i = 0; i < MSA_WRLEN / df_bits; i++) {
+ts = msa_load_wr_elem_s64(env, ws, df, i);
+td = (int64_t) ts + u5;
+msa_store_wr_elem(env, td, wd, df, i);
+}
+if (env->active_msa.msair & MSAIR_WRP_BIT) {
+env->active_msa.msamodify |= (1 << wd);
+}
+}
+
+void helper_msa_subvi_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
+uint32_t ws, int64_t u5)
+{
+int64_t td, ts;
+int i;
+int df_bits = 8 * (1 << df);
+for (i = 0; i < MSA_WRLEN / df_bits; i++) {
+ts = msa_load_wr_elem_s64(env, ws, df, i);
+td = (int64_t) ts - u5;
+msa_store_wr_elem(env, td, wd, df, i);
+}
+if (env->active_msa.msair & MSAIR_WRP_BIT) {
+env->active_msa.msamodify |= (1 << wd);
+}
+}
+
 void helper_msa_andi_b(CPUMIPSState *env, uint32_t wd, uint32_t ws,
 uint32_t i8)
 {
@@ -295,6 +327,120 @@ void helper_msa_bseli_b(CPUMIPSState *env, uint32_t wd, 
uint32_t ws,
 }
 }
 
+static inline int64_t msa_ceq_df(CPUMIPSState *env, uint32_t df, int64_t arg1,
+int64_t arg2)
+{
+return arg1 == arg2 ? -1 : 0;
+}
+
+void helper_msa_ceqi_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
+uint32_t ws, int64_t i5)
+{
+int64_t td, ts;
+int i;
+int df_bits = 8 * (1 << df);
+for (i = 0; i < MSA_WRLEN / df_bits; i++) {
+ts = msa_load_wr_elem_s64(env, ws, df, i);
+td = msa_ceq_df(env, df, ts, i5);
+msa_store_wr_elem(env, td, wd, df, i);
+}
+if (env->active_msa.msair & MSAIR_WRP_BIT) {
+env->active_msa.msamodify |= (1 << wd);
+}
+}
+
+static inline int64_t msa_cle_s_df(CPUMIPSState *env, uint32_t df,
+int64_t arg1, int64_t arg2)
+{
+return arg1 <= arg2 ? -1 : 0;
+}
+
+void helper_msa_clei_s_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
+uint32_t ws, int64_t s5)
+{
+int64_t td, ts;
+int i;
+int df_bits = 8 * (1 << df);
+for (i = 0; i < MSA_WRLEN / df_bits; i++) {
+ts = msa_load_wr_elem_s64(env, ws, df, i);
+td = msa_cle_s_df(env, df, ts, s5);
+msa_store_wr_elem(env, td, wd, df, i);
+}
+if (env->active_msa.msair & MSAIR_WRP_BIT) {
+env->active_msa.msamodify |= (1 << wd);
+}
+}
+
+static inline int64_t msa_cle_u_df(CPUMIPSState *env, uint32_t df,
+int64_t arg1, int64_t arg2)
+{
+uint64_t u_arg1 = UNSIGNED(arg1, df);
+uint64_t u_arg2 = UNSIGNED(arg2, df);
+return u_arg1 <= u_arg2 ? -1 : 0;
+}
+
+void helper_msa_clei_u_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
+uint32_t ws, int64_t u5)
+{
+uint64_t td, ts;
+int i;
+int df_bits = 8 * (1 << df);
+for (i = 0; i < MSA_WRLEN / df_bits; i++) {
+ts = msa_load_wr_elem_i64(env, ws, df, i);
+td = msa_cle_u_df(env, df, ts, u5);
+msa_store_wr_elem(env, td, wd, df, i);
+}
+if (env->active_msa.msair & MSAIR_WRP_BIT) {
+ 

[Qemu-devel] [PATCH 20/20] target-mips: add MSA support to mips32r5-generic

2014-07-14 Thread Yongbok Kim
add MSA support to mips32r5-generic core definition

Signed-off-by: Yongbok Kim 
---
 target-mips/translate_init.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c
index 9e0f67b..034a3f8 100644
--- a/target-mips/translate_init.c
+++ b/target-mips/translate_init.c
@@ -355,7 +355,7 @@ static const mips_def_t mips_defs[] =
(0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) |
(1 << CP0C1_CA),
 .CP0_Config2 = MIPS_CONFIG2,
-.CP0_Config3 = MIPS_CONFIG3 | (1U << CP0C3_M),
+.CP0_Config3 = MIPS_CONFIG3 | (1U << CP0C3_M) | (1 << CP0C3_MSAP),
 .CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M),
 .CP0_Config4_rw_bitmask = 0,
 .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_UFR),
@@ -373,7 +373,7 @@ static const mips_def_t mips_defs[] =
 (0x93 << FCR0_PRID),
 .SEGBITS = 32,
 .PABITS = 32,
-.insn_flags = CPU_MIPS32R5 | ASE_MIPS16 | ASE_DSP | ASE_DSPR2,
+.insn_flags = CPU_MIPS32R5 | ASE_MIPS16 | ASE_DSP | ASE_DSPR2 | 
ASE_MSA,
 .mmu_type = MMU_TYPE_R4000,
 },
 #if defined(TARGET_MIPS64)
-- 
1.7.4




[Qemu-devel] [PATCH 07/20] target-mips: add msa_reset(), global msa register

2014-07-14 Thread Yongbok Kim
add msa_reset() and global msa register (d type only)

Signed-off-by: Yongbok Kim 
---
 target-mips/translate.c  |   74 ++
 target-mips/translate_init.c |   45 +
 2 files changed, 119 insertions(+), 0 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index 6b4a82c..b8dbbdc 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -1256,6 +1256,7 @@ static TCGv cpu_dspctrl, btarget, bcond;
 static TCGv_i32 hflags;
 static TCGv_i32 fpu_fcr0, fpu_fcr31;
 static TCGv_i64 fpu_f64[32];
+static TCGv_i64 msa_wr_d[64];
 
 static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
 static target_ulong gen_opc_btarget[OPC_BUF_SIZE];
@@ -1353,6 +1354,25 @@ static const char * const fregnames[] = {
 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
 };
 
+static const char * const msaregnames[] = {
+"w0.d0",  "w0.d1",  "w1.d0",  "w1.d1",
+"w2.d0",  "w2.d1",  "w3.d0",  "w3.d1",
+"w4.d0",  "w4.d1",  "w4.d0",  "w4.d1",
+"w6.d0",  "w6.d1",  "w7.d0",  "w7.d1",
+"w8.d0",  "w8.d1",  "w9.d0",  "w9.d1",
+"w10.d0", "w10.d1", "w11.d0", "w11.d1",
+"w12.d0", "w12.d1", "w13.d0", "w13.d1",
+"w14.d0", "w14.d1", "w15.d0", "w15.d1",
+"w16.d0", "w16.d1", "w17.d0", "w17.d1",
+"w18.d0", "w18.d1", "w19.d0", "w19.d1",
+"w20.d0", "w20.d1", "w21.d0", "w21.d1",
+"w22.d0", "w22.d1", "w23.d0", "w23.d1",
+"w24.d0", "w24.d1", "w25.d0", "w25.d1",
+"w26.d0", "w26.d1", "w27.d0", "w27.d1",
+"w28.d0", "w28.d1", "w29.d0", "w29.d1",
+"w30.d0", "w30.d1", "w31.d0", "w31.d1",
+};
+
 #define MIPS_DEBUG(fmt, ...)  \
 do {  \
 if (MIPS_DEBUG_DISAS) {   \
@@ -14627,6 +14647,47 @@ static void gen_mipsdsp_accinsn(DisasContext *ctx, 
uint32_t op1, uint32_t op2,
 
 /* End MIPSDSP functions. */
 
+/* MIPS SIMD Architecture (MSA)  */
+
+static inline int check_msa_access(CPUMIPSState *env, DisasContext *ctx,
+int wt, int ws, int wd)
+{
+if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
+ !(ctx->hflags & MIPS_HFLAG_F64))) {
+generate_exception(ctx, EXCP_RI);
+return 0;
+}
+
+if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
+if (ctx->insn_flags & ASE_MSA) {
+generate_exception(ctx, EXCP_MSADIS);
+return 0;
+} else {
+generate_exception(ctx, EXCP_RI);
+return 0;
+}
+}
+
+if (env->active_msa.msair & MSAIR_WRP_BIT) {
+int curr_request  = 0;
+if (wd != -1) {
+curr_request |= (1 << wd);
+}
+if (wt != -1) {
+curr_request |= (1 << wt);
+}
+if (ws != -1) {
+curr_request |= (1 << ws);
+}
+env->active_msa.msarequest = curr_request
+& (~env->active_msa.msaaccess | env->active_msa.msasave);
+if (unlikely(env->active_msa.msarequest != 0)) {
+generate_exception(ctx, EXCP_MSADIS);
+return 0;
+}
+}
+return 1;
+}
 static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
 {
 int32_t offset;
@@ -16119,6 +16180,15 @@ void mips_tcg_init(void)
 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
 }
 
+for (i = 0; i < 32; i++) {
+int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
+msa_wr_d[i * 2] =
+tcg_global_mem_new_i64(TCG_AREG0, off, msaregnames[i * 2]);
+off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
+msa_wr_d[i * 2 + 1] =
+tcg_global_mem_new_i64(TCG_AREG0, off, msaregnames[i * 2 + 1]);
+}
+
 cpu_PC = tcg_global_mem_new(TCG_AREG0,
 offsetof(CPUMIPSState, active_tc.PC), "PC");
 for (i = 0; i < MIPS_DSP_ACC; i++) {
@@ -16318,6 +16388,10 @@ void cpu_state_reset(CPUMIPSState *env)
 }
 }
 #endif
+/* MSA */
+if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
+msa_reset(env);
+}
 compute_hflags(env);
 cs->exception_index = EXCP_NONE;
 }
diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c
index 29dc2ef..9e0f67b 100644
--- a/target-mips/translate_init.c
+++ b/target-mips/translate_init.c
@@ -688,3 +688,48 @@ static void mvp_init (CPUMIPSState *env, const mips_def_t 
*def)
  (0x0 << CP0MVPC1_PCX) | (0x0 << CP0MVPC1_PCP2) |
  (0x1 << CP0MVPC1_PCP1);
 }
+
+static void msa_reset(CPUMIPSState *env)
+{
+#ifdef CONFIG_USER_ONLY
+/* MSA access enabled */
+env->CP0_Config5 |= 1 << CP0C5_MSAEn;
+
+/* DSP and CP1 enabled, 64-bit FPRs */
+env->CP0_Status |= (1 << CP0St_MX);
+env->hflags |= MIPS_HFLAG_DSP;
+
+env->CP0_Status |= (1 << CP0St_CU1) | (1 << CP0St_FR);
+

[Qemu-devel] [PATCH 12/20] target-mips: add MSA BIT format instructions

2014-07-14 Thread Yongbok Kim
add MSA BIT format instructions

Signed-off-by: Yongbok Kim 
---
 target-mips/helper.h |   12 ++
 target-mips/msa_helper.c |  292 ++
 target-mips/translate.c  |  100 
 3 files changed, 404 insertions(+), 0 deletions(-)

diff --git a/target-mips/helper.h b/target-mips/helper.h
index fe0cf48..f9406d6 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -694,9 +694,14 @@ DEF_HELPER_FLAGS_2(rddsp, 0, tl, tl, env)
 
 DEF_HELPER_5(msa_addvi_df, void, env, i32, i32, i32, s64)
 DEF_HELPER_4(msa_andi_b, void, env, i32, i32, i32)
+DEF_HELPER_5(msa_bclri_df, void, env, i32, i32, i32, i32)
+DEF_HELPER_5(msa_binsli_df, void, env, i32, i32, i32, i32)
+DEF_HELPER_5(msa_binsri_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_4(msa_bmnzi_b, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_bmzi_b, void, env, i32, i32, i32)
+DEF_HELPER_5(msa_bnegi_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_4(msa_bseli_b, void, env, i32, i32, i32)
+DEF_HELPER_5(msa_bseti_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_ceqi_df, void, env, i32, i32, i32, s64)
 DEF_HELPER_5(msa_clei_s_df, void, env, i32, i32, i32, s64)
 DEF_HELPER_5(msa_clei_u_df, void, env, i32, i32, i32, s64)
@@ -709,6 +714,13 @@ DEF_HELPER_5(msa_mini_s_df, void, env, i32, i32, i32, s64)
 DEF_HELPER_5(msa_mini_u_df, void, env, i32, i32, i32, s64)
 DEF_HELPER_4(msa_nori_b, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_ori_b, void, env, i32, i32, i32)
+DEF_HELPER_5(msa_sat_s_df, void, env, i32, i32, i32, i32)
+DEF_HELPER_5(msa_sat_u_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_shf_df, void, env, i32, i32, i32, i32)
+DEF_HELPER_5(msa_slli_df, void, env, i32, i32, i32, i32)
+DEF_HELPER_5(msa_srai_df, void, env, i32, i32, i32, i32)
+DEF_HELPER_5(msa_srari_df, void, env, i32, i32, i32, i32)
+DEF_HELPER_5(msa_srli_df, void, env, i32, i32, i32, i32)
+DEF_HELPER_5(msa_srlri_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_subvi_df, void, env, i32, i32, i32, s64)
 DEF_HELPER_4(msa_xori_b, void, env, i32, i32, i32)
diff --git a/target-mips/msa_helper.c b/target-mips/msa_helper.c
index 00b6e77..39377d6 100644
--- a/target-mips/msa_helper.c
+++ b/target-mips/msa_helper.c
@@ -279,6 +279,140 @@ void helper_msa_xori_b(CPUMIPSState *env, uint32_t wd, 
uint32_t ws,
 }
 }
 
+static inline int64_t msa_bclr_df(CPUMIPSState *env, uint32_t df, int64_t arg1,
+int64_t arg2)
+{
+int32_t b_arg2 = BIT_POSITION(arg2, df);
+
+return UNSIGNED(arg1 & (~(1LL << b_arg2)), df);
+}
+
+void helper_msa_bclri_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
+uint32_t ws, uint32_t m)
+{
+int64_t td, ts;
+int i;
+int df_bits = 8 * (1 << df);
+for (i = 0; i < MSA_WRLEN / df_bits; i++) {
+ts = msa_load_wr_elem_s64(env, ws, df, i);
+td = msa_bclr_df(env, df, ts, m);
+msa_store_wr_elem(env, td, wd, df, i);
+}
+if (env->active_msa.msair & MSAIR_WRP_BIT) {
+env->active_msa.msamodify |= (1 << wd);
+}
+}
+
+static inline int64_t msa_bneg_df(CPUMIPSState *env, uint32_t df, int64_t arg1,
+int64_t arg2)
+{
+int32_t b_arg2 = BIT_POSITION(arg2, df);
+return UNSIGNED(arg1 ^ (1LL << b_arg2), df);
+}
+
+void helper_msa_bnegi_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
+uint32_t ws, uint32_t m)
+{
+int64_t td, ts;
+int i;
+int df_bits = 8 * (1 << df);
+for (i = 0; i < MSA_WRLEN / df_bits; i++) {
+ts = msa_load_wr_elem_s64(env, ws, df, i);
+td = msa_bneg_df(env, df, ts, m);
+msa_store_wr_elem(env, td, wd, df, i);
+}
+if (env->active_msa.msair & MSAIR_WRP_BIT) {
+env->active_msa.msamodify |= (1 << wd);
+}
+}
+
+static inline int64_t msa_bset_df(CPUMIPSState *env, uint32_t df, int64_t arg1,
+int64_t arg2)
+{
+int32_t b_arg2 = BIT_POSITION(arg2, df);
+return UNSIGNED(arg1 | (1LL << b_arg2), df);
+}
+
+void helper_msa_bseti_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
+uint32_t ws, uint32_t m)
+{
+int64_t td, ts;
+int i;
+int df_bits = 8 * (1 << df);
+for (i = 0; i < MSA_WRLEN / df_bits; i++) {
+ts = msa_load_wr_elem_s64(env, ws, df, i);
+td = msa_bset_df(env, df, ts, m);
+msa_store_wr_elem(env, td, wd, df, i);
+}
+if (env->active_msa.msair & MSAIR_WRP_BIT) {
+env->active_msa.msamodify |= (1 << wd);
+}
+}
+
+static inline int64_t msa_binsl_df(CPUMIPSState *env, uint32_t df,
+int64_t dest, int64_t arg1, int64_t arg2)
+{
+uint64_t u_arg1 = UNSIGNED(arg1, df);
+uint64_t u_dest = UNSIGNED(dest, df);
+int32_t sh_d = BIT_POSITION(arg2, df) + 1;
+int32_t sh_a = DF_BITS(df) - sh_d;
+if (sh_d == DF_BITS(df)) {
+return u_arg1;
+} else {
+return UNSIGNED(UNSIGNED(u_dest << sh_d, df) >> sh_d, df) |
+   UNSIGNED(UNSIGNED(u_arg1 >> sh_a, df) << sh_a, df);
+}
+}
+
+void helper_msa_binsli_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
+uint

[Qemu-devel] [PATCH 09/20] target-mips: add MSA branch instructions

2014-07-14 Thread Yongbok Kim
add MSA branch instructions

Signed-off-by: Yongbok Kim 
---
 target-mips/translate.c |  107 ++-
 1 files changed, 105 insertions(+), 2 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index b8dbbdc..0bfbcfe 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -14688,6 +14688,95 @@ static inline int check_msa_access(CPUMIPSState *env, 
DisasContext *ctx,
 }
 return 1;
 }
+
+static void determ_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
+{
+/* Note this function only works with MSA_WRLEN = 128 */
+uint64_t eval_zero_or_big;
+uint64_t eval_big;
+switch (df) {
+case 0: /*DF_BYTE*/
+eval_zero_or_big = 0x0101010101010101ULL;
+eval_big = 0x8080808080808080ULL;
+break;
+case 1: /*DF_HALF*/
+eval_zero_or_big = 0x0001000100010001ULL;
+eval_big = 0x8000800080008000ULL;
+break;
+case 2: /*DF_WORD*/
+eval_zero_or_big = 0x00010001ULL;
+eval_big = 0x80008000ULL;
+break;
+case 3: /*DF_DOUBLE*/
+eval_zero_or_big = 0x0001ULL;
+eval_big = 0x8000ULL;
+break;
+}
+TCGv_i64 t0 = tcg_temp_local_new_i64();
+TCGv_i64 t1 = tcg_temp_local_new_i64();
+tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
+tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
+tcg_gen_andi_i64(t0, t0, eval_big);
+tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
+tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
+tcg_gen_andi_i64(t1, t1, eval_big);
+tcg_gen_or_i64(t0, t0, t1);
+/* if all bits is zero then all element is not zero */
+/* if some bit is non-zero then some element is zero */
+tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
+tcg_gen_trunc_i64_tl(tresult, t0);
+tcg_temp_free_i64(t0);
+tcg_temp_free_i64(t1);
+}
+
+static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
+{
+check_insn(ctx, ASE_MSA);
+
+if (ctx->hflags & MIPS_HFLAG_BMASK) {
+generate_exception(ctx, EXCP_RI);
+return;
+}
+
+uint8_t df = (ctx->opcode >> 21) & 0x3 /* df [22:21] */;
+uint8_t wt = (ctx->opcode >> 16) & 0x1f /* wt [20:16] */;
+int64_t s16 = (ctx->opcode >> 0) & 0x /* s16 [15:0] */;
+s16 = (s16 << 48) >> 48; /* sign extend s16 to 64 bits*/
+
+check_msa_access(env, ctx, wt, -1, -1);
+
+switch (op1) {
+case OPC_MSA_BZ_V:
+case OPC_MSA_BNZ_V:
+{
+TCGv_i64 t0 = tcg_temp_local_new_i64();
+tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
+tcg_gen_setcondi_i64((op1 == OPC_MSA_BZ_V) ?
+TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
+tcg_gen_trunc_i64_tl(bcond, t0);
+tcg_temp_free_i64(t0);
+}
+break;
+case OPC_MSA_BZ_B:
+case OPC_MSA_BZ_H:
+case OPC_MSA_BZ_W:
+case OPC_MSA_BZ_D:
+determ_zero_element(bcond, df, wt);
+break;
+case OPC_MSA_BNZ_B:
+case OPC_MSA_BNZ_H:
+case OPC_MSA_BNZ_W:
+case OPC_MSA_BNZ_D:
+determ_zero_element(bcond, df, wt);
+tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
+break;
+}
+
+int64_t offset = s16 << 2;
+ctx->btarget = ctx->pc + offset + 4;
+
+ctx->hflags |= MIPS_HFLAG_BC;
+}
 static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
 {
 int32_t offset;
@@ -15729,9 +15818,23 @@ static void decode_opc (CPUMIPSState *env, 
DisasContext *ctx)
 break;
 
 case OPC_CP1:
-if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
+op1 = MASK_CP1(ctx->opcode);
+
+if ((ctx->insn_flags & ASE_MSA) &&
+(op1 == OPC_MSA_BZ_V ||
+ op1 == OPC_MSA_BNZ_V ||
+ op1 == OPC_MSA_BZ_B ||
+ op1 == OPC_MSA_BZ_H ||
+ op1 == OPC_MSA_BZ_W ||
+ op1 == OPC_MSA_BZ_D ||
+ op1 == OPC_MSA_BNZ_B ||
+ op1 == OPC_MSA_BNZ_H ||
+ op1 == OPC_MSA_BNZ_W ||
+ op1 == OPC_MSA_BNZ_D)) {
+gen_msa_branch(env, ctx, op1);
+} else if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
 check_cp1_enabled(ctx);
-op1 = MASK_CP1(ctx->opcode);
+
 switch (op1) {
 case OPC_MFHC1:
 case OPC_MTHC1:
-- 
1.7.4




[Qemu-devel] [PATCH 14/20] target-mips: add MSA ELM format instructions

2014-07-14 Thread Yongbok Kim
add MSA ELM format instructions

Signed-off-by: Yongbok Kim 
---
 target-mips/helper.h |9 ++
 target-mips/msa_helper.c |  239 ++
 target-mips/translate.c  |  136 ++
 3 files changed, 384 insertions(+), 0 deletions(-)

diff --git a/target-mips/helper.h b/target-mips/helper.h
index 00705c4..e13daec 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -720,6 +720,7 @@ DEF_HELPER_5(msa_bset_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_bseti_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_ceq_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_ceqi_df, void, env, i32, i32, i32, s64)
+DEF_HELPER_2(msa_cfcmsa, tl, env, i32)
 DEF_HELPER_5(msa_cle_s_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_cle_u_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_clei_s_df, void, env, i32, i32, i32, s64)
@@ -728,6 +729,9 @@ DEF_HELPER_5(msa_clt_s_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_clt_u_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_clti_s_df, void, env, i32, i32, i32, s64)
 DEF_HELPER_5(msa_clti_u_df, void, env, i32, i32, i32, s64)
+DEF_HELPER_5(msa_copy_s_df, void, env, i32, i32, i32, i32)
+DEF_HELPER_5(msa_copy_u_df, void, env, i32, i32, i32, i32)
+DEF_HELPER_3(msa_ctcmsa, void, env, tl, i32)
 DEF_HELPER_5(msa_div_s_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_div_u_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_dotp_s_df, void, env, i32, i32, i32, i32)
@@ -744,6 +748,8 @@ DEF_HELPER_5(msa_ilvev_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_ilvl_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_ilvod_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_ilvr_df, void, env, i32, i32, i32, i32)
+DEF_HELPER_5(msa_insert_df, void, env, i32, i32, i32, i32)
+DEF_HELPER_5(msa_insve_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_4(msa_ldi_df, void, env, i32, i32, i32)
 DEF_HELPER_5(msa_maddv_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_max_a_df, void, env, i32, i32, i32, i32)
@@ -758,6 +764,7 @@ DEF_HELPER_5(msa_mini_s_df, void, env, i32, i32, i32, s64)
 DEF_HELPER_5(msa_mini_u_df, void, env, i32, i32, i32, s64)
 DEF_HELPER_5(msa_mod_s_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_mod_u_df, void, env, i32, i32, i32, i32)
+DEF_HELPER_3(msa_move_v, void, env, i32, i32)
 DEF_HELPER_5(msa_msubv_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_mulv_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_4(msa_nori_b, void, env, i32, i32, i32)
@@ -768,9 +775,11 @@ DEF_HELPER_5(msa_sat_s_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_sat_u_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_shf_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_sld_df, void, env, i32, i32, i32, i32)
+DEF_HELPER_5(msa_sldi_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_sll_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_slli_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_splat_df, void, env, i32, i32, i32, i32)
+DEF_HELPER_5(msa_splati_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_sra_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_srai_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_srar_df, void, env, i32, i32, i32, i32)
diff --git a/target-mips/msa_helper.c b/target-mips/msa_helper.c
index bb4ea65..220a0cd 100644
--- a/target-mips/msa_helper.c
+++ b/target-mips/msa_helper.c
@@ -1166,6 +1166,59 @@ void helper_msa_clti_u_df(CPUMIPSState *env, uint32_t 
df, uint32_t wd,
 }
 }
 
+void helper_msa_copy_s_df(CPUMIPSState *env, uint32_t df, uint32_t rd,
+uint32_t ws, uint32_t n)
+{
+n %= DF_ELEMENTS(df, MSA_WRLEN);
+msa_check_index(env, (uint32_t)df, (uint32_t)n);
+switch (df) {
+case DF_BYTE: /* b */
+env->active_tc.gpr[rd] = (int8_t)env->active_fpu.fpr[ws].wr.b[n];
+break;
+case DF_HALF: /* h */
+env->active_tc.gpr[rd] = (int16_t)env->active_fpu.fpr[ws].wr.h[n];
+break;
+case DF_WORD: /* w */
+env->active_tc.gpr[rd] = (int32_t)env->active_fpu.fpr[ws].wr.w[n];
+break;
+#ifdef TARGET_MIPS64
+case DF_DOUBLE: /* d */
+env->active_tc.gpr[rd] = (int64_t)env->active_fpu.fpr[ws].wr.d[n];
+break;
+#endif
+default:
+/* shouldn't get here */
+assert(0);
+}
+}
+
+void helper_msa_copy_u_df(CPUMIPSState *env, uint32_t df, uint32_t rd,
+uint32_t ws, uint32_t n)
+{
+n %= DF_ELEMENTS(df, MSA_WRLEN);
+msa_check_index(env, (uint32_t)df, (uint32_t)n);
+switch (df) {
+case DF_BYTE: /* b */
+env->active_tc.gpr[rd] = (uint8_t)env->active_fpu.fpr[ws].wr.b[n];
+break;
+case DF_HALF: /* h */
+env->active_tc.gpr[rd] = (uint16_t)env->active_fpu.fpr[ws].wr.h[n];
+break;
+case DF_WORD: /* w */
+env->active_tc.gpr[rd] = (uint32_t)env->active_fpu.fpr[ws].wr.w[n];
+break;
+#ifdef TARGET_MIPS64
+case DF_DOUBLE: /* d */
+env->active_tc.gpr[rd] = (uint64_t)env->active_fpu.f

[Qemu-devel] [PATCH 06/20] target-mips: add MSA opcode enum

2014-07-14 Thread Yongbok Kim
add MSA opcode enum

Signed-off-by: Yongbok Kim 
---
 target-mips/translate.c |  248 +++
 1 files changed, 248 insertions(+), 0 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index cccbc44..6b4a82c 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -108,6 +108,8 @@ enum {
 OPC_SDC2 = (0x3E << 26),
 /* MDMX ASE specific */
 OPC_MDMX = (0x1E << 26),
+/* MSA ASE, same as MDMX */
+OPC_MSA  = OPC_MDMX,
 /* Cache and prefetch */
 OPC_CACHE= (0x2F << 26),
 OPC_PREF = (0x33 << 26),
@@ -128,10 +130,12 @@ enum {
 OPC_ROTR = OPC_SRL | (1 << 21),
 OPC_SRA  = 0x03 | OPC_SPECIAL,
 OPC_SLLV = 0x04 | OPC_SPECIAL,
+OPC_MSA_S05  = 0x05 | OPC_SPECIAL,
 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
 OPC_ROTRV= OPC_SRLV | (1 << 6),
 OPC_SRAV = 0x07 | OPC_SPECIAL,
 OPC_DSLLV= 0x14 | OPC_SPECIAL,
+OPC_MSA_S15  = 0x15 | OPC_SPECIAL,
 OPC_DSRLV= 0x16 | OPC_SPECIAL, /* also DROTRV */
 OPC_DROTRV   = OPC_DSRLV | (1 << 6),
 OPC_DSRAV= 0x17 | OPC_SPECIAL,
@@ -835,6 +839,8 @@ enum {
 OPC_BC1  = (0x08 << 21) | OPC_CP1, /* bc */
 OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
 OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
+OPC_MSA_BZ_V = (0x0B << 21) | OPC_CP1,
+OPC_MSA_BNZ_V = (0x0F << 21) | OPC_CP1,
 OPC_S_FMT= (FMT_S << 21) | OPC_CP1,
 OPC_D_FMT= (FMT_D << 21) | OPC_CP1,
 OPC_E_FMT= (FMT_E << 21) | OPC_CP1,
@@ -842,6 +848,14 @@ enum {
 OPC_W_FMT= (FMT_W << 21) | OPC_CP1,
 OPC_L_FMT= (FMT_L << 21) | OPC_CP1,
 OPC_PS_FMT   = (FMT_PS << 21) | OPC_CP1,
+OPC_MSA_BZ_B = (0x18 << 21) | OPC_CP1,
+OPC_MSA_BZ_H = (0x19 << 21) | OPC_CP1,
+OPC_MSA_BZ_W = (0x1A << 21) | OPC_CP1,
+OPC_MSA_BZ_D = (0x1B << 21) | OPC_CP1,
+OPC_MSA_BNZ_B = (0x1C << 21) | OPC_CP1,
+OPC_MSA_BNZ_H = (0x1D << 21) | OPC_CP1,
+OPC_MSA_BNZ_W = (0x1E << 21) | OPC_CP1,
+OPC_MSA_BNZ_D  = (0x1F << 21) | OPC_CP1,
 };
 
 #define MASK_CP1_FUNC(op)   MASK_CP1(op) | (op & 0x3F)
@@ -1000,6 +1014,240 @@ enum {
 OPC_NMSUB_PS= 0x3E | OPC_CP3,
 };
 
+/* MSA Opcodes */
+
+#define MASK_MSA_MINOR(op)(MASK_OP_MAJOR(op) | (op & 0x3F))
+enum {
+OPC_MSA_I8_00   = 0x00 | OPC_MSA,
+OPC_MSA_I8_01   = 0x01 | OPC_MSA,
+OPC_MSA_I8_02   = 0x02 | OPC_MSA,
+OPC_MSA_I5_06   = 0x06 | OPC_MSA,
+OPC_MSA_I5_07   = 0x07 | OPC_MSA,
+OPC_MSA_BIT_09  = 0x09 | OPC_MSA,
+OPC_MSA_BIT_0A  = 0x0A | OPC_MSA,
+OPC_MSA_3R_0D   = 0x0D | OPC_MSA,
+OPC_MSA_3R_0E   = 0x0E | OPC_MSA,
+OPC_MSA_3R_0F   = 0x0F | OPC_MSA,
+OPC_MSA_3R_10   = 0x10 | OPC_MSA,
+OPC_MSA_3R_11   = 0x11 | OPC_MSA,
+OPC_MSA_3R_12   = 0x12 | OPC_MSA,
+OPC_MSA_3R_13   = 0x13 | OPC_MSA,
+OPC_MSA_3R_14   = 0x14 | OPC_MSA,
+OPC_MSA_3R_15   = 0x15 | OPC_MSA,
+OPC_MSA_ELM = 0x19 | OPC_MSA,
+OPC_MSA_3RF_1A  = 0x1A | OPC_MSA,
+OPC_MSA_3RF_1B  = 0x1B | OPC_MSA,
+OPC_MSA_3RF_1C  = 0x1C | OPC_MSA,
+OPC_MSA_VEC = 0x1E | OPC_MSA,
+
+/* MI10 instruction */
+OPC_MSA_LD_B= (0x20) | OPC_MSA,
+OPC_MSA_LD_H= (0x21) | OPC_MSA,
+OPC_MSA_LD_W= (0x22) | OPC_MSA,
+OPC_MSA_LD_D= (0x23) | OPC_MSA,
+OPC_MSA_ST_B= (0x24) | OPC_MSA,
+OPC_MSA_ST_H= (0x25) | OPC_MSA,
+OPC_MSA_ST_W= (0x26) | OPC_MSA,
+OPC_MSA_ST_D= (0x27) | OPC_MSA,
+};
+
+enum {
+/* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
+OPC_MSA_ADDVI_df= (0x0 << 23) | OPC_MSA_I5_06,
+OPC_MSA_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07,
+OPC_MSA_SUBVI_df= (0x1 << 23) | OPC_MSA_I5_06,
+OPC_MSA_MAXI_S_df   = (0x2 << 23) | OPC_MSA_I5_06,
+OPC_MSA_CLTI_S_df   = (0x2 << 23) | OPC_MSA_I5_07,
+OPC_MSA_MAXI_U_df   = (0x3 << 23) | OPC_MSA_I5_06,
+OPC_MSA_CLTI_U_df   = (0x3 << 23) | OPC_MSA_I5_07,
+OPC_MSA_MINI_S_df   = (0x4 << 23) | OPC_MSA_I5_06,
+OPC_MSA_CLEI_S_df   = (0x4 << 23) | OPC_MSA_I5_07,
+OPC_MSA_MINI_U_df   = (0x5 << 23) | OPC_MSA_I5_06,
+OPC_MSA_CLEI_U_df   = (0x5 << 23) | OPC_MSA_I5_07,
+OPC_MSA_LDI_df  = (0x6 << 23) | OPC_MSA_I5_07,
+
+/* I8 instruction */
+OPC_MSA_ANDI_B  = (0x0 << 24) | OPC_MSA_I8_00,
+OPC_MSA_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
+OPC_MSA_SHF_B   = (0x0 << 24) | OPC_MSA_I8_02,
+OPC_MSA_ORI_B   = (0x1 << 24) | OPC_MSA_I8_00,
+OPC_MSA_BMZI_B  = (0x1 << 24) | OPC_MSA_I8_01,
+OPC_MSA_SHF_H   = (0x1 << 24) | OPC_MSA_I8_02,
+OPC_MSA_NORI_B  = (0x2 << 24) | OPC_MSA_I8_00,
+OPC_MSA_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
+OPC_MSA_SHF_W   = (0x2 << 24) | OPC_MSA_I8_02,
+OPC_MSA_XORI_B  = (0x3 << 24) | OPC_MSA_I8_00,
+
+/* VEC/2R/2RF instruction */
+OPC_MSA_AND_V   = (0x00 << 21) | OPC_MSA_VEC,
+OPC_MSA_OR_V= (0x01 << 21) | OPC_MSA_VEC,
+OPC_MSA_NOR_V   = (0x02 << 21) | OPC_MSA_VEC,
+OPC_MSA_XOR_V   = 

[Qemu-devel] [PATCH 16/20] target-mips: add MSA VEC/2R format instructions

2014-07-14 Thread Yongbok Kim
add MSA VEC/2R format instructions

Signed-off-by: Yongbok Kim 
---
 target-mips/helper.h |   11 ++
 target-mips/msa_helper.c |  244 ++
 target-mips/translate.c  |   98 ++
 3 files changed, 353 insertions(+), 0 deletions(-)

diff --git a/target-mips/helper.h b/target-mips/helper.h
index fec21b6..b87bb50 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -698,6 +698,7 @@ DEF_HELPER_5(msa_adds_s_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_adds_u_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_addv_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_addvi_df, void, env, i32, i32, i32, s64)
+DEF_HELPER_4(msa_and_v, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_andi_b, void, env, i32, i32, i32)
 DEF_HELPER_5(msa_asub_s_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_asub_u_df, void, env, i32, i32, i32, i32)
@@ -711,10 +712,13 @@ DEF_HELPER_5(msa_binsl_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_binsli_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_binsr_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_binsri_df, void, env, i32, i32, i32, i32)
+DEF_HELPER_4(msa_bmnz_v, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_bmnzi_b, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_bmz_v, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_bmzi_b, void, env, i32, i32, i32)
 DEF_HELPER_5(msa_bneg_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_bnegi_df, void, env, i32, i32, i32, i32)
+DEF_HELPER_4(msa_bsel_v, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_bseli_b, void, env, i32, i32, i32)
 DEF_HELPER_5(msa_bset_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_bseti_df, void, env, i32, i32, i32, i32)
@@ -755,6 +759,7 @@ DEF_HELPER_5(msa_fcune_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_fdiv_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_fexdo_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_fexp2_df, void, env, i32, i32, i32, i32)
+DEF_HELPER_4(msa_fill_df, void, env, i32, i32, i32)
 DEF_HELPER_5(msa_fmadd_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_fmax_a_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_fmax_df, void, env, i32, i32, i32, i32)
@@ -808,10 +813,15 @@ DEF_HELPER_5(msa_msubv_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_mul_q_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_mulr_q_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_mulv_df, void, env, i32, i32, i32, i32)
+DEF_HELPER_4(msa_nloc_df, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_nlzc_df, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_nor_v, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_nori_b, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_or_v, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_ori_b, void, env, i32, i32, i32)
 DEF_HELPER_5(msa_pckev_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_pckod_df, void, env, i32, i32, i32, i32)
+DEF_HELPER_4(msa_pcnt_df, void, env, i32, i32, i32)
 DEF_HELPER_5(msa_sat_s_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_sat_u_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_shf_df, void, env, i32, i32, i32, i32)
@@ -836,4 +846,5 @@ DEF_HELPER_5(msa_subsuu_s_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_subv_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_subvi_df, void, env, i32, i32, i32, s64)
 DEF_HELPER_5(msa_vshf_df, void, env, i32, i32, i32, i32)
+DEF_HELPER_4(msa_xor_v, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_xori_b, void, env, i32, i32, i32)
diff --git a/target-mips/msa_helper.c b/target-mips/msa_helper.c
index bb4ab66..aa165ac 100644
--- a/target-mips/msa_helper.c
+++ b/target-mips/msa_helper.c
@@ -495,6 +495,22 @@ void helper_msa_subsus_u_df(CPUMIPSState *env, uint32_t 
df, uint32_t wd,
 }
 }
 
+void helper_msa_and_v(CPUMIPSState *env, uint32_t wd, uint32_t ws,
+uint32_t wt)
+{
+void *pwd = &(env->active_fpu.fpr[wd]);
+void *pws = &(env->active_fpu.fpr[ws]);
+void *pwt = &(env->active_fpu.fpr[wt]);
+
+ALL_D_ELEMENTS(i, MSA_WRLEN) {
+D(pwd, i) = D(pws, i) & D(pwt, i);
+} DONE_ALL_ELEMENTS;
+
+if (env->active_msa.msair & MSAIR_WRP_BIT) {
+env->active_msa.msamodify |= (1 << wd);
+}
+}
+
 void helper_msa_andi_b(CPUMIPSState *env, uint32_t wd, uint32_t ws,
 uint32_t i8)
 {
@@ -508,6 +524,22 @@ void helper_msa_andi_b(CPUMIPSState *env, uint32_t wd, 
uint32_t ws,
 }
 }
 
+void helper_msa_or_v(CPUMIPSState *env, uint32_t wd, uint32_t ws,
+uint32_t wt)
+{
+void *pwd = &(env->active_fpu.fpr[wd]);
+void *pws = &(env->active_fpu.fpr[ws]);
+void *pwt = &(env->active_fpu.fpr[wt]);
+
+ALL_D_ELEMENTS(i, MSA_WRLEN) {
+D(pwd, i) = D(pws, i) | D(pwt, i);
+} DONE_ALL_ELEMENTS;
+
+if (env->active_msa.msair & MSAIR_WRP_BIT) {
+env->active_msa.msamodify |= (1 << wd);
+}
+}
+
 void helper_msa_ori_b(CPUMIPSState *env, uint32_t wd, uint32_t ws,
 uint32_t i8)
 {
@@ -521,6 +553,22 @@ void helper_msa_ori_b(CPUMIPSState *env, uint32_t wd, 
ui

[Qemu-devel] [PATCH 18/20] target-mips: add MSA MI10 format instructions

2014-07-14 Thread Yongbok Kim
add MSA MI10 format instructions

Signed-off-by: Yongbok Kim 
---
 target-mips/helper.h |2 +
 target-mips/msa_helper.c |   75 ++
 target-mips/translate.c  |   43 ++
 3 files changed, 120 insertions(+), 0 deletions(-)

diff --git a/target-mips/helper.h b/target-mips/helper.h
index c86bd36..89ca4d1 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -806,6 +806,7 @@ DEF_HELPER_5(msa_ilvod_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_ilvr_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_insert_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_insve_df, void, env, i32, i32, i32, i32)
+DEF_HELPER_5(msa_ld_df, void, env, i32, i32, i32, s64)
 DEF_HELPER_4(msa_ldi_df, void, env, i32, i32, i32)
 DEF_HELPER_5(msa_madd_q_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_maddr_q_df, void, env, i32, i32, i32, i32)
@@ -855,6 +856,7 @@ DEF_HELPER_5(msa_srl_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_srli_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_srlr_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_srlri_df, void, env, i32, i32, i32, i32)
+DEF_HELPER_5(msa_st_df, void, env, i32, i32, i32, s64)
 DEF_HELPER_5(msa_subs_s_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_subs_u_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_subsus_u_df, void, env, i32, i32, i32, i32)
diff --git a/target-mips/msa_helper.c b/target-mips/msa_helper.c
index d152953..9827dfd 100644
--- a/target-mips/msa_helper.c
+++ b/target-mips/msa_helper.c
@@ -3240,6 +3240,81 @@ void helper_msa_msubr_q_df(CPUMIPSState *env, uint32_t 
df, uint32_t wd,
 }
 }
 
+static inline int64_t msa_ld_df(CPUMIPSState *env, uint32_t df_bits,
+target_ulong addr)
+{
+switch (df_bits) {
+case 8:
+return  do_ld8(env, addr, env->hflags & MIPS_HFLAG_KSU);
+case 16:
+return  do_ld16(env, addr, env->hflags & MIPS_HFLAG_KSU);
+case 32:
+return (int64_t) do_ld32(env, addr, env->hflags & MIPS_HFLAG_KSU);
+case 64:
+return (int64_t) do_ld64(env, addr, env->hflags & MIPS_HFLAG_KSU);
+}
+return 0;
+}
+
+void helper_msa_ld_df(CPUMIPSState *env, uint32_t df, uint32_t wd, uint32_t rs,
+int64_t s10)
+{
+int64_t td;
+int df_bits = 8 * (1 << df);
+int i;
+target_ulong addr;
+int16_t offset = s10 << df;
+
+for (i = 0; i < MSA_WRLEN / df_bits; i++) {
+addr = env->active_tc.gpr[rs] + offset + (i << df);
+td = msa_ld_df(env, df_bits, addr);
+msa_store_wr_elem(env, td, wd, df, i);
+}
+
+if (env->active_msa.msair & MSAIR_WRP_BIT) {
+env->active_msa.msamodify |= (1 << wd);
+}
+}
+
+static inline void msa_st_df(CPUMIPSState *env, uint32_t df_bits,
+target_ulong addr, int64_t val)
+{
+switch (df_bits) {
+case 8:
+do_st8(env, addr, val, env->hflags & MIPS_HFLAG_KSU);
+break;
+case 16:
+do_st16(env, addr, val, env->hflags & MIPS_HFLAG_KSU);
+break;
+case 32:
+do_st32(env, addr, val, env->hflags & MIPS_HFLAG_KSU);
+break;
+case 64:
+do_st64(env, addr, val, env->hflags & MIPS_HFLAG_KSU);
+break;
+}
+}
+
+void helper_msa_st_df(CPUMIPSState *env, uint32_t df, uint32_t wd, uint32_t rs,
+int64_t s10)
+{
+int64_t td;
+int df_bits = 8 * (1 << df);
+int i;
+target_ulong addr;
+int16_t offset = s10 << df;
+
+for (i = 0; i < MSA_WRLEN / df_bits; i++) {
+addr = env->active_tc.gpr[rs] + offset + (i << df);
+td = msa_load_wr_elem_i64(env, wd, df, i);
+msa_st_df(env, df_bits, addr, td);
+}
+
+if (env->active_msa.msair & MSAIR_WRP_BIT) {
+env->active_msa.msamodify |= (1 << wd);
+}
+}
+
 #define FLOAT_ONE32 make_float32(0x3f8 << 20)
 #define FLOAT_ONE64 make_float64(0x3ffULL << 52)
 
diff --git a/target-mips/translate.c b/target-mips/translate.c
index dcfe830..7047248 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -15862,6 +15862,49 @@ static void gen_msa(CPUMIPSState *env, DisasContext 
*ctx)
 case OPC_MSA_VEC:
 gen_msa_vec(env, ctx);
 break;
+case OPC_MSA_LD_B:
+case OPC_MSA_LD_H:
+case OPC_MSA_LD_W:
+case OPC_MSA_LD_D:
+case OPC_MSA_ST_B:
+case OPC_MSA_ST_H:
+case OPC_MSA_ST_W:
+case OPC_MSA_ST_D:
+{
+int64_t s10 = (ctx->opcode >> 16) & 0x3ff /* s10 [25:16] */;
+s10 = (s10 << 54) >> 54; /* sign extend s10 to 64 bits*/
+uint8_t rs = (ctx->opcode >> 11) & 0x1f /* rs [15:11] */;
+uint8_t wd = (ctx->opcode >> 6) & 0x1f /* wd [10:6] */;
+uint8_t df = (ctx->opcode >> 0) & 0x3 /* df [1:0] */;
+
+TCGv_i32 tdf = tcg_const_i32(df);
+TCGv_i32 twd = tcg_const_i32(wd);
+TCGv_i32 trs = tcg_const_i32(rs);
+TCGv_i64 ts10 = tcg_const_i64(s10);
+
+switch (MASK_MSA_MINOR(opcode)) {
+ 

[Qemu-devel] [PATCH 17/20] target-mips: add MSA 2RF format instructions

2014-07-14 Thread Yongbok Kim
add MSA 2RF format instructions

Signed-off-by: Yongbok Kim 
---
 target-mips/helper.h |   16 ++
 target-mips/msa_helper.c |  656 ++
 target-mips/translate.c  |   76 ++
 3 files changed, 748 insertions(+), 0 deletions(-)

diff --git a/target-mips/helper.h b/target-mips/helper.h
index b87bb50..c86bd36 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -747,6 +747,7 @@ DEF_HELPER_5(msa_dpsub_u_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_fadd_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_fcaf_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_fceq_df, void, env, i32, i32, i32, i32)
+DEF_HELPER_4(msa_fclass_df, void, env, i32, i32, i32)
 DEF_HELPER_5(msa_fcle_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_fclt_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_fcne_df, void, env, i32, i32, i32, i32)
@@ -759,7 +760,14 @@ DEF_HELPER_5(msa_fcune_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_fdiv_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_fexdo_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_fexp2_df, void, env, i32, i32, i32, i32)
+DEF_HELPER_4(msa_fexupl_df, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_fexupr_df, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_ffint_s_df, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_ffint_u_df, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_ffql_df, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_ffqr_df, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_fill_df, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_flog2_df, void, env, i32, i32, i32)
 DEF_HELPER_5(msa_fmadd_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_fmax_a_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_fmax_df, void, env, i32, i32, i32, i32)
@@ -767,19 +775,27 @@ DEF_HELPER_5(msa_fmin_a_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_fmin_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_fmsub_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_fmul_df, void, env, i32, i32, i32, i32)
+DEF_HELPER_4(msa_frcp_df, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_frint_df, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_frsqrt_df, void, env, i32, i32, i32)
 DEF_HELPER_5(msa_fsaf_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_fseq_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_fsle_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_fslt_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_fsne_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_fsor_df, void, env, i32, i32, i32, i32)
+DEF_HELPER_4(msa_fsqrt_df, void, env, i32, i32, i32)
 DEF_HELPER_5(msa_fsub_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_fsueq_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_fsule_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_fsult_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_fsun_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_fsune_df, void, env, i32, i32, i32, i32)
+DEF_HELPER_4(msa_ftint_s_df, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_ftint_u_df, void, env, i32, i32, i32)
 DEF_HELPER_5(msa_ftq_df, void, env, i32, i32, i32, i32)
+DEF_HELPER_4(msa_ftrunc_s_df, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_ftrunc_u_df, void, env, i32, i32, i32)
 DEF_HELPER_5(msa_hadd_s_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_hadd_u_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_hsub_s_df, void, env, i32, i32, i32, i32)
diff --git a/target-mips/msa_helper.c b/target-mips/msa_helper.c
index aa165ac..d152953 100644
--- a/target-mips/msa_helper.c
+++ b/target-mips/msa_helper.c
@@ -3240,6 +3240,9 @@ void helper_msa_msubr_q_df(CPUMIPSState *env, uint32_t 
df, uint32_t wd,
 }
 }
 
+#define FLOAT_ONE32 make_float32(0x3f8 << 20)
+#define FLOAT_ONE64 make_float64(0x3ffULL << 52)
+
 #define FLOAT_SNAN16 (float16_default_nan ^ 0x0220)
 /* 0x7c20 */
 #define FLOAT_SNAN32 (float32_default_nan ^ 0x00400020)
@@ -3352,6 +3355,28 @@ static inline int update_msacsr(CPUMIPSState *env, int 
action, int denormal)
 (!float ## BITS ## _is_zero(ARG)\
 && float ## BITS ## _is_zero_or_denormal(ARG))
 
+#define MSA_FLOAT_UNOP0(DEST, OP, ARG, BITS)\
+do {\
+int c;  \
+int cause;  \
+int enable; \
+\
+set_float_exception_flags(0, &env->active_msa.fp_status);   \
+DEST = float ## BITS ## _ ## OP(ARG, &env->active_msa.fp_status);   \
+c = update_msacsr(env, CLEAR_FS_UNDERFLOW, 0);  \
+enable = GET_FP_ENABLE(env->active_msa.msacsr) | FP_UNIMPLEMENTED;  \
+cause = c & enable; \
+

[Qemu-devel] [Bug 1303926] Re: qemu-system-x86_64 crashed with SIGABRT

2014-07-14 Thread Sunding Wei
I have the similar issue, the KVM 2.0 keeps crashing, here is the stack
I captured with GDB

(gdb) c
Continuing.

Program received signal SIGABRT, Aborted.
[Switching to Thread 0x7ffede1f9700 (LWP )]
0x7ffeee4d4f79 in __GI_raise (sig=sig@entry=6) at 
../nptl/sysdeps/unix/sysv/linux/raise.c:56
56  ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0  0x7ffeee4d4f79 in __GI_raise (sig=sig@entry=6) at 
../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1  0x7ffeee4d8388 in __GI_abort () at abort.c:89
#2  0x7ffeee4cde36 in __assert_fail_base (fmt=0x7ffeee61f718 "%s%s%s:%u: 
%s%sAssertion `%s' failed.\n%n",
assertion=assertion@entry=0x7ffef45f1c1e "s->current",
file=file@entry=0x7ffef45f17e0 
"/build/buildd/qemu-2.0.0~rc1+dfsg/hw/scsi/lsi53c895a.c", line=line@entry=541,
function=function@entry=0x7ffef45f275b "lsi_do_dma") at assert.c:92
#3  0x7ffeee4cdee2 in __GI___assert_fail (assertion=0x7ffef45f1c1e 
"s->current",
file=0x7ffef45f17e0 
"/build/buildd/qemu-2.0.0~rc1+dfsg/hw/scsi/lsi53c895a.c", line=541,
function=0x7ffef45f275b "lsi_do_dma") at assert.c:101
#4  0x7ffef43de87d in ?? ()
#5  0x7ffef43dca97 in ?? ()
#6  0x7ffef4507631 in ?? ()
#7  0x7ffef450c776 in ?? ()
#8  0x7ffef44b1933 in ?? ()
#9  0x7ffef4506615 in ?? ()
#10 0x7ffef44a6f42 in ?? ()
#11 0x7ffeee86c182 in start_thread (arg=0x7ffede1f9700) at 
pthread_create.c:312
#12 0x7ffeee59930d in clone () at 
../sysdeps/unix/sysv/linux/x86_64/clone.S:111
(gdb)

My KVM command line
==

qemu-system-x86_64 -enable-kvm -name 015-win2k3-32bit-dev-target -S
-machine pc-i440fx-trusty,accel=kvm,usb=off -m 4096 -realtime mlock=off
-smp 4,sockets=4,cores=1,threads=1 -uuid 2af25570-37cd-
a3af-e157-0d85cf31d47d -no-user-config -nodefaults -chardev
socket,id=charmonitor,path=/var/lib/libvirt/qemu/015-win2k3-32bit-dev-
target.monitor,server,nowait -mon
chardev=charmonitor,id=monitor,mode=control -rtc base=localtime -no-
shutdown -boot strict=on -device piix3-usb-
uhci,id=usb,bus=pci.0,addr=0x1.0x2 -device
lsi,id=scsi0,bus=pci.0,addr=0x4 -drive file=/home/vm/015-win2k3-32bit-
dev-target/disk.qcow2,if=none,id=drive-
ide0-0-0,format=qcow2,cache=writeback -device ide-
hd,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,bootindex=1 -drive
file=/home/vm/015-win2k3-32bit-dev-target/zhe_test.qcow2,if=none,id
=drive-scsi0-0-0,format=qcow2,cache=writeback -device scsi-
hd,bus=scsi0.0,scsi-id=0,drive=drive-scsi0-0-0,id=scsi0-0-0 -netdev
tap,fd=25,id=hostnet0 -device
e1000,netdev=hostnet0,id=net0,mac=e0:db:55:04:dd:0f,bus=pci.0,addr=0x3
-chardev pty,id=charserial0 -device isa-
serial,chardev=charserial0,id=serial0 -device usb-tablet,id=input0 -vnc
0.0.0.0:115 -device VGA,id=video0,bus=pci.0,addr=0x2 -device virtio-
balloon-pci,id=balloon0,bus=pci.0,addr=0x5

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

Title:
  qemu-system-x86_64 crashed with SIGABRT

Status in QEMU:
  New
Status in “qemu” package in Ubuntu:
  Fix Released

Bug description:
  I've been getting this periodically since my upgrade to qemu 2.0 in
  trusty this morning.

  ProblemType: Crash
  DistroRelease: Ubuntu 14.04
  Package: qemu-system-x86 2.0.0~rc1+dfsg-0ubuntu1
  ProcVersionSignature: Ubuntu 3.13.0-23.45-generic 3.13.8
  Uname: Linux 3.13.0-23-generic x86_64
  ApportVersion: 2.14.1-0ubuntu1
  Architecture: amd64
  Date: Mon Apr  7 13:31:53 2014
  ExecutablePath: /usr/bin/qemu-system-x86_64
  InstallationDate: Installed on 2013-11-26 (131 days ago)
  InstallationMedia: Ubuntu 13.10 "Saucy Salamander" - Release amd64 
(20131016.1)
  ProcEnviron: PATH=(custom, no user)
  Registers: No symbol table is loaded.  Use the "file" command.
  Signal: 6
  SourcePackage: qemu
  StacktraceTop:
   
  Title: qemu-system-x86_64 crashed with SIGABRT
  UpgradeStatus: Upgraded to trusty on 2014-01-17 (79 days ago)
  UserGroups:

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



Re: [Qemu-devel] [PATCH 3/5] PPC: mac_nvram: Allow 2 and 4 byte accesses

2014-07-14 Thread Alexander Graf


On 14.07.14 08:41, Paolo Bonzini wrote:

Il 13/07/2014 18:17, Alexander Graf ha scritto:

The NVRAM in our Core99 machine really supports 2byte and 4byte accesses
just as well as 1byte accesses. In fact, Mac OS X uses those.

Add support for higher register size granularities.

Signed-off-by: Alexander Graf 
---
 hw/nvram/mac_nvram.c | 43 ---
 1 file changed, 32 insertions(+), 11 deletions(-)

diff --git a/hw/nvram/mac_nvram.c b/hw/nvram/mac_nvram.c
index bcff074..0a6df44 100644
--- a/hw/nvram/mac_nvram.c
+++ b/hw/nvram/mac_nvram.c
@@ -40,32 +40,53 @@
 #define DEF_SYSTEM_SIZE 0xc10

 /* macio style NVRAM device */
-static void macio_nvram_writeb(void *opaque, hwaddr addr,
-   uint64_t value, unsigned size)
+static void macio_nvram_write(void *opaque, hwaddr addr,
+  uint64_t value, unsigned size)
 {
 MacIONVRAMState *s = opaque;

 addr = (addr >> s->it_shift) & (s->size - 1);
-s->data[addr] = value;
-NVR_DPRINTF("writeb addr %04" PHYS_PRIx " val %" PRIx64 "\n", 
addr, value);

+switch (size) {
+case 1:
+s->data[addr] = value;
+break;
+case 2:
+stw_be_p(&s->data[addr], value);
+break;
+case 4:
+stl_be_p(&s->data[addr], value);
+break;
+}
+NVR_DPRINTF("write%d addr %04" PRIx64 " val %" PRIx64 "\n", 
size, addr,

+value);
 }

-static uint64_t macio_nvram_readb(void *opaque, hwaddr addr,
-  unsigned size)
+static uint64_t macio_nvram_read(void *opaque, hwaddr addr,
+ unsigned size)
 {
 MacIONVRAMState *s = opaque;
-uint32_t value;
+uint32_t value = 0;

 addr = (addr >> s->it_shift) & (s->size - 1);
-value = s->data[addr];
-NVR_DPRINTF("readb addr %04x val %x\n", (int)addr, value);
+switch (size) {
+case 1:
+value = s->data[addr];
+break;
+case 2:
+value = lduw_be_p(&s->data[addr]);
+break;
+case 4:
+value = ldl_be_p(&s->data[addr]);
+break;
+}
+NVR_DPRINTF("read%d addr %04x val %x\n", size, (int)addr, value);

 return value;
 }

 static const MemoryRegionOps macio_nvram_ops = {
-.read = macio_nvram_readb,
-.write = macio_nvram_writeb,
+.read = macio_nvram_read,
+.write = macio_nvram_write,
 .endianness = DEVICE_BIG_ENDIAN,
 };




I think this ought to be enough:

 static const MemoryRegionOps test_ioport_byte_ops = {
 .read = macio_nvram_readb,
 .write = macio_nvram_writeb,
+.valid.min_access_size = 1,
+.valid.max_access_size = 4,
+.impl.min_access_size = 1,
+.impl.max_access_size = 1,
 .endianness = DEVICE_BIG_ENDIAN,
 };


Heh - I knew there had to be a trick to this :). That's certainly a lot 
cleaner.



Alex




[Qemu-devel] [PATCH v2 3/5] PPC: mac_nvram: Allow 2 and 4 byte accesses

2014-07-14 Thread Alexander Graf
The NVRAM in our Core99 machine really supports 2byte and 4byte accesses
just as well as 1byte accesses. In fact, Mac OS X uses those.

Add support for higher register size granularities.

Signed-off-by: Alexander Graf 

---

v1 -> v2:

  - Leave single-byte accesses, but mark the MMIO handler 4-byte capable
with 1-byte granularity (thanks to Paolo for the suggestion!)
---
 hw/nvram/mac_nvram.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/hw/nvram/mac_nvram.c b/hw/nvram/mac_nvram.c
index bcff074..7656951 100644
--- a/hw/nvram/mac_nvram.c
+++ b/hw/nvram/mac_nvram.c
@@ -66,6 +66,10 @@ static uint64_t macio_nvram_readb(void *opaque, hwaddr addr,
 static const MemoryRegionOps macio_nvram_ops = {
 .read = macio_nvram_readb,
 .write = macio_nvram_writeb,
+.valid.min_access_size = 1,
+.valid.max_access_size = 4,
+.impl.min_access_size = 1,
+.impl.max_access_size = 1,
 .endianness = DEVICE_BIG_ENDIAN,
 };
 
-- 
1.8.1.4




[Qemu-devel] [PATCH for 2.1] virtio-scsi: fix with -M pc-i440fx-2.0

2014-07-14 Thread Paolo Bonzini
Right now starting a machine with virtio-scsi and a <= 2.0 machine type
fails with:

qemu-system-x86_64: -device virtio-scsi-pci: Property .any_layout not found

This is because the any_layout bit was actually never set after
virtio-scsi was changed to support arbitrary layout for virtio buffers.

(This was just a cleanup and a preparation for virtio 1.0; no guest
actually checks the bit, but the new request parsing algorithms are
tested even with old guest).

Reported-by: David Gilbert 
Signed-off-by: Paolo Bonzini 
---
 include/hw/virtio/virtio-scsi.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h
index 0419ee4..188a2d9 100644
--- a/include/hw/virtio/virtio-scsi.h
+++ b/include/hw/virtio/virtio-scsi.h
@@ -178,6 +178,8 @@ typedef struct {
 DEFINE_PROP_UINT32("cmd_per_lun", _state, _conf_field.cmd_per_lun, 128)
 
 #define DEFINE_VIRTIO_SCSI_FEATURES(_state, _feature_field)
\
+DEFINE_PROP_BIT("any_layout", _state, _feature_field,  
\
+VIRTIO_F_ANY_LAYOUT, true),
\
 DEFINE_PROP_BIT("hotplug", _state, _feature_field, VIRTIO_SCSI_F_HOTPLUG,  
\
true),  
\
 DEFINE_PROP_BIT("param_change", _state, _feature_field,
\
-- 
1.9.3




Re: [Qemu-devel] [PATCH] Tap: fix vcpu long time io blocking on tap

2014-07-14 Thread Wangkai (Kevin,C)


> -Original Message-
> From: Stefan Hajnoczi [mailto:stefa...@redhat.com]
> Sent: Monday, July 14, 2014 4:43 PM
> To: Wangkai (Kevin,C)
> Cc: qemu-devel@nongnu.org; aligu...@amazon.com; Lee yang
> Subject: Re: [PATCH] Tap: fix vcpu long time io blocking on tap
> 
> On Mon, Jul 14, 2014 at 01:55:05AM +, Wangkai (Kevin,C) wrote:
> >
> >
> > > -Original Message-
> > > From: Stefan Hajnoczi [mailto:stefa...@redhat.com]
> > > Sent: Friday, July 11, 2014 9:04 PM
> > > To: Wangkai (Kevin,C)
> > > Cc: qemu-devel@nongnu.org; aligu...@amazon.com; Lee yang
> > > Subject: Re: [PATCH] Tap: fix vcpu long time io blocking on tap
> > >
> > > On Fri, Jul 11, 2014 at 01:05:30AM +, Wangkai (Kevin,C) wrote:
> > > > When used a tap as net driver for vm, if too many packets was
> > > > delivered to the guest os via tap interface, the guest os will be
> > > > blocked on io events for a long time, while tap driver was
> busying
> > > process packets.
> > > >
> > > > kvm vcpu thread block on io lock call trace:
> > > >   __lll_lock_wait
> > > >   _L_lock_1004
> > > >   __pthread_mutex_lock
> > > >   qemu_mutex_lock
> > > >   kvm_cpu_exec
> > > >   qemu_kvm_cpu_thread_fn
> > > >   start_thread
> > > >
> > > > qemu io thread call trace:
> > > >   ...
> > > >   qemu_net_queue_send
> > > >   tap_send
> > > >   qemu_iohandler_poll
> > > >   main_loop_wait
> > > >   main_loop
> > > >
> > > >
> > > > I think the qemu io lock time should be as small as possible, and
> > > > the io work slice should be limited at a particular ration or
> time.
> > > >
> > > > ---
> > > > Signed-off-by: Wangkai 
> > >
> > > How many packets are you seeing in a single tap_send() call?
> > >
> > > Have you profiled the tap_send() code path?  Maybe it is performing
> > > some operation that is very slow.
> > >
> > > By the way, if you want good performance you should use vhost_net
> > > instead of userspace vhost_net.  Userspace virtio-net is not very
> > > optimized.
> > >
> > > Stefan
> >
> >
> > Hi Stefan,
> >
> > I am not use profile, just debug with gdb and code review.
> 
> It's worth understanding the root cause for this behavior because
> something is probably wrong.
> 
> > When packets delivered, I found the VM was hung, and I check qemu run
> >
> > State by gdb, I see the call trace for IO thread and vcpu thread, and
> >
> > I add debug info to check how many packets within tap_send, the info
> below:
> >
> > total recv 393520 time 1539821 us
> > total recv 1270 time 4931 us
> > total recv 257872 time 995828 us
> > total recv 10745 time 41438 us
> > total recv 505387 time 2000925 us
> 
> 505387 packets or 505387 bytes?
> 
> If that's packets, then even with small 64-byte packets that would mean
> 32 MB of pending data!
> 
> Are you running a networking benchmark where you'd expect lots of
> packets?
> 
> Have you checked how lot the time between tap_send() calls is?  Perhaps
> something else in QEMU is blocking the event loop so packets accumulate
> in the host kernel.
> 
> Stefan

Hi Stefan,

Here the detail network:

++
| The host add tap1 and eth10 to bridge 'br1'| ++
| ++ | |  send  |
| |   VM  eth1-+-tap1 --- bridge --- eth10 --+-+ packets|
| ++ | ||
++ ++

Qemu start vm by virtio, use tap interface, option is:
-net nic,vlan=101, model=virtio -net 
tap,vlan=101,ifname=tap1,script=no,downscript=no

And add tap1 and eth10 to bridge br1 in the host:
Brctl addif br1 tap1
Brctl addif br1 eth10

total recv 505387 time 2000925 us:
means call tap_send once dealing 505387 packets, the packet payload was 300 
bytes, and
time use for tap_send() was 2,000,925 micro-seconds, time was measured by 
record time stamp
at function tap_send() start and end.

We just test the performance of VM.

Regards
Wangkai




Re: [Qemu-devel] [PATCH for-2.1? 2/2] thread-pool: avoid deadlock in nested aio_poll() calls

2014-07-14 Thread Paolo Bonzini

Il 14/07/2014 10:36, Paolo Bonzini ha scritto:



to

/* In case elem->common.cb() makes a nested aio_poll() call,
 * next may become invalid as well.  Instead of just
 * restarting the QLIST_FOREACH_SAFE, go through the BH
 * once more, which also avoids deadlock if element A's
 * callback waits for element B and both completed at the
 * same time.
 */
qemu_bh_schedule(pool->completion_bh);
elem->common.cb(elem->common.opaque, elem->ret);
qemu_aio_release(elem);


This is of course missing here:

break;

Paolo



There is no change in logic, it's just that the goto is switched to a BH
representing a continuation.  I am then not sure why
pool->completion_token is necessary?





Re: [Qemu-devel] [PULL for-2.1 0/1] s390x/kvm: bugfix

2014-07-14 Thread Peter Maydell
On 14 July 2014 08:27, Cornelia Huck  wrote:
> The following changes since commit ab6d3749c4915cd5692633e321f7745dce06fe77:
>
>   Merge remote-tracking branch 'remotes/kraxel/tags/pull-vga-20140711-1' into 
> staging (2014-07-11 17:50:38 +0100)
>
> are available in the git repository at:
>
>
>   git://github.com/cohuck/qemu.git tags/s390x-20140714
>
> for you to fetch changes up to 85ad6230b3af048109b3e949ca95ade4dd9a0bfa:
>
>   s390x/kvm: synchronize guest floating point registers (2014-07-14 09:15:38 
> +0200)
>
> 
> A s390x/kvm bugfix for missing floating point register synchronization.

Applied, thanks.

-- PMM



[Qemu-devel] Hot unplug of pci-serial-2x fails assertion

2014-07-14 Thread Markus Armbruster
Watch this:

(qemu) chardev-add file,path=foo2,id=foo2
(qemu) chardev-add file,path=foo3,id=foo3
(qemu) device_add id=gg,driver=pci-serial-2x,chardev1=foo2,chardev2=foo3
(qemu) device_del gg
(qemu) upstream-qemu: /work/armbru/qemu/memory.c:1259: 
memory_region_finalize: Assertion `((&mr->subregions)->tqh_first == ((void 
*)0))' failed.

Program received signal SIGABRT, Aborted.
[Switching to Thread 0x7fffe2eb5700 (LWP 28433)]
0x7fffedef2c39 in raise () from /lib64/libc.so.6
(gdb) bt
#0  0x7fffedef2c39 in raise () from /lib64/libc.so.6
#1  0x7fffedef4348 in abort () from /lib64/libc.so.6
#2  0x7fffedeebb96 in __assert_fail_base () from /lib64/libc.so.6
#3  0x7fffedeebc42 in __assert_fail () from /lib64/libc.so.6
#4  0x556443cd in memory_region_finalize (obj=)
at /work/armbru/qemu/memory.c:1259
#5  0x5583fdca in object_deinit (type=, 
obj=0x563ee328) at /work/armbru/qemu/qom/object.c:408
#6  object_finalize (data=0x563ee328) at 
/work/armbru/qemu/qom/object.c:421
#7  object_unref (obj=0x563ee328) at /work/armbru/qemu/qom/object.c:729
#8  0x5578f598 in multi_serial_pci_exit (dev=0x563edae0)
at /work/armbru/qemu/hw/char/serial-pci.c:154
#9  0x557e4730 in pci_unregister_device (dev=)
at /work/armbru/qemu/hw/pci/pci.c:909
#10 0x557913d4 in device_unrealize (dev=0x563edae0, 
errp=0x7fffe2eb48c0) at /work/armbru/qemu/hw/core/qdev.c:196
#11 0x5579288a in device_set_realized (obj=, 
value=, errp=0x0) at /work/armbru/qemu/hw/core/qdev.c:885
#12 0x5583eefe in property_set_bool (obj=0x563edae0, 
v=, opaque=0x563c01f0, name=, 
errp=0x0)
at /work/armbru/qemu/qom/object.c:1473
#13 0x55841837 in object_property_set_qobject (obj=0x563edae0, 
value=, name=0x5590e3d8 "realized", errp=0x0)
at /work/armbru/qemu/qom/qom-qobject.c:24
#14 0x55840450 in object_property_set_bool (
obj=obj@entry=0x563edae0, value=value@entry=false, 
name=name@entry=0x5590e3d8 "realized", errp=errp@entry=0x0)
at /work/armbru/qemu/qom/object.c:888
#15 0x557910db in device_unparent (obj=0x563edae0)
at /work/armbru/qemu/hw/core/qdev.c:1006
#16 0x558400c5 in object_unparent (obj=0x563edae0)
at /work/armbru/qemu/qom/object.c:396
#17 0x5576e3b6 in acpi_pcihp_eject_slot (s=, 
bsel=, slots=)
at /work/armbru/qemu/hw/acpi/pcihp.c:139
#18 0x55640bba in access_with_adjusted_size (addr=addr@entry=8, 
value=value@entry=0x7fffe2eb4ab0, size=size@entry=4, 
access_size_min=, access_size_max=, 
access=
0x55640e60 , mr=0x563f5e78)
at /work/armbru/qemu/memory.c:481
#19 0x55645897 in memory_region_dispatch_write (size=4, data=16, 
addr=8, mr=0x563f5e78) at /work/armbru/qemu/memory.c:1143
#20 io_mem_write (mr=mr@entry=0x563f5e78, addr=8, val=, 
size=4) at /work/armbru/qemu/memory.c:1976
#21 0x5560fad3 in address_space_rw (
as=0x55d3ce80 , addr=addr@entry=44552, 
buf=0x77ff7000 "\020", len=len@entry=4, 
is_write=is_write@entry=true)
at /work/armbru/qemu/exec.c:2054
#22 0x5563ff18 in kvm_handle_io (count=1, size=4, 
direction=, data=, port=44552)
at /work/armbru/qemu/kvm-all.c:1597
#23 kvm_cpu_exec (cpu=cpu@entry=0x563aaee0)
at /work/armbru/qemu/kvm-all.c:1734
#24 0x5562e2e2 in qemu_kvm_cpu_thread_fn (arg=0x563aaee0)
at /work/armbru/qemu/cpus.c:874
#25 0x76bc7f33 in start_thread () from /lib64/libpthread.so.0
#26 0x7fffedfb1ded in clone () from /lib64/libc.so.6



Re: [Qemu-devel] hw/arm: add Lego NXT board

2014-07-14 Thread Peter Crosthwaite
On Mon, Jul 14, 2014 at 12:20 AM, Alexander Graf  wrote:
> Hi,
>
> I developed a software in the loop simulator for the Lego Mindstorms NXT
> brick. It uses the Qemu ARM emulator to run the Robot's Firmware. I plan to
> release the simulator as an open source project. Now, I wonder if it makes
> sense to integrate the Qemu board implementation back into Qemu mainline or
> simply maintain it as an external set of patches.
>
> The problem is that the qemu board I designed is not self-contained. It
> allows the firmware to read/write IO memory in order to read back sensor
> values from the simulated environment and to control actuators. The
> environment simulator is an external program which is connected to several
> qemu instances via posix named pipes using a simple communication protocol.

> Without pipe interaction the emulator can still be used to debug NXT
> firmware images without sensor/actuator interaction.
>

Sounds like self contained functionality to me :) People have
gone-to-list with less.

> I'm happy to prepare a patch, but do you think it is of any value to
> integrate code that is not 100% self contained?
>

Many first-round series are not self contained and tend be not much
more that "boot the bare minimum software and lets add I/O features
later".

Regards,
Peter

> Best Regards
> Alexander
>



Re: [Qemu-devel] [PATCH for 2.1] virtio-scsi: fix with -M pc-i440fx-2.0

2014-07-14 Thread Dr. David Alan Gilbert
* Paolo Bonzini (pbonz...@redhat.com) wrote:
> Right now starting a machine with virtio-scsi and a <= 2.0 machine type
> fails with:
> 
> qemu-system-x86_64: -device virtio-scsi-pci: Property .any_layout not 
> found
> 
> This is because the any_layout bit was actually never set after
> virtio-scsi was changed to support arbitrary layout for virtio buffers.
> 
> (This was just a cleanup and a preparation for virtio 1.0; no guest
> actually checks the bit, but the new request parsing algorithms are
> tested even with old guest).
> 
> Reported-by: David Gilbert 
> Signed-off-by: Paolo Bonzini 

Seems to fix the bug I hit.

Dave

> ---
>  include/hw/virtio/virtio-scsi.h | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h
> index 0419ee4..188a2d9 100644
> --- a/include/hw/virtio/virtio-scsi.h
> +++ b/include/hw/virtio/virtio-scsi.h
> @@ -178,6 +178,8 @@ typedef struct {
>  DEFINE_PROP_UINT32("cmd_per_lun", _state, _conf_field.cmd_per_lun, 128)
>  
>  #define DEFINE_VIRTIO_SCSI_FEATURES(_state, _feature_field)  
>   \
> +DEFINE_PROP_BIT("any_layout", _state, _feature_field,
>   \
> +VIRTIO_F_ANY_LAYOUT, true),  
>   \
>  DEFINE_PROP_BIT("hotplug", _state, _feature_field, 
> VIRTIO_SCSI_F_HOTPLUG,  \
> true),
>   \
>  DEFINE_PROP_BIT("param_change", _state, _feature_field,  
>   \
> -- 
> 1.9.3
> 
--
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK



[Qemu-devel] [PULL v2 for-2.1 00/22] Block patches for 2.1.0-rc2

2014-07-14 Thread Kevin Wolf
v2:
- Fixed assertion failure on 32 bit hosts triggered by qtests
  (32 bit truncation of image file size in patch "block: Make qiov
  match the request size until EOF")


The following changes since commit 675879f6f3c9463e103735a4e41e9deb0bee9b39:

  Update version for v2.1.0-rc1 release (2014-07-08 16:53:59 +0100)

are available in the git repository at:

  git://repo.or.cz/qemu/kevin.git tags/for-upstream

for you to fetch changes up to 58ac321135af890b503ebe56d0d00e184779918f:

  ide: Treat read/write beyond end as invalid (2014-07-14 12:03:21 +0200)


Block patches for 2.1.0-rc2 (v2)


Andreas Färber (1):
  tests: Fix unterminated string output visitor enum human string

Kevin Wolf (7):
  block/backup: Fix hang for unaligned image size
  block: Fix bdrv_is_allocated() return value
  block: Make qiov match the request size until EOF
  qcow2: Make qiov match request size until backing file EOF
  qed: Make qiov match request size until backing file EOF
  block: Assert qiov length matches request length
  dma-helpers: Fix too long qiov

Markus Armbruster (4):
  virtio-blk: Factor common checks out of virtio_blk_handle_read/write()
  virtio-blk: Bypass error action and I/O accounting on invalid r/w
  virtio-blk: Treat read/write beyond end as invalid
  ide: Treat read/write beyond end as invalid

Nikolay Nikolaev (1):
  qtest: fix vhost-user-test compilation with old GLib

Paolo Bonzini (5):
  block: prefer aio_poll to qemu_aio_wait
  block: drop aio functions that operate on the main AioContext
  test-aio: fix GSource-based timer test
  AioContext: speed up aio_notify
  AioContext: do not rely on aio_poll(ctx, true) result to end a loop

Stefan Hajnoczi (4):
  virtio-blk: avoid dataplane VirtIOBlockReq early free
  dataplane: do not free VirtQueueElement in vring_push()
  virtio-blk: avoid g_slice_new0() for VirtIOBlockReq and VirtQueueElement
  virtio-blk: embed VirtQueueElement in VirtIOBlockReq

 aio-posix.c |  38 -
 aio-win32.c |   6 +-
 async.c |  19 ++-
 block.c |  22 ++-
 block/backup.c  |   2 +-
 block/qcow2.c   |  11 +-
 block/qed.c |  38 +++--
 block/qed.h |   1 +
 block/raw-posix.c   |  15 +-
 blockjob.c  |   2 +-
 dma-helpers.c   |   4 +
 docs/aio_notify.promela | 104 ++
 hw/block/dataplane/virtio-blk.c |  30 ++--
 hw/block/virtio-blk.c   |  95 +++--
 hw/ide/core.c   |  28 
 hw/virtio/dataplane/vring.c |  22 ++-
 include/block/aio.h |  32 ++---
 include/block/blockjob.h|   4 +-
 include/block/coroutine.h   |   2 +-
 include/hw/virtio/dataplane/vring.h |   3 +-
 include/hw/virtio/virtio-blk.h  |   6 +-
 include/qemu-common.h   |   1 +
 iothread.c  |   5 +-
 main-loop.c |  21 ---
 qemu-io-cmds.c  |   4 +-
 tests/qemu-iotests/028  |  27 +++-
 tests/qemu-iotests/028.out  | 269 
 tests/test-aio.c|  38 ++---
 tests/test-string-output-visitor.c  |   7 +-
 tests/test-thread-pool.c|   4 +-
 tests/vhost-user-test.c |   4 +
 util/iov.c  |  13 ++
 32 files changed, 704 insertions(+), 173 deletions(-)
 create mode 100644 docs/aio_notify.promela



[Qemu-devel] [PULL v2 for-2.1 03/22] block: prefer aio_poll to qemu_aio_wait

2014-07-14 Thread Kevin Wolf
From: Paolo Bonzini 

Signed-off-by: Paolo Bonzini 
Signed-off-by: Kevin Wolf 
---
 block.c| 2 +-
 blockjob.c | 2 +-
 qemu-io-cmds.c | 4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/block.c b/block.c
index c9629a4..510430d 100644
--- a/block.c
+++ b/block.c
@@ -471,7 +471,7 @@ int bdrv_create(BlockDriver *drv, const char* filename,
 co = qemu_coroutine_create(bdrv_create_co_entry);
 qemu_coroutine_enter(co, &cco);
 while (cco.ret == NOT_DONE) {
-qemu_aio_wait();
+aio_poll(qemu_get_aio_context(), true);
 }
 }
 
diff --git a/blockjob.c b/blockjob.c
index 67a64ea..ca0b4e2 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -187,7 +187,7 @@ int block_job_cancel_sync(BlockJob *job)
 job->opaque = &data;
 block_job_cancel(job);
 while (data.ret == -EINPROGRESS) {
-qemu_aio_wait();
+aio_poll(bdrv_get_aio_context(bs), true);
 }
 return (data.cancelled && data.ret == 0) ? -ECANCELED : data.ret;
 }
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index 60c1ceb..c503fc6 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -483,7 +483,7 @@ static int do_co_write_zeroes(BlockDriverState *bs, int64_t 
offset, int count,
 co = qemu_coroutine_create(co_write_zeroes_entry);
 qemu_coroutine_enter(co, &data);
 while (!data.done) {
-qemu_aio_wait();
+aio_poll(bdrv_get_aio_context(bs), true);
 }
 if (data.ret < 0) {
 return data.ret;
@@ -2027,7 +2027,7 @@ static const cmdinfo_t resume_cmd = {
 static int wait_break_f(BlockDriverState *bs, int argc, char **argv)
 {
 while (!bdrv_debug_is_suspended(bs, argv[1])) {
-qemu_aio_wait();
+aio_poll(bdrv_get_aio_context(bs), true);
 }
 
 return 0;
-- 
1.8.3.1




[Qemu-devel] [PULL v2 for-2.1 04/22] block: drop aio functions that operate on the main AioContext

2014-07-14 Thread Kevin Wolf
From: Paolo Bonzini 

The main AioContext should be accessed explicitly via qemu_get_aio_context().
Most of the time, using it is not the right thing to do.

Signed-off-by: Paolo Bonzini 
Signed-off-by: Kevin Wolf 
---
 aio-posix.c   |  4 ++--
 aio-win32.c   |  6 +++---
 include/block/aio.h   | 17 ++---
 include/block/blockjob.h  |  4 ++--
 include/block/coroutine.h |  2 +-
 main-loop.c   | 21 -
 tests/test-thread-pool.c  |  4 ++--
 7 files changed, 12 insertions(+), 46 deletions(-)

diff --git a/aio-posix.c b/aio-posix.c
index f921d4f..44c4df3 100644
--- a/aio-posix.c
+++ b/aio-posix.c
@@ -125,7 +125,7 @@ static bool aio_dispatch(AioContext *ctx)
 bool progress = false;
 
 /*
- * We have to walk very carefully in case qemu_aio_set_fd_handler is
+ * We have to walk very carefully in case aio_set_fd_handler is
  * called while we're walking.
  */
 node = QLIST_FIRST(&ctx->aio_handlers);
@@ -183,7 +183,7 @@ bool aio_poll(AioContext *ctx, bool blocking)
 /*
  * If there are callbacks left that have been queued, we need to call them.
  * Do not call select in this case, because it is possible that the caller
- * does not need a complete flush (as is the case for qemu_aio_wait loops).
+ * does not need a complete flush (as is the case for aio_poll loops).
  */
 if (aio_bh_poll(ctx)) {
 blocking = false;
diff --git a/aio-win32.c b/aio-win32.c
index 23f4e5b..c12f61e 100644
--- a/aio-win32.c
+++ b/aio-win32.c
@@ -102,7 +102,7 @@ bool aio_poll(AioContext *ctx, bool blocking)
 /*
  * If there are callbacks left that have been queued, we need to call then.
  * Do not call select in this case, because it is possible that the caller
- * does not need a complete flush (as is the case for qemu_aio_wait loops).
+ * does not need a complete flush (as is the case for aio_poll loops).
  */
 if (aio_bh_poll(ctx)) {
 blocking = false;
@@ -115,7 +115,7 @@ bool aio_poll(AioContext *ctx, bool blocking)
 /*
  * Then dispatch any pending callbacks from the GSource.
  *
- * We have to walk very carefully in case qemu_aio_set_fd_handler is
+ * We have to walk very carefully in case aio_set_fd_handler is
  * called while we're walking.
  */
 node = QLIST_FIRST(&ctx->aio_handlers);
@@ -177,7 +177,7 @@ bool aio_poll(AioContext *ctx, bool blocking)
 blocking = false;
 
 /* we have to walk very carefully in case
- * qemu_aio_set_fd_handler is called while we're walking */
+ * aio_set_fd_handler is called while we're walking */
 node = QLIST_FIRST(&ctx->aio_handlers);
 while (node) {
 AioHandler *tmp;
diff --git a/include/block/aio.h b/include/block/aio.h
index a92511b..d81250c 100644
--- a/include/block/aio.h
+++ b/include/block/aio.h
@@ -220,7 +220,7 @@ bool aio_poll(AioContext *ctx, bool blocking);
 #ifdef CONFIG_POSIX
 /* Register a file descriptor and associated callbacks.  Behaves very similarly
  * to qemu_set_fd_handler2.  Unlike qemu_set_fd_handler2, these callbacks will
- * be invoked when using qemu_aio_wait().
+ * be invoked when using aio_poll().
  *
  * Code that invokes AIO completion functions should rely on this function
  * instead of qemu_set_fd_handler[2].
@@ -234,7 +234,7 @@ void aio_set_fd_handler(AioContext *ctx,
 
 /* Register an event notifier and associated callbacks.  Behaves very similarly
  * to event_notifier_set_handler.  Unlike event_notifier_set_handler, these 
callbacks
- * will be invoked when using qemu_aio_wait().
+ * will be invoked when using aio_poll().
  *
  * Code that invokes AIO completion functions should rely on this function
  * instead of event_notifier_set_handler.
@@ -251,19 +251,6 @@ GSource *aio_get_g_source(AioContext *ctx);
 /* Return the ThreadPool bound to this AioContext */
 struct ThreadPool *aio_get_thread_pool(AioContext *ctx);
 
-/* Functions to operate on the main QEMU AioContext.  */
-
-bool qemu_aio_wait(void);
-void qemu_aio_set_event_notifier(EventNotifier *notifier,
- EventNotifierHandler *io_read);
-
-#ifdef CONFIG_POSIX
-void qemu_aio_set_fd_handler(int fd,
- IOHandler *io_read,
- IOHandler *io_write,
- void *opaque);
-#endif
-
 /**
  * aio_timer_new:
  * @ctx: the aio context
diff --git a/include/block/blockjob.h b/include/block/blockjob.h
index f3cf63f..60aa835 100644
--- a/include/block/blockjob.h
+++ b/include/block/blockjob.h
@@ -74,7 +74,7 @@ struct BlockJob {
  * Set to true if the job should cancel itself.  The flag must
  * always be tested just before toggling the busy flag from false
  * to true.  After a job has been cancelled, it should only yield
- * if #qemu_aio_wait will ("sooner or later") reenter the coroutine.
+ * if #aio_poll will ("sooner or later") reenter t

[Qemu-devel] [PULL v2 for-2.1 12/22] dataplane: do not free VirtQueueElement in vring_push()

2014-07-14 Thread Kevin Wolf
From: Stefan Hajnoczi 

VirtQueueElement is allocated in vring_pop() so it seems to make sense
that vring_push() should free it.  Alas, virtio-blk frees
VirtQueueElement itself in virtio_blk_free_request().

This patch solves a double-free assertion in glib's g_slice_free().

Rename vring_free_element() to vring_unmap_element() since it no longer
frees the VirtQueueElement.

Signed-off-by: Stefan Hajnoczi 
Tested-by: Christian Borntraeger 
Signed-off-by: Kevin Wolf 
---
 hw/virtio/dataplane/vring.c | 9 -
 include/hw/virtio/dataplane/vring.h | 1 -
 2 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/hw/virtio/dataplane/vring.c b/hw/virtio/dataplane/vring.c
index 665a1ff..5d17d39 100644
--- a/hw/virtio/dataplane/vring.c
+++ b/hw/virtio/dataplane/vring.c
@@ -272,7 +272,7 @@ static int get_indirect(Vring *vring, VirtQueueElement 
*elem,
 return 0;
 }
 
-void vring_free_element(VirtQueueElement *elem)
+static void vring_unmap_element(VirtQueueElement *elem)
 {
 int i;
 
@@ -287,8 +287,6 @@ void vring_free_element(VirtQueueElement *elem)
 for (i = 0; i < elem->in_num; i++) {
 vring_unmap(elem->in_sg[i].iov_base, true);
 }
-
-g_slice_free(VirtQueueElement, elem);
 }
 
 /* This looks in the virtqueue and for the first available buffer, and converts
@@ -402,7 +400,8 @@ out:
 vring->broken = true;
 }
 if (elem) {
-vring_free_element(elem);
+vring_unmap_element(elem);
+g_slice_free(VirtQueueElement, elem);
 }
 *p_elem = NULL;
 return ret;
@@ -418,7 +417,7 @@ void vring_push(Vring *vring, VirtQueueElement *elem, int 
len)
 unsigned int head = elem->index;
 uint16_t new;
 
-vring_free_element(elem);
+vring_unmap_element(elem);
 
 /* Don't touch vring if a fatal error occurred */
 if (vring->broken) {
diff --git a/include/hw/virtio/dataplane/vring.h 
b/include/hw/virtio/dataplane/vring.h
index 63e7bf4..b23edd2 100644
--- a/include/hw/virtio/dataplane/vring.h
+++ b/include/hw/virtio/dataplane/vring.h
@@ -55,6 +55,5 @@ bool vring_enable_notification(VirtIODevice *vdev, Vring 
*vring);
 bool vring_should_notify(VirtIODevice *vdev, Vring *vring);
 int vring_pop(VirtIODevice *vdev, Vring *vring, VirtQueueElement **elem);
 void vring_push(Vring *vring, VirtQueueElement *elem, int len);
-void vring_free_element(VirtQueueElement *elem);
 
 #endif /* VRING_H */
-- 
1.8.3.1




[Qemu-devel] [PULL v2 for-2.1 01/22] block/backup: Fix hang for unaligned image size

2014-07-14 Thread Kevin Wolf
When doing a block backup of an image with an unaligned size (with
respect to the BACKUP_CLUSTER_SIZE), qemu would check the allocation
status of sectors after the end of the image. bdrv_is_allocated()
returns a result that is valid for 0 sectors in this case, so the backup
job ran into an endless loop.

Stop looping when seeing a result valid for 0 sectors, we're at EOF then.

The test case looks somewhat unrelated at first sight because I
originally tried to reproduce a different suspected bug that turned out
to not exist. Still a good test case and it accidentally found this one.

Signed-off-by: Kevin Wolf 
Reviewed-by: Eric Blake 
---
 block/backup.c |   2 +-
 tests/qemu-iotests/028 |  27 -
 tests/qemu-iotests/028.out | 269 +
 3 files changed, 296 insertions(+), 2 deletions(-)

diff --git a/block/backup.c b/block/backup.c
index 7978ae2..d0b0225 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -307,7 +307,7 @@ static void coroutine_fn backup_run(void *opaque)
 BACKUP_SECTORS_PER_CLUSTER - i, &n);
 i += n;
 
-if (alloced == 1) {
+if (alloced == 1 || n == 0) {
 break;
 }
 }
diff --git a/tests/qemu-iotests/028 b/tests/qemu-iotests/028
index a99e4fa..d5718c5 100755
--- a/tests/qemu-iotests/028
+++ b/tests/qemu-iotests/028
@@ -33,7 +33,8 @@ status=1  # failure is the default!
 
 _cleanup()
 {
-   _cleanup_test_img
+rm -f "${TEST_IMG}.copy"
+_cleanup_test_img
 }
 trap "_cleanup; exit \$status" 0 1 2 3 15
 
@@ -41,6 +42,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
 . ./common.rc
 . ./common.filter
 . ./common.pattern
+. ./common.qemu
 
 # Any format supporting backing files except vmdk and qcow which do not support
 # smaller backing files.
@@ -99,6 +101,29 @@ _check_test_img
 # Rebase it on top of its base image
 $QEMU_IMG rebase -b "$TEST_IMG.base" "$TEST_IMG"
 
+echo
+echo block-backup
+echo
+
+qemu_comm_method="monitor"
+_launch_qemu -drive file="${TEST_IMG}",cache=${CACHEMODE},id=disk
+h=$QEMU_HANDLE
+QEMU_COMM_TIMEOUT=1
+
+_send_qemu_cmd $h "drive_backup disk ${TEST_IMG}.copy" "(qemu)"
+qemu_cmd_repeat=20 _send_qemu_cmd $h "info block-jobs" "No active jobs"
+_send_qemu_cmd $h 'quit' ""
+
+# Base image sectors
+TEST_IMG="${TEST_IMG}.copy" io readv $(( offset )) 512 1024 32
+
+# Image sectors
+TEST_IMG="${TEST_IMG}.copy" io readv $(( offset + 512 )) 512 1024 64
+
+# Zero sectors beyond end of base image
+TEST_IMG="${TEST_IMG}.copy" io_zero readv $(( offset + 32 * 1024 )) 512 1024 32
+
+
 _check_test_img
 
 # success, all done
diff --git a/tests/qemu-iotests/028.out b/tests/qemu-iotests/028.out
index 8affb7f..38099e4 100644
--- a/tests/qemu-iotests/028.out
+++ b/tests/qemu-iotests/028.out
@@ -465,5 +465,274 @@ read 512/512 bytes at offset 3221257728
 read 512/512 bytes at offset 3221258752
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 No errors were found on the image.
+
+block-backup
+
+QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) 
ddrdridrivdrivedrive_drive_bdrive_badrive_bacdrive_backdrive_backudrive_backupdrive_backup
 drive_backup 
ddrive_backup 
didrive_backup 
disdrive_backup 
diskdrive_backup disk 
drive_backup disk 
/drive_backup disk 
/hdrive_backup 
disk /ho!
 drive_backup disk 
/homdrive_backup
 disk 
/homedrive_backup
 disk 
/home/drive_backup
 disk 
/home/kdrive_backup
 disk 
/home/kwdrive_backup
 disk 
/home/kwodrive_backup
 disk 
/home/kwoldrive_backup
 disk 
/home/kwolf

[Qemu-devel] [PULL v2 for-2.1 17/22] qtest: fix vhost-user-test compilation with old GLib

2014-07-14 Thread Kevin Wolf
From: Nikolay Nikolaev 

Mising G_TIME_SPAN_SECOND definition breaks the RHEL6 compilation as GLib
version before 2.26 does not have it. In such case just define it.

Reported-by: Kevin Wolf 
Signed-off-by: Nikolay Nikolaev 
Tested-by: Kevin Wolf 
Signed-off-by: Kevin Wolf 
---
 tests/vhost-user-test.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c
index 2af2381..406ba70 100644
--- a/tests/vhost-user-test.c
+++ b/tests/vhost-user-test.c
@@ -22,6 +22,10 @@
 #include 
 
 /* GLIB version compatibility flags */
+#if !GLIB_CHECK_VERSION(2, 26, 0)
+#define G_TIME_SPAN_SECOND  (G_GINT64_CONSTANT(100))
+#endif
+
 #if GLIB_CHECK_VERSION(2, 28, 0)
 #define HAVE_MONOTONIC_TIME
 #endif
-- 
1.8.3.1




[Qemu-devel] [PULL v2 for-2.1 02/22] block: Fix bdrv_is_allocated() return value

2014-07-14 Thread Kevin Wolf
bdrv_is_allocated() should return either 0 or 1 in successful cases.
We're lucky that currently, the callers that rely on this (e.g. because
they check for ret == 1) don't seem to break badly. They just might skip
some optimisation or in the case of qemu-io 'map' print separate lines
where a single line would suffice. In theory, a wrong allocation status
could lead to image corruption with certain operations, so let's fix
this quickly.

Signed-off-by: Kevin Wolf 
Reviewed-by: Eric Blake 
---
 block.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/block.c b/block.c
index 8800a6b..c9629a4 100644
--- a/block.c
+++ b/block.c
@@ -4040,7 +4040,7 @@ int coroutine_fn bdrv_is_allocated(BlockDriverState *bs, 
int64_t sector_num,
 if (ret < 0) {
 return ret;
 }
-return (ret & BDRV_BLOCK_ALLOCATED);
+return !!(ret & BDRV_BLOCK_ALLOCATED);
 }
 
 /*
-- 
1.8.3.1




[Qemu-devel] [PULL v2 for-2.1 09/22] qed: Make qiov match request size until backing file EOF

2014-07-14 Thread Kevin Wolf
If a QED image has a shorter backing file and a read request to
unallocated clusters goes across EOF of the backing file, the backing
file sees a shortened request and the rest is filled with zeros.
However, the original too long qiov was used with the shortened request.

This patch makes the qiov size match the request size, avoiding a
potential buffer overflow in raw-posix.

Signed-off-by: Kevin Wolf 
Reviewed-by: Eric Blake 
---
 block/qed.c | 38 ++
 block/qed.h |  1 +
 2 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/block/qed.c b/block/qed.c
index b69374b..cd4872b 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -761,17 +761,19 @@ static BDRVQEDState *acb_to_s(QEDAIOCB *acb)
 /**
  * Read from the backing file or zero-fill if no backing file
  *
- * @s:  QED state
- * @pos:Byte position in device
- * @qiov:   Destination I/O vector
- * @cb: Completion function
- * @opaque: User data for completion function
+ * @s:  QED state
+ * @pos:Byte position in device
+ * @qiov:   Destination I/O vector
+ * @backing_qiov:   Possibly shortened copy of qiov, to be allocated here
+ * @cb: Completion function
+ * @opaque: User data for completion function
  *
  * This function reads qiov->size bytes starting at pos from the backing file.
  * If there is no backing file then zeroes are read.
  */
 static void qed_read_backing_file(BDRVQEDState *s, uint64_t pos,
   QEMUIOVector *qiov,
+  QEMUIOVector **backing_qiov,
   BlockDriverCompletionFunc *cb, void *opaque)
 {
 uint64_t backing_length = 0;
@@ -804,15 +806,21 @@ static void qed_read_backing_file(BDRVQEDState *s, 
uint64_t pos,
 /* If the read straddles the end of the backing file, shorten it */
 size = MIN((uint64_t)backing_length - pos, qiov->size);
 
+assert(*backing_qiov == NULL);
+*backing_qiov = g_new(QEMUIOVector, 1);
+qemu_iovec_init(*backing_qiov, qiov->niov);
+qemu_iovec_concat(*backing_qiov, qiov, 0, size);
+
 BLKDBG_EVENT(s->bs->file, BLKDBG_READ_BACKING_AIO);
 bdrv_aio_readv(s->bs->backing_hd, pos / BDRV_SECTOR_SIZE,
-   qiov, size / BDRV_SECTOR_SIZE, cb, opaque);
+   *backing_qiov, size / BDRV_SECTOR_SIZE, cb, opaque);
 }
 
 typedef struct {
 GenericCB gencb;
 BDRVQEDState *s;
 QEMUIOVector qiov;
+QEMUIOVector *backing_qiov;
 struct iovec iov;
 uint64_t offset;
 } CopyFromBackingFileCB;
@@ -829,6 +837,12 @@ static void qed_copy_from_backing_file_write(void *opaque, 
int ret)
 CopyFromBackingFileCB *copy_cb = opaque;
 BDRVQEDState *s = copy_cb->s;
 
+if (copy_cb->backing_qiov) {
+qemu_iovec_destroy(copy_cb->backing_qiov);
+g_free(copy_cb->backing_qiov);
+copy_cb->backing_qiov = NULL;
+}
+
 if (ret) {
 qed_copy_from_backing_file_cb(copy_cb, ret);
 return;
@@ -866,11 +880,12 @@ static void qed_copy_from_backing_file(BDRVQEDState *s, 
uint64_t pos,
 copy_cb = gencb_alloc(sizeof(*copy_cb), cb, opaque);
 copy_cb->s = s;
 copy_cb->offset = offset;
+copy_cb->backing_qiov = NULL;
 copy_cb->iov.iov_base = qemu_blockalign(s->bs, len);
 copy_cb->iov.iov_len = len;
 qemu_iovec_init_external(©_cb->qiov, ©_cb->iov, 1);
 
-qed_read_backing_file(s, pos, ©_cb->qiov,
+qed_read_backing_file(s, pos, ©_cb->qiov, ©_cb->backing_qiov,
   qed_copy_from_backing_file_write, copy_cb);
 }
 
@@ -1313,7 +1328,7 @@ static void qed_aio_read_data(void *opaque, int ret,
 return;
 } else if (ret != QED_CLUSTER_FOUND) {
 qed_read_backing_file(s, acb->cur_pos, &acb->cur_qiov,
-  qed_aio_next_io, acb);
+  &acb->backing_qiov, qed_aio_next_io, acb);
 return;
 }
 
@@ -1339,6 +1354,12 @@ static void qed_aio_next_io(void *opaque, int ret)
 
 trace_qed_aio_next_io(s, acb, ret, acb->cur_pos + acb->cur_qiov.size);
 
+if (acb->backing_qiov) {
+qemu_iovec_destroy(acb->backing_qiov);
+g_free(acb->backing_qiov);
+acb->backing_qiov = NULL;
+}
+
 /* Handle I/O error */
 if (ret) {
 qed_aio_complete(acb, ret);
@@ -1378,6 +1399,7 @@ static BlockDriverAIOCB *qed_aio_setup(BlockDriverState 
*bs,
 acb->qiov_offset = 0;
 acb->cur_pos = (uint64_t)sector_num * BDRV_SECTOR_SIZE;
 acb->end_pos = acb->cur_pos + nb_sectors * BDRV_SECTOR_SIZE;
+acb->backing_qiov = NULL;
 acb->request.l2_table = NULL;
 qemu_iovec_init(&acb->cur_qiov, qiov->niov);
 
diff --git a/block/qed.h b/block/qed.h
index b024751..2b0e724 100644
--- a/block/qed.h
+++ b/block/qed.h
@@ -142,6 +142,7 @@ typedef struct QEDAIOCB {
 
 /* Current cluster scatter-gather list */
 QEMUIOVector cur_qiov;
+QEMUIOVector *backing_qiov;
 uint64_t cur_po

[Qemu-devel] [PULL v2 for-2.1 10/22] block: Assert qiov length matches request length

2014-07-14 Thread Kevin Wolf
At least raw-posix relies on this because it can allocate bounce buffers
based on the request length, but access it using all of the qiov entries
later.

Signed-off-by: Kevin Wolf 
Reviewed-by: Max Reitz 
---
 block.c   |  2 ++
 block/raw-posix.c | 15 +++
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/block.c b/block.c
index 0143268..3e252a2 100644
--- a/block.c
+++ b/block.c
@@ -3010,6 +3010,7 @@ static int coroutine_fn 
bdrv_aligned_preadv(BlockDriverState *bs,
 
 assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0);
 assert((bytes & (BDRV_SECTOR_SIZE - 1)) == 0);
+assert(!qiov || bytes == qiov->size);
 
 /* Handle Copy on Read and associated serialisation */
 if (flags & BDRV_REQ_COPY_ON_READ) {
@@ -3279,6 +3280,7 @@ static int coroutine_fn 
bdrv_aligned_pwritev(BlockDriverState *bs,
 
 assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0);
 assert((bytes & (BDRV_SECTOR_SIZE - 1)) == 0);
+assert(!qiov || bytes == qiov->size);
 
 waited = wait_serialising_requests(req);
 assert(!waited || !req->serialising);
diff --git a/block/raw-posix.c b/block/raw-posix.c
index a857def..2bcc73d 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -790,6 +790,7 @@ static ssize_t handle_aiocb_rw(RawPosixAIOData *aiocb)
 memcpy(p, aiocb->aio_iov[i].iov_base, aiocb->aio_iov[i].iov_len);
 p += aiocb->aio_iov[i].iov_len;
 }
+assert(p - buf == aiocb->aio_nbytes);
 }
 
 nbytes = handle_aiocb_rw_linear(aiocb, buf);
@@ -804,9 +805,11 @@ static ssize_t handle_aiocb_rw(RawPosixAIOData *aiocb)
 copy = aiocb->aio_iov[i].iov_len;
 }
 memcpy(aiocb->aio_iov[i].iov_base, p, copy);
+assert(count >= copy);
 p += copy;
 count -= copy;
 }
+assert(count == 0);
 }
 qemu_vfree(buf);
 
@@ -993,12 +996,14 @@ static int paio_submit_co(BlockDriverState *bs, int fd,
 acb->aio_type = type;
 acb->aio_fildes = fd;
 
+acb->aio_nbytes = nb_sectors * BDRV_SECTOR_SIZE;
+acb->aio_offset = sector_num * BDRV_SECTOR_SIZE;
+
 if (qiov) {
 acb->aio_iov = qiov->iov;
 acb->aio_niov = qiov->niov;
+assert(qiov->size == acb->aio_nbytes);
 }
-acb->aio_nbytes = nb_sectors * 512;
-acb->aio_offset = sector_num * 512;
 
 trace_paio_submit_co(sector_num, nb_sectors, type);
 pool = aio_get_thread_pool(bdrv_get_aio_context(bs));
@@ -1016,12 +1021,14 @@ static BlockDriverAIOCB *paio_submit(BlockDriverState 
*bs, int fd,
 acb->aio_type = type;
 acb->aio_fildes = fd;
 
+acb->aio_nbytes = nb_sectors * BDRV_SECTOR_SIZE;
+acb->aio_offset = sector_num * BDRV_SECTOR_SIZE;
+
 if (qiov) {
 acb->aio_iov = qiov->iov;
 acb->aio_niov = qiov->niov;
+assert(qiov->size == acb->aio_nbytes);
 }
-acb->aio_nbytes = nb_sectors * 512;
-acb->aio_offset = sector_num * 512;
 
 trace_paio_submit(acb, opaque, sector_num, nb_sectors, type);
 pool = aio_get_thread_pool(bdrv_get_aio_context(bs));
-- 
1.8.3.1




[Qemu-devel] [PULL v2 for-2.1 05/22] test-aio: fix GSource-based timer test

2014-07-14 Thread Kevin Wolf
From: Paolo Bonzini 

The current test depends too much on the implementation of the AioContext
GSource.  Just iterate on the main loop until the callback has been invoked
the right number of times.

Signed-off-by: Paolo Bonzini 
Signed-off-by: Kevin Wolf 
---
 tests/test-aio.c | 13 ++---
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/tests/test-aio.c b/tests/test-aio.c
index e5f8b55..264dab9 100644
--- a/tests/test-aio.c
+++ b/tests/test-aio.c
@@ -806,17 +806,16 @@ static void test_source_timer_schedule(void)
 g_usleep(1 * G_USEC_PER_SEC);
 g_assert_cmpint(data.n, ==, 0);
 
-g_assert(g_main_context_iteration(NULL, false));
+g_assert(g_main_context_iteration(NULL, true));
 g_assert_cmpint(data.n, ==, 1);
+expiry += data.ns;
 
-/* The comment above was not kidding when it said this wakes up itself */
-do {
-g_assert(g_main_context_iteration(NULL, true));
-} while (qemu_clock_get_ns(data.clock_type) <= expiry);
-g_usleep(1 * G_USEC_PER_SEC);
-g_main_context_iteration(NULL, false);
+while (data.n < 2) {
+g_main_context_iteration(NULL, true);
+}
 
 g_assert_cmpint(data.n, ==, 2);
+g_assert(qemu_clock_get_ns(data.clock_type) > expiry);
 
 aio_set_fd_handler(ctx, pipefd[0], NULL, NULL, NULL);
 close(pipefd[0]);
-- 
1.8.3.1




[Qemu-devel] [PULL v2 for-2.1 15/22] AioContext: do not rely on aio_poll(ctx, true) result to end a loop

2014-07-14 Thread Kevin Wolf
From: Paolo Bonzini 

Currently, whenever aio_poll(ctx, true) has completed all pending
work it returns true *and* the next call to aio_poll(ctx, true)
will not block.

This invariant has its roots in qemu_aio_flush()'s implementation
as "while (qemu_aio_wait()) {}".  However, qemu_aio_flush() does
not exist anymore and bdrv_drain_all() is implemented differently;
and this invariant is complicated to maintain and subtly different
from the return value of GMainLoop's g_main_context_iteration.

All calls to aio_poll(ctx, true) except one are guarded by a
while() loop checking for a request to be incomplete, or a
BlockDriverState to be idle.  The one remaining call (in
iothread.c) uses this to delay the aio_context_release/acquire
pair until the AioContext is quiescent, however:

- we can do the same just by using non-blocking aio_poll,
  similar to how vl.c invokes main_loop_wait

- it is buggy, because it does not ensure that the AioContext
  is released between an aio_notify and the next time the
  iothread goes to sleep.  This leads to hangs when stopping
  the dataplane thread.

In the end, these semantics are a bad match for the current
users of AioContext.  So modify that one exception in iothread.c,
which also fixes the hangs, as well as the testcase so that
it use the same idiom as the actual QEMU code.

Reported-by: Christian Borntraeger 
Tested-by: Christian Borntraeger 
Signed-off-by: Paolo Bonzini 
Signed-off-by: Kevin Wolf 
---
 include/block/aio.h |  6 +++---
 iothread.c  |  5 -
 tests/test-aio.c| 25 +
 3 files changed, 20 insertions(+), 16 deletions(-)

diff --git a/include/block/aio.h b/include/block/aio.h
index 433e7ff..c23de3c 100644
--- a/include/block/aio.h
+++ b/include/block/aio.h
@@ -214,9 +214,9 @@ bool aio_pending(AioContext *ctx);
 /* Progress in completing AIO work to occur.  This can issue new pending
  * aio as a result of executing I/O completion or bh callbacks.
  *
- * If there is no pending AIO operation or completion (bottom half),
- * return false.  If there are pending AIO operations of bottom halves,
- * return true.
+ * Return whether any progress was made by executing AIO or bottom half
+ * handlers.  If @blocking == true, this should always be true except
+ * if someone called aio_notify.
  *
  * If there are no pending bottom halves, but there are pending AIO
  * operations, it may not be possible to make any progress without
diff --git a/iothread.c b/iothread.c
index 1fbf9f1..d9403cf 100644
--- a/iothread.c
+++ b/iothread.c
@@ -30,6 +30,7 @@ typedef ObjectClass IOThreadClass;
 static void *iothread_run(void *opaque)
 {
 IOThread *iothread = opaque;
+bool blocking;
 
 qemu_mutex_lock(&iothread->init_done_lock);
 iothread->thread_id = qemu_get_thread_id();
@@ -38,8 +39,10 @@ static void *iothread_run(void *opaque)
 
 while (!iothread->stopping) {
 aio_context_acquire(iothread->ctx);
-while (!iothread->stopping && aio_poll(iothread->ctx, true)) {
+blocking = true;
+while (!iothread->stopping && aio_poll(iothread->ctx, blocking)) {
 /* Progress was made, keep going */
+blocking = false;
 }
 aio_context_release(iothread->ctx);
 }
diff --git a/tests/test-aio.c b/tests/test-aio.c
index 264dab9..4c40a49 100644
--- a/tests/test-aio.c
+++ b/tests/test-aio.c
@@ -24,14 +24,6 @@ typedef struct {
 bool auto_set;
 } EventNotifierTestData;
 
-/* Wait until there are no more BHs or AIO requests */
-static void wait_for_aio(void)
-{
-while (aio_poll(ctx, true)) {
-/* Do nothing */
-}
-}
-
 /* Wait until event notifier becomes inactive */
 static void wait_until_inactive(EventNotifierTestData *data)
 {
@@ -204,7 +196,9 @@ static void test_bh_schedule10(void)
 g_assert(aio_poll(ctx, true));
 g_assert_cmpint(data.n, ==, 2);
 
-wait_for_aio();
+while (data.n < 10) {
+aio_poll(ctx, true);
+}
 g_assert_cmpint(data.n, ==, 10);
 
 g_assert(!aio_poll(ctx, false));
@@ -252,7 +246,9 @@ static void test_bh_delete_from_cb(void)
 qemu_bh_schedule(data1.bh);
 g_assert_cmpint(data1.n, ==, 0);
 
-wait_for_aio();
+while (data1.n < data1.max) {
+aio_poll(ctx, true);
+}
 g_assert_cmpint(data1.n, ==, data1.max);
 g_assert(data1.bh == NULL);
 
@@ -287,7 +283,12 @@ static void test_bh_delete_from_cb_many(void)
 g_assert_cmpint(data4.n, ==, 1);
 g_assert(data1.bh == NULL);
 
-wait_for_aio();
+while (data1.n < data1.max ||
+   data2.n < data2.max ||
+   data3.n < data3.max ||
+   data4.n < data4.max) {
+aio_poll(ctx, true);
+}
 g_assert_cmpint(data1.n, ==, data1.max);
 g_assert_cmpint(data2.n, ==, data2.max);
 g_assert_cmpint(data3.n, ==, data3.max);
@@ -306,7 +307,7 @@ static void test_bh_flush(void)
 qemu_bh_schedule(data.bh);
 g_assert_cmpint(data.n, ==, 0);
 
-wait_for_aio();
+g_assert(aio_poll(ctx, tru

[Qemu-devel] [PULL v2 for-2.1 06/22] AioContext: speed up aio_notify

2014-07-14 Thread Kevin Wolf
From: Paolo Bonzini 

In many cases, the call to event_notifier_set in aio_notify is unnecessary.
In particular, if we are executing aio_dispatch, or if aio_poll is not
blocking, we know that we will soon get to the next loop iteration (if
necessary); the thread that hosts the AioContext's event loop does not
need any nudging.

The patch includes a Promela formal model that shows that this really
works and does not need any further complication such as generation
counts.  It needs a memory barrier though.

The generation counts are not needed because any change to
ctx->dispatching after the memory barrier is okay for aio_notify.
If it changes from zero to one, it is the right thing to skip
event_notifier_set.  If it changes from one to zero, the
event_notifier_set is unnecessary but harmless.

Signed-off-by: Paolo Bonzini 
Signed-off-by: Kevin Wolf 
---
 aio-posix.c |  34 +++-
 async.c |  19 -
 docs/aio_notify.promela | 104 
 include/block/aio.h |   9 +
 4 files changed, 164 insertions(+), 2 deletions(-)
 create mode 100644 docs/aio_notify.promela

diff --git a/aio-posix.c b/aio-posix.c
index 44c4df3..2eada2e 100644
--- a/aio-posix.c
+++ b/aio-posix.c
@@ -175,11 +175,38 @@ static bool aio_dispatch(AioContext *ctx)
 bool aio_poll(AioContext *ctx, bool blocking)
 {
 AioHandler *node;
+bool was_dispatching;
 int ret;
 bool progress;
 
+was_dispatching = ctx->dispatching;
 progress = false;
 
+/* aio_notify can avoid the expensive event_notifier_set if
+ * everything (file descriptors, bottom halves, timers) will
+ * be re-evaluated before the next blocking poll().  This happens
+ * in two cases:
+ *
+ * 1) when aio_poll is called with blocking == false
+ *
+ * 2) when we are called after poll().  If we are called before
+ *poll(), bottom halves will not be re-evaluated and we need
+ *aio_notify() if blocking == true.
+ *
+ * The first aio_dispatch() only does something when AioContext is
+ * running as a GSource, and in that case aio_poll is used only
+ * with blocking == false, so this optimization is already quite
+ * effective.  However, the code is ugly and should be restructured
+ * to have a single aio_dispatch() call.  To do this, we need to
+ * reorganize aio_poll into a prepare/poll/dispatch model like
+ * glib's.
+ *
+ * If we're in a nested event loop, ctx->dispatching might be true.
+ * In that case we can restore it just before returning, but we
+ * have to clear it now.
+ */
+aio_set_dispatching(ctx, !blocking);
+
 /*
  * If there are callbacks left that have been queued, we need to call them.
  * Do not call select in this case, because it is possible that the caller
@@ -190,12 +217,14 @@ bool aio_poll(AioContext *ctx, bool blocking)
 progress = true;
 }
 
+/* Re-evaluate condition (1) above.  */
+aio_set_dispatching(ctx, !blocking);
 if (aio_dispatch(ctx)) {
 progress = true;
 }
 
 if (progress && !blocking) {
-return true;
+goto out;
 }
 
 ctx->walking_handlers++;
@@ -234,9 +263,12 @@ bool aio_poll(AioContext *ctx, bool blocking)
 }
 
 /* Run dispatch even if there were no readable fds to run timers */
+aio_set_dispatching(ctx, true);
 if (aio_dispatch(ctx)) {
 progress = true;
 }
 
+out:
+aio_set_dispatching(ctx, was_dispatching);
 return progress;
 }
diff --git a/async.c b/async.c
index 5b6fe6b..34af0b2 100644
--- a/async.c
+++ b/async.c
@@ -26,6 +26,7 @@
 #include "block/aio.h"
 #include "block/thread-pool.h"
 #include "qemu/main-loop.h"
+#include "qemu/atomic.h"
 
 /***/
 /* bottom halves (can be seen as timers which expire ASAP) */
@@ -247,9 +248,25 @@ ThreadPool *aio_get_thread_pool(AioContext *ctx)
 return ctx->thread_pool;
 }
 
+void aio_set_dispatching(AioContext *ctx, bool dispatching)
+{
+ctx->dispatching = dispatching;
+if (!dispatching) {
+/* Write ctx->dispatching before reading e.g. bh->scheduled.
+ * Optimization: this is only needed when we're entering the "unsafe"
+ * phase where other threads must call event_notifier_set.
+ */
+smp_mb();
+}
+}
+
 void aio_notify(AioContext *ctx)
 {
-event_notifier_set(&ctx->notifier);
+/* Write e.g. bh->scheduled before reading ctx->dispatching.  */
+smp_mb();
+if (!ctx->dispatching) {
+event_notifier_set(&ctx->notifier);
+}
 }
 
 static void aio_timerlist_notify(void *opaque)
diff --git a/docs/aio_notify.promela b/docs/aio_notify.promela
new file mode 100644
index 000..ad3f6f0
--- /dev/null
+++ b/docs/aio_notify.promela
@@ -0,0 +1,104 @@
+/*
+ * This model describes the interaction between aio_set_dispatching()
+ * and aio_notify().
+ *
+ * Author: Paolo Bonzin

[Qemu-devel] [PULL v2 for-2.1 07/22] block: Make qiov match the request size until EOF

2014-07-14 Thread Kevin Wolf
If a read request goes across EOF, the block driver sees a shortened
request that stops at EOF (the rest is memsetted in block.c), however
the original qiov was used for this request.

This patch makes the qiov size match the request size, avoiding a
potential buffer overflow in raw-posix.

Signed-off-by: Kevin Wolf 
Reviewed-by: Max Reitz 
---
 block.c | 16 ++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/block.c b/block.c
index 510430d..0143268 100644
--- a/block.c
+++ b/block.c
@@ -3054,8 +3054,20 @@ static int coroutine_fn 
bdrv_aligned_preadv(BlockDriverState *bs,
 max_nb_sectors = ROUND_UP(MAX(0, total_sectors - sector_num),
   align >> BDRV_SECTOR_BITS);
 if (max_nb_sectors > 0) {
-ret = drv->bdrv_co_readv(bs, sector_num,
- MIN(nb_sectors, max_nb_sectors), qiov);
+QEMUIOVector local_qiov;
+size_t local_sectors;
+
+max_nb_sectors = MIN(max_nb_sectors, SIZE_MAX / BDRV_SECTOR_BITS);
+local_sectors = MIN(max_nb_sectors, nb_sectors);
+
+qemu_iovec_init(&local_qiov, qiov->niov);
+qemu_iovec_concat(&local_qiov, qiov, 0,
+  local_sectors * BDRV_SECTOR_SIZE);
+
+ret = drv->bdrv_co_readv(bs, sector_num, local_sectors,
+ &local_qiov);
+
+qemu_iovec_destroy(&local_qiov);
 } else {
 ret = 0;
 }
-- 
1.8.3.1




[Qemu-devel] [PULL v2 for-2.1 11/22] virtio-blk: avoid dataplane VirtIOBlockReq early free

2014-07-14 Thread Kevin Wolf
From: Stefan Hajnoczi 

VirtIOBlockReq is freed later by virtio_blk_free_request() in
hw/block/virtio-blk.c.  Remove this extraneous g_slice_free().

This patch fixes the following segfault:

  0x556373af in virtio_blk_rw_complete (opaque=0x565ff5e0, ret=0) 
at hw/block/virtio-blk.c:99
  99  bdrv_acct_done(req->dev->bs, &req->acct);
  (gdb) print req
  $1 = (VirtIOBlockReq *) 0x565ff5e0
  (gdb) print req->dev
  $2 = (VirtIOBlock *) 0x0
  (gdb) bt
  #0  0x556373af in virtio_blk_rw_complete (opaque=0x565ff5e0, 
ret=0) at hw/block/virtio-blk.c:99
  #1  0x55840ebe in bdrv_co_em_bh (opaque=0x566152d0) at 
block.c:4675
  #2  0x5583de77 in aio_bh_poll (ctx=ctx@entry=0x563a8150) at 
async.c:81
  #3  0x5584b7a7 in aio_poll (ctx=0x563a8150, 
blocking=blocking@entry=true) at aio-posix.c:188
  #4  0x556e520e in iothread_run (opaque=0x563a7fd8) at 
iothread.c:41
  #5  0x742ba124 in start_thread () from /usr/lib/libpthread.so.0
  #6  0x716d14bd in clone () from /usr/lib/libc.so.6

Reported-by: Max Reitz 
Cc: Fam Zheng 
Signed-off-by: Stefan Hajnoczi 
Tested-by: Christian Borntraeger 
Signed-off-by: Kevin Wolf 
---
 hw/block/dataplane/virtio-blk.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
index 4bc0729..bed9f13 100644
--- a/hw/block/dataplane/virtio-blk.c
+++ b/hw/block/dataplane/virtio-blk.c
@@ -68,7 +68,6 @@ static void complete_request_vring(VirtIOBlockReq *req, 
unsigned char status)
 vring_push(&req->dev->dataplane->vring, req->elem,
req->qiov.size + sizeof(*req->in));
 notify_guest(req->dev->dataplane);
-g_slice_free(VirtIOBlockReq, req);
 }
 
 static void handle_notify(EventNotifier *e)
-- 
1.8.3.1




[Qemu-devel] [PULL v2 for-2.1 08/22] qcow2: Make qiov match request size until backing file EOF

2014-07-14 Thread Kevin Wolf
If a qcow2 image has a shorter backing file and a read request to
unallocated clusters goes across EOF of the backing file, the backing
file sees a shortened request and the rest is filled with zeros.
However, the original too long qiov was used with the shortened request.

This patch makes the qiov size match the request size, avoiding a
potential buffer overflow in raw-posix.

Signed-off-by: Kevin Wolf 
Reviewed-by: Max Reitz 
---
 block/qcow2.c | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index 67e55c9..b0faa69 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1020,11 +1020,20 @@ static coroutine_fn int qcow2_co_readv(BlockDriverState 
*bs, int64_t sector_num,
 n1 = qcow2_backing_read1(bs->backing_hd, &hd_qiov,
 sector_num, cur_nr_sectors);
 if (n1 > 0) {
+QEMUIOVector local_qiov;
+
+qemu_iovec_init(&local_qiov, hd_qiov.niov);
+qemu_iovec_concat(&local_qiov, &hd_qiov, 0,
+  n1 * BDRV_SECTOR_SIZE);
+
 BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
 qemu_co_mutex_unlock(&s->lock);
 ret = bdrv_co_readv(bs->backing_hd, sector_num,
-n1, &hd_qiov);
+n1, &local_qiov);
 qemu_co_mutex_lock(&s->lock);
+
+qemu_iovec_destroy(&local_qiov);
+
 if (ret < 0) {
 goto fail;
 }
-- 
1.8.3.1




[Qemu-devel] [PULL v2 for-2.1 21/22] virtio-blk: Treat read/write beyond end as invalid

2014-07-14 Thread Kevin Wolf
From: Markus Armbruster 

The block layer fails such reads and writes just fine.  However, they
then get treated like valid operations that fail: the error action
gets executed.  Unwanted; reporting the error to the guest is the only
sensible action.

Reject them before passing them to the block layer.  This bypasses the
error action and I/O accounting.

Signed-off-by: Markus Armbruster 
Reviewed-by: Fam Zheng 
Signed-off-by: Kevin Wolf 
---
 hw/block/virtio-blk.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index e6e6276..c241c50 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -291,12 +291,19 @@ static void virtio_blk_handle_flush(VirtIOBlockReq *req, 
MultiReqBuffer *mrb)
 static bool virtio_blk_sect_range_ok(VirtIOBlock *dev,
  uint64_t sector, size_t size)
 {
+uint64_t nb_sectors = size >> BDRV_SECTOR_BITS;
+uint64_t total_sectors;
+
 if (sector & dev->sector_mask) {
 return false;
 }
 if (size % dev->conf->logical_block_size) {
 return false;
 }
+bdrv_get_geometry(dev->bs, &total_sectors);
+if (sector > total_sectors || nb_sectors > total_sectors - sector) {
+return false;
+}
 return true;
 }
 
-- 
1.8.3.1




[Qemu-devel] [PULL v2 for-2.1 13/22] virtio-blk: avoid g_slice_new0() for VirtIOBlockReq and VirtQueueElement

2014-07-14 Thread Kevin Wolf
From: Stefan Hajnoczi 

In commit de6c8042ec55da18702fa51f09072fcaa315edc3 ("virtio-blk: Avoid
zeroing every request structure") we avoided the 40 KB memset when
allocating VirtIOBlockReq.

The memset was reintroduced in commit
671ec3f056559f22a2531a91dce3a258b9b5eb8a ("virtio-blk: Convert
VirtIOBlockReq.elem to pointer").

It must be fixed again to avoid a performance regression.

Cc: Fam Zheng 
Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Kevin Wolf 
---
 hw/block/virtio-blk.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index aec3146..b06a56d 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -31,9 +31,11 @@
 
 static VirtIOBlockReq *virtio_blk_alloc_request(VirtIOBlock *s)
 {
-VirtIOBlockReq *req = g_slice_new0(VirtIOBlockReq);
+VirtIOBlockReq *req = g_slice_new(VirtIOBlockReq);
 req->dev = s;
-req->elem = g_slice_new0(VirtQueueElement);
+req->qiov.size = 0;
+req->next = NULL;
+req->elem = g_slice_new(VirtQueueElement);
 return req;
 }
 
-- 
1.8.3.1




[Qemu-devel] [PULL v2 for-2.1 22/22] ide: Treat read/write beyond end as invalid

2014-07-14 Thread Kevin Wolf
From: Markus Armbruster 

The block layer fails such reads and writes just fine.  However, they
then get treated like valid operations that fail: the error action
gets executed.  Unwanted; reporting the error to the guest is the only
sensible action.

Reject them before passing them to the block layer.  This bypasses the
error action and I/O accounting.  Not quite correct for DMA, because
DMA can fail after some success, and when that happens, the part that
succeeded isn't counted.  Tolerable, because I/O accounting is an
inconsistent mess anyway.

Signed-off-by: Markus Armbruster 
Signed-off-by: Kevin Wolf 
---
 hw/ide/core.c | 28 
 1 file changed, 28 insertions(+)

diff --git a/hw/ide/core.c b/hw/ide/core.c
index 3a38f1e..db191a6 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -499,6 +499,18 @@ static void ide_rw_error(IDEState *s) {
 ide_set_irq(s->bus);
 }
 
+static bool ide_sect_range_ok(IDEState *s,
+  uint64_t sector, uint64_t nb_sectors)
+{
+uint64_t total_sectors;
+
+bdrv_get_geometry(s->bs, &total_sectors);
+if (sector > total_sectors || nb_sectors > total_sectors - sector) {
+return false;
+}
+return true;
+}
+
 static void ide_sector_read_cb(void *opaque, int ret)
 {
 IDEState *s = opaque;
@@ -554,6 +566,11 @@ void ide_sector_read(IDEState *s)
 printf("sector=%" PRId64 "\n", sector_num);
 #endif
 
+if (!ide_sect_range_ok(s, sector_num, n)) {
+ide_rw_error(s);
+return;
+}
+
 s->iov.iov_base = s->io_buffer;
 s->iov.iov_len  = n * BDRV_SECTOR_SIZE;
 qemu_iovec_init_external(&s->qiov, &s->iov, 1);
@@ -671,6 +688,12 @@ void ide_dma_cb(void *opaque, int ret)
sector_num, n, s->dma_cmd);
 #endif
 
+if (!ide_sect_range_ok(s, sector_num, n)) {
+dma_buf_commit(s);
+ide_dma_error(s);
+return;
+}
+
 switch (s->dma_cmd) {
 case IDE_DMA_READ:
 s->bus->dma->aiocb = dma_bdrv_read(s->bs, &s->sg, sector_num,
@@ -790,6 +813,11 @@ void ide_sector_write(IDEState *s)
 n = s->req_nb_sectors;
 }
 
+if (!ide_sect_range_ok(s, sector_num, n)) {
+ide_rw_error(s);
+return;
+}
+
 s->iov.iov_base = s->io_buffer;
 s->iov.iov_len  = n * BDRV_SECTOR_SIZE;
 qemu_iovec_init_external(&s->qiov, &s->iov, 1);
-- 
1.8.3.1




[Qemu-devel] [PULL v2 for-2.1 16/22] tests: Fix unterminated string output visitor enum human string

2014-07-14 Thread Kevin Wolf
From: Andreas Färber 

The buffer was being allocated of size string length plus two.
Around the string two quotes were being added, but no terminating NUL.
It was then compared using g_assert_cmpstr(), resulting in fairly random
assertion failures:

 ERROR:tests/test-string-output-visitor.c:213:test_visitor_out_enum: assertion 
failed (str == str_human): ("\"value1\"" == "\"value1\"\001EE\0171")

There is no g_assert_cmpnstr() counterpart, so use g_strdup_printf()
for safely assembling the string in the first place.

Cc: Hu Tao 
Cc: Michael S. Tsirkin 
Suggested-by: Eric Blake 
Fixes: b4900c0 tests: add human format test for string output visitor
Signed-off-by: Andreas Färber 
Reviewed-by: Eric Blake 
Signed-off-by: Kevin Wolf 
---
 tests/test-string-output-visitor.c | 7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/tests/test-string-output-visitor.c 
b/tests/test-string-output-visitor.c
index e89e43c..101fb27 100644
--- a/tests/test-string-output-visitor.c
+++ b/tests/test-string-output-visitor.c
@@ -196,16 +196,11 @@ static void test_visitor_out_enum(TestOutputVisitorData 
*data,
 
 for (i = 0; i < ENUM_ONE_MAX; i++) {
 char *str_human;
-int len;
 
 visit_type_EnumOne(data->ov, &i, "unused", &err);
 g_assert(!err);
 
-len = strlen(EnumOne_lookup[i]) + 2;
-str_human = g_malloc0(len);
-str_human[0] = '"';
-strncpy(str_human + 1, EnumOne_lookup[i], strlen(EnumOne_lookup[i]));
-str_human[len - 1] = '"';
+str_human = g_strdup_printf("\"%s\"", EnumOne_lookup[i]);
 
 str = string_output_get_string(data->sov);
 g_assert(str != NULL);
-- 
1.8.3.1




[Qemu-devel] [PULL v2 for-2.1 14/22] virtio-blk: embed VirtQueueElement in VirtIOBlockReq

2014-07-14 Thread Kevin Wolf
From: Stefan Hajnoczi 

The memory allocation between hw/block/virtio-blk.c,
hw/block/dataplane/virtio-blk.c, and hw/virtio/dataplane/vring.c is
messy.  Structs are allocated in different files than they are freed in.
This is risky and makes memory leaks easier.

Embed VirtQueueElement in VirtIOBlockReq to reduce the amount of memory
allocation we need to juggle.  This also makes vring.c and virtio.c
slightly more similar.

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Kevin Wolf 
---
 hw/block/dataplane/virtio-blk.c | 29 +++
 hw/block/virtio-blk.c   | 46 ++---
 hw/virtio/dataplane/vring.c | 17 +-
 include/hw/virtio/dataplane/vring.h |  2 +-
 include/hw/virtio/virtio-blk.h  |  6 -
 5 files changed, 48 insertions(+), 52 deletions(-)

diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
index bed9f13..227bb15 100644
--- a/hw/block/dataplane/virtio-blk.c
+++ b/hw/block/dataplane/virtio-blk.c
@@ -65,7 +65,7 @@ static void complete_request_vring(VirtIOBlockReq *req, 
unsigned char status)
 {
 stb_p(&req->in->status, status);
 
-vring_push(&req->dev->dataplane->vring, req->elem,
+vring_push(&req->dev->dataplane->vring, &req->elem,
req->qiov.size + sizeof(*req->in));
 notify_guest(req->dev->dataplane);
 }
@@ -74,33 +74,32 @@ static void handle_notify(EventNotifier *e)
 {
 VirtIOBlockDataPlane *s = container_of(e, VirtIOBlockDataPlane,
host_notifier);
-
-VirtQueueElement *elem;
-VirtIOBlockReq *req;
-int ret;
-MultiReqBuffer mrb = {
-.num_writes = 0,
-};
+VirtIOBlock *vblk = VIRTIO_BLK(s->vdev);
 
 event_notifier_test_and_clear(&s->host_notifier);
 bdrv_io_plug(s->blk->conf.bs);
 for (;;) {
+MultiReqBuffer mrb = {
+.num_writes = 0,
+};
+int ret;
+
 /* Disable guest->host notifies to avoid unnecessary vmexits */
 vring_disable_notification(s->vdev, &s->vring);
 
 for (;;) {
-ret = vring_pop(s->vdev, &s->vring, &elem);
+VirtIOBlockReq *req = virtio_blk_alloc_request(vblk);
+
+ret = vring_pop(s->vdev, &s->vring, &req->elem);
 if (ret < 0) {
-assert(elem == NULL);
+virtio_blk_free_request(req);
 break; /* no more requests */
 }
 
-trace_virtio_blk_data_plane_process_request(s, elem->out_num,
-elem->in_num, 
elem->index);
+trace_virtio_blk_data_plane_process_request(s, req->elem.out_num,
+req->elem.in_num,
+req->elem.index);
 
-req = g_slice_new(VirtIOBlockReq);
-req->dev = VIRTIO_BLK(s->vdev);
-req->elem = elem;
 virtio_blk_handle_request(req, &mrb);
 }
 
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index b06a56d..02cd6b0 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -29,20 +29,18 @@
 #include "hw/virtio/virtio-bus.h"
 #include "hw/virtio/virtio-access.h"
 
-static VirtIOBlockReq *virtio_blk_alloc_request(VirtIOBlock *s)
+VirtIOBlockReq *virtio_blk_alloc_request(VirtIOBlock *s)
 {
 VirtIOBlockReq *req = g_slice_new(VirtIOBlockReq);
 req->dev = s;
 req->qiov.size = 0;
 req->next = NULL;
-req->elem = g_slice_new(VirtQueueElement);
 return req;
 }
 
-static void virtio_blk_free_request(VirtIOBlockReq *req)
+void virtio_blk_free_request(VirtIOBlockReq *req)
 {
 if (req) {
-g_slice_free(VirtQueueElement, req->elem);
 g_slice_free(VirtIOBlockReq, req);
 }
 }
@@ -56,7 +54,7 @@ static void virtio_blk_complete_request(VirtIOBlockReq *req,
 trace_virtio_blk_req_complete(req, status);
 
 stb_p(&req->in->status, status);
-virtqueue_push(s->vq, req->elem, req->qiov.size + sizeof(*req->in));
+virtqueue_push(s->vq, &req->elem, req->qiov.size + sizeof(*req->in));
 virtio_notify(vdev, s->vq);
 }
 
@@ -121,7 +119,7 @@ static VirtIOBlockReq *virtio_blk_get_request(VirtIOBlock 
*s)
 {
 VirtIOBlockReq *req = virtio_blk_alloc_request(s);
 
-if (!virtqueue_pop(s->vq, req->elem)) {
+if (!virtqueue_pop(s->vq, &req->elem)) {
 virtio_blk_free_request(req);
 return NULL;
 }
@@ -254,7 +252,7 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
 {
 int status;
 
-status = virtio_blk_handle_scsi_req(req->dev, req->elem);
+status = virtio_blk_handle_scsi_req(req->dev, &req->elem);
 virtio_blk_req_complete(req, status);
 virtio_blk_free_request(req);
 }
@@ -351,12 +349,12 @@ static void virtio_blk_handle_read(VirtIOBlockReq *req)
 void virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb)
 {
 uint32_t type;
-struct iovec 

Re: [Qemu-devel] hw/arm: add Lego NXT board

2014-07-14 Thread Paolo Bonzini

Il 13/07/2014 16:20, Alexander Graf ha scritto:


The problem is that the qemu board I designed is not self-contained. It
allows the firmware to read/write IO memory in order to read back sensor
values from the simulated environment and to control actuators. The
environment simulator is an external program which is connected to
several qemu instances via posix named pipes using a simple
communication protocol. Without pipe interaction the emulator can still
be used to debug NXT firmware images without sensor/actuator interaction.


What does your protocol look like, and what kind of bus do the actual 
sensors and actuators use?


If it is I2C or SPI, having generic i2c-over-chardev or spi-over-chardev 
protocols and devices would be a nice addition to QEMU.


Paolo



[Qemu-devel] [PULL v2 for-2.1 18/22] dma-helpers: Fix too long qiov

2014-07-14 Thread Kevin Wolf
If the size of the scatter/gather list isn't a multiple of 512, the
number of sectors for the block layer request is rounded down, resulting
in a qiov that doesn't match the request length. Truncate the qiov to the
new length of the request.

This fixes the IDE qtest case /x86_64/ide/bmdma/short_prdt.

Signed-off-by: Kevin Wolf 
Reviewed-by: Eric Blake 
---
 dma-helpers.c |  4 
 include/qemu-common.h |  1 +
 util/iov.c| 13 +
 3 files changed, 18 insertions(+)

diff --git a/dma-helpers.c b/dma-helpers.c
index 53cbe92..499b52b 100644
--- a/dma-helpers.c
+++ b/dma-helpers.c
@@ -170,6 +170,10 @@ static void dma_bdrv_cb(void *opaque, int ret)
 return;
 }
 
+if (dbs->iov.size & ~BDRV_SECTOR_MASK) {
+qemu_iovec_discard_back(&dbs->iov, dbs->iov.size & ~BDRV_SECTOR_MASK);
+}
+
 dbs->acb = dbs->io_func(dbs->bs, dbs->sector_num, &dbs->iov,
 dbs->iov.size / 512, dma_bdrv_cb, dbs);
 assert(dbs->acb);
diff --git a/include/qemu-common.h b/include/qemu-common.h
index ae76197..6ef8282 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -329,6 +329,7 @@ size_t qemu_iovec_memset(QEMUIOVector *qiov, size_t offset,
  int fillc, size_t bytes);
 ssize_t qemu_iovec_compare(QEMUIOVector *a, QEMUIOVector *b);
 void qemu_iovec_clone(QEMUIOVector *dest, const QEMUIOVector *src, void *buf);
+void qemu_iovec_discard_back(QEMUIOVector *qiov, size_t bytes);
 
 bool buffer_is_zero(const void *buf, size_t len);
 
diff --git a/util/iov.c b/util/iov.c
index 2b4f46d..24566c8 100644
--- a/util/iov.c
+++ b/util/iov.c
@@ -550,3 +550,16 @@ size_t iov_discard_back(struct iovec *iov, unsigned int 
*iov_cnt,
 
 return total;
 }
+
+void qemu_iovec_discard_back(QEMUIOVector *qiov, size_t bytes)
+{
+size_t total;
+unsigned int niov = qiov->niov;
+
+assert(qiov->size >= bytes);
+total = iov_discard_back(qiov->iov, &niov, bytes);
+assert(total == bytes);
+
+qiov->niov = niov;
+qiov->size -= bytes;
+}
-- 
1.8.3.1




Re: [Qemu-devel] Hot unplug of pci-serial-2x fails assertion

2014-07-14 Thread Peter Crosthwaite
On Mon, Jul 14, 2014 at 9:10 PM, Markus Armbruster  wrote:
> Watch this:
>
> (qemu) chardev-add file,path=foo2,id=foo2
> (qemu) chardev-add file,path=foo3,id=foo3
> (qemu) device_add id=gg,driver=pci-serial-2x,chardev1=foo2,chardev2=foo3
> (qemu) device_del gg
> (qemu) upstream-qemu: /work/armbru/qemu/memory.c:1259: 
> memory_region_finalize: Assertion `((&mr->subregions)->tqh_first == ((void 
> *)0))' failed.
>

Are there more specifics to reproduction? I'm struggling and I've
tried a few variants.

Curiously I can device_del gg repeatedly with seemingly no effect however:

pcrost@pcrost-K42F:~/qemu$ ./x86_64-softmmu/qemu-system-x86_64  -nographic
QEMU 2.0.91 monitor - type 'help' for more information
(qemu)  chardev-add file,path=foo2,id=foo2
(qemu)  chardev-add file,path=foo3,id=foo3
(qemu) device_add id=gg,driver=pci-serial-2x,chardev1=foo2,chardev2=foo3
(qemu) device_del gg
(qemu) device_del gg
(qemu) device_del gg
(qemu) info qtree
bus: main-system-bus
  type System
  dev: hpet, id ""
gpio-in "" 2
gpio-out "" 1
timers = 3 (0x3)
msi = false
hpet-intcap = 4 (0x4)
irq 32
mmio fed0/0400
  dev: ioapic, id ""
gpio-in "" 24
irq 0
mmio fec0/1000
  dev: i440FX-pcihost, id ""
pci-hole64-size = 18446744073709551615 (16 EiB)
short_root_bus = 0 (0x0)
irq 0
bus: pci.0
  type PCI
  dev: pci-serial-2x, id "gg"
chardev1 = "foo2"
chardev2 = "foo3"
prog_if = 2 (0x2)
addr = 04.0
romfile = ""
rombar = 1 (0x1)
multifunction = false
command_serr_enable = true
class Serial port, addr 00:04.0, pci id 1b36:0003 (sub 1af4:1100)
bar 0: i/o at 0x [0xe]

Am I missing something?

Regards,
Peter



[Qemu-devel] [PULL v2 for-2.1 19/22] virtio-blk: Factor common checks out of virtio_blk_handle_read/write()

2014-07-14 Thread Kevin Wolf
From: Markus Armbruster 

Signed-off-by: Markus Armbruster 
Reviewed-by: Fam Zheng 
Signed-off-by: Kevin Wolf 
---
 hw/block/virtio-blk.c | 24 ++--
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 02cd6b0..075e6e6 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -288,6 +288,18 @@ static void virtio_blk_handle_flush(VirtIOBlockReq *req, 
MultiReqBuffer *mrb)
 bdrv_aio_flush(req->dev->bs, virtio_blk_flush_complete, req);
 }
 
+static bool virtio_blk_sect_range_ok(VirtIOBlock *dev,
+ uint64_t sector, size_t size)
+{
+if (sector & dev->sector_mask) {
+return false;
+}
+if (size % dev->conf->logical_block_size) {
+return false;
+}
+return true;
+}
+
 static void virtio_blk_handle_write(VirtIOBlockReq *req, MultiReqBuffer *mrb)
 {
 BlockRequest *blkreq;
@@ -299,11 +311,7 @@ static void virtio_blk_handle_write(VirtIOBlockReq *req, 
MultiReqBuffer *mrb)
 
 trace_virtio_blk_handle_write(req, sector, req->qiov.size / 512);
 
-if (sector & req->dev->sector_mask) {
-virtio_blk_rw_complete(req, -EIO);
-return;
-}
-if (req->qiov.size % req->dev->conf->logical_block_size) {
+if (!virtio_blk_sect_range_ok(req->dev, sector, req->qiov.size)) {
 virtio_blk_rw_complete(req, -EIO);
 return;
 }
@@ -333,11 +341,7 @@ static void virtio_blk_handle_read(VirtIOBlockReq *req)
 
 trace_virtio_blk_handle_read(req, sector, req->qiov.size / 512);
 
-if (sector & req->dev->sector_mask) {
-virtio_blk_rw_complete(req, -EIO);
-return;
-}
-if (req->qiov.size % req->dev->conf->logical_block_size) {
+if (!virtio_blk_sect_range_ok(req->dev, sector, req->qiov.size)) {
 virtio_blk_rw_complete(req, -EIO);
 return;
 }
-- 
1.8.3.1




[Qemu-devel] [PULL v2 for-2.1 20/22] virtio-blk: Bypass error action and I/O accounting on invalid r/w

2014-07-14 Thread Kevin Wolf
From: Markus Armbruster 

When a device model's I/O operation fails, we execute the error
action.  This lets layers above QEMU implement thin provisioning, or
attempt to correct errors before they reach the guest.  But when the
I/O operation fails because it's invalid, reporting the error to the
guest is the only sensible action.

If the guest's read or write asks for an invalid sector range, fail
the request right away, without considering the error action.  No
change with error action BDRV_ACTION_REPORT.

Furthermore, bypass I/O accounting, because we want to track only I/O
that actually reaches the block layer.

The next commit will extend "invalid sector range" to cover attempts
to read/write beyond the end of the medium.

Signed-off-by: Markus Armbruster 
Signed-off-by: Kevin Wolf 
---
 hw/block/virtio-blk.c | 14 --
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 075e6e6..e6e6276 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -307,15 +307,16 @@ static void virtio_blk_handle_write(VirtIOBlockReq *req, 
MultiReqBuffer *mrb)
 
 sector = virtio_ldq_p(VIRTIO_DEVICE(req->dev), &req->out.sector);
 
-bdrv_acct_start(req->dev->bs, &req->acct, req->qiov.size, BDRV_ACCT_WRITE);
-
 trace_virtio_blk_handle_write(req, sector, req->qiov.size / 512);
 
 if (!virtio_blk_sect_range_ok(req->dev, sector, req->qiov.size)) {
-virtio_blk_rw_complete(req, -EIO);
+virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
+virtio_blk_free_request(req);
 return;
 }
 
+bdrv_acct_start(req->dev->bs, &req->acct, req->qiov.size, BDRV_ACCT_WRITE);
+
 if (mrb->num_writes == 32) {
 virtio_submit_multiwrite(req->dev->bs, mrb);
 }
@@ -337,14 +338,15 @@ static void virtio_blk_handle_read(VirtIOBlockReq *req)
 
 sector = virtio_ldq_p(VIRTIO_DEVICE(req->dev), &req->out.sector);
 
-bdrv_acct_start(req->dev->bs, &req->acct, req->qiov.size, BDRV_ACCT_READ);
-
 trace_virtio_blk_handle_read(req, sector, req->qiov.size / 512);
 
 if (!virtio_blk_sect_range_ok(req->dev, sector, req->qiov.size)) {
-virtio_blk_rw_complete(req, -EIO);
+virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
+virtio_blk_free_request(req);
 return;
 }
+
+bdrv_acct_start(req->dev->bs, &req->acct, req->qiov.size, BDRV_ACCT_READ);
 bdrv_aio_readv(req->dev->bs, sector, &req->qiov,
req->qiov.size / BDRV_SECTOR_SIZE,
virtio_blk_rw_complete, req);
-- 
1.8.3.1




Re: [Qemu-devel] Hot unplug of pci-serial-2x fails assertion

2014-07-14 Thread Paolo Bonzini

Il 14/07/2014 13:10, Markus Armbruster ha scritto:

Watch this:

(qemu) chardev-add file,path=foo2,id=foo2
(qemu) chardev-add file,path=foo3,id=foo3
(qemu) device_add id=gg,driver=pci-serial-2x,chardev1=foo2,chardev2=foo3
(qemu) device_del gg
(qemu) upstream-qemu: /work/armbru/qemu/memory.c:1259: memory_region_finalize: 
Assertion `((&mr->subregions)->tqh_first == ((void *)0))' failed.


I think this is a bug you had already reported, but 
http://permalink.gmane.org/gmane.comp.emulators.qemu/283063 fell through 
the cracks.


Paolo



Re: [Qemu-devel] [PATCH 3/4 v8] ppc: Add software breakpoint support

2014-07-14 Thread Madhavan Srinivasan
On Monday 14 July 2014 02:45 PM, Bharat Bhushan wrote:
> This patch allow insert/remove software breakpoint.
> 
> When QEMU is not able to handle debug exception then we inject
> program exception to guest because for software breakpoint QEMU
> uses a ehpriv-1 instruction;
> So there cannot be any reason that we are in qemu with exit reason
> KVM_EXIT_DEBUG  for guest set debug exception, only possibility is
> guest executed ehpriv-1 privilege instruction and that's why we are
> injecting program exception.
> 
> Signed-off-by: Bharat Bhushan 
> ---
> v7->v8
>  - Decrement nip by 4 before calling ppc_cpu_do_interrupt()
>as pointed by "Madhavan Srinivasan"

Just a minor change. We increment the nip.

>  - Also added missing cpu_sync()
> 
>  target-ppc/kvm.c | 93 
> +++-
>  1 file changed, 79 insertions(+), 14 deletions(-)
> 
> diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
> index e00a20f..0f2e8e4 100644
> --- a/target-ppc/kvm.c
> +++ b/target-ppc/kvm.c
> @@ -1275,6 +1275,75 @@ static int kvmppc_handle_dcr_write(CPUPPCState *env, 
> uint32_t dcrn, uint32_t dat
>  return 0;
>  }
> 
> +int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
> +{
> +/* Mixed endian case is not handled */
> +uint32_t sc = debug_inst_opcode;
> +
> +if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn,
> +sizeof(sc), 0) ||
> +cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&sc, sizeof(sc), 1)) {
> +return -EINVAL;
> +}
> +
> +return 0;
> +}
> +
> +int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
> +{
> +uint32_t sc;
> +
> +if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&sc, sizeof(sc), 0) ||
> +sc != debug_inst_opcode ||
> +cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn,
> +sizeof(sc), 1)) {
> +return -EINVAL;
> +}
> +
> +return 0;
> +}
> +
> +void kvm_arch_update_guest_debug(CPUState *cs, struct kvm_guest_debug *dbg)
> +{
> +/* Software Breakpoint updates */
> +if (kvm_sw_breakpoints_active(cs)) {
> +dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP;
> +}
> +}
> +
> +static int kvm_handle_debug(PowerPCCPU *cpu, struct kvm_run *run)
> +{
> +CPUState *cs = CPU(cpu);
> +CPUPPCState *env = &cpu->env;
> +struct kvm_debug_exit_arch *arch_info = &run->debug.arch;
> +int handle = 0;
> +
> +if (kvm_find_sw_breakpoint(cs, arch_info->address)) {
> +handle = 1;
> +} else {
> +/* QEMU is not able to handle debug exception, so inject
> + * program exception to guest;
> + * Yes program exception NOT debug exception !!
> + * For software breakpoint QEMU uses a ehpriv-1 instruction;
Instead, can you say "QEMU uses a SW breakpoint instruction". In server
side, we use illegal instruction to trap to hypervisor ("0x0000")
> + * So there cannot be any reason that we are here for guest
> + * set debug exception, only possibility is guest executed a
> + * privilege instruction and that's why we are injecting
privilege or illegal instruction

My Bad. I should have read just last time. But just minor and I am ok as is.

Reviewed By: Madhavan Srinivasan 

> + * program exception.
> + */
> +
> +cpu_synchronize_state(cs);
> +/* env->nip is PC, so increment this by 4 to use
> + * ppc_cpu_do_interrupt(), which set srr0 = env->nip - 4.
> + */
> +env->nip += 4;
> +cs->exception_index = POWERPC_EXCP_PROGRAM;
> +env->error_code = POWERPC_EXCP_INVAL;
> +ppc_cpu_do_interrupt(cs);
> +}
> +
> +return handle;
> +}
> +
>  int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
>  {
>  PowerPCCPU *cpu = POWERPC_CPU(cs);
> @@ -1315,6 +1384,16 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run 
> *run)
>  ret = 0;
>  break;
> 
> +case KVM_EXIT_DEBUG:
> +DPRINTF("handle debug exception\n");
> +if (kvm_handle_debug(cpu, run)) {
> +ret = EXCP_DEBUG;
> +break;
> +}
> +/* re-enter, this exception was guest-internal */
> +ret = 0;
> +break;
> +
>  default:
>  fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason);
>  ret = -1;
> @@ -2003,16 +2082,6 @@ void kvm_arch_init_irq_routing(KVMState *s)
>  {
>  }
> 
> -int kvm_arch_insert_sw_breakpoint(CPUState *cpu, struct kvm_sw_breakpoint 
> *bp)
> -{
> -return -EINVAL;
> -}
> -
> -int kvm_arch_remove_sw_breakpoint(CPUState *cpu, struct kvm_sw_breakpoint 
> *bp)
> -{
> -return -EINVAL;
> -}
> -
>  int kvm_arch_insert_hw_breakpoint(target_ulong addr, target_ulong len, int 
> type)
>  {
>  return -EINVAL;
> @@ -2027,10 +2096,6 @@ void kvm_arch_remove_all_hw_breakpoints(void)
>  {
>  }
> 
> -void kvm_arch_u

Re: [Qemu-devel] [PATCH 1/4 v8] ppc: debug stub: Get trap instruction opcode from KVM

2014-07-14 Thread Madhavan Srinivasan
On Monday 14 July 2014 02:45 PM, Bharat Bhushan wrote:
> Get trap instruction opcode from KVM and this opcode will
> be used for setting software breakpoint in following patch
> 
> Signed-off-by: Bharat Bhushan 
> ---
> v7->v8
>  - No change
> 

Reviewed By: Madhavan Srinivasan 


>  target-ppc/kvm.c | 4 
>  1 file changed, 4 insertions(+)
> 
> diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
> index 2d87108..4df23dd 100644
> --- a/target-ppc/kvm.c
> +++ b/target-ppc/kvm.c
> @@ -72,6 +72,8 @@ static int cap_papr;
>  static int cap_htab_fd;
>  static int cap_fixup_hcalls;
> 
> +static uint32_t debug_inst_opcode;
> +
>  /* XXX We have a race condition where we actually have a level triggered
>   * interrupt, but the infrastructure can't expose that yet, so the guest
>   * takes but ignores it, goes to sleep and never gets notified that 
> there's
> @@ -436,6 +438,8 @@ int kvm_arch_init_vcpu(CPUState *cs)
>  break;
>  }
> 
> +kvm_get_one_reg(cs, KVM_REG_PPC_DEBUG_INST, &debug_inst_opcode);
> +
>  return ret;
>  }
> 




[Qemu-devel] [PATCH] sPAPR/IOMMU: Fix TCE entry permission

2014-07-14 Thread Gavin Shan
The permission of TCE entry should exclude physical base address.
Otherwise, unmapping TCE entry can be interpreted to mapping TCE
entry wrongly for VFIO devices.

Signed-off-by: Gavin Shan 
---
 hw/misc/vfio.c   | 2 +-
 hw/ppc/spapr_iommu.c | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c
index f9426ef..75ccceb 100644
--- a/hw/misc/vfio.c
+++ b/hw/misc/vfio.c
@@ -2316,7 +2316,7 @@ static void vfio_iommu_map_notify(Notifier *n, void *data)
 return;
 }
 
-if (iotlb->perm != IOMMU_NONE) {
+if ((iotlb->perm & IOMMU_RW) != IOMMU_NONE) {
 vaddr = memory_region_get_ram_ptr(mr) + xlat;
 
 ret = vfio_dma_map(container, iotlb->iova,
diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
index e603ac1..e223374 100644
--- a/hw/ppc/spapr_iommu.c
+++ b/hw/ppc/spapr_iommu.c
@@ -81,7 +81,7 @@ static IOMMUTLBEntry spapr_tce_translate_iommu(MemoryRegion 
*iommu, hwaddr addr)
 ret.iova = addr & page_mask;
 ret.translated_addr = tce & page_mask;
 ret.addr_mask = ~page_mask;
-ret.perm = tce;
+ret.perm = tce & IOMMU_RW;
 }
 trace_spapr_iommu_xlate(tcet->liobn, addr, ret.iova, ret.perm,
 ret.addr_mask);
@@ -225,7 +225,7 @@ static target_ulong put_tce_emu(sPAPRTCETable *tcet, 
target_ulong ioba,
 entry.iova = ioba & page_mask;
 entry.translated_addr = tce & page_mask;
 entry.addr_mask = ~page_mask;
-entry.perm = tce;
+entry.perm = tce & IOMMU_RW;
 memory_region_notify_iommu(&tcet->iommu, entry);
 
 return H_SUCCESS;
-- 
1.8.3.2




Re: [Qemu-devel] Hot unplug of pci-serial-2x fails assertion

2014-07-14 Thread Markus Armbruster
Peter Crosthwaite  writes:

> On Mon, Jul 14, 2014 at 9:10 PM, Markus Armbruster  wrote:
>> Watch this:
>>
>> (qemu) chardev-add file,path=foo2,id=foo2
>> (qemu) chardev-add file,path=foo3,id=foo3
>> (qemu) device_add id=gg,driver=pci-serial-2x,chardev1=foo2,chardev2=foo3
>> (qemu) device_del gg
>> (qemu) upstream-qemu: /work/armbru/qemu/memory.c:1259:
>> memory_region_finalize: Assertion `((&mr->subregions)->tqh_first ==
>> ((void *)0))' failed.
>>
>
> Are there more specifics to reproduction? I'm struggling and I've
> tried a few variants.
>
> Curiously I can device_del gg repeatedly with seemingly no effect however:
>
> pcrost@pcrost-K42F:~/qemu$ ./x86_64-softmmu/qemu-system-x86_64  -nographic
> QEMU 2.0.91 monitor - type 'help' for more information
> (qemu)  chardev-add file,path=foo2,id=foo2
> (qemu)  chardev-add file,path=foo3,id=foo3
> (qemu) device_add id=gg,driver=pci-serial-2x,chardev1=foo2,chardev2=foo3
> (qemu) device_del gg
> (qemu) device_del gg
> (qemu) device_del gg
> (qemu) info qtree
> bus: main-system-bus
>   type System
>   dev: hpet, id ""
> gpio-in "" 2
> gpio-out "" 1
> timers = 3 (0x3)
> msi = false
> hpet-intcap = 4 (0x4)
> irq 32
> mmio fed0/0400
>   dev: ioapic, id ""
> gpio-in "" 24
> irq 0
> mmio fec0/1000
>   dev: i440FX-pcihost, id ""
> pci-hole64-size = 18446744073709551615 (16 EiB)
> short_root_bus = 0 (0x0)
> irq 0
> bus: pci.0
>   type PCI
>   dev: pci-serial-2x, id "gg"
> chardev1 = "foo2"
> chardev2 = "foo3"
> prog_if = 2 (0x2)
> addr = 04.0
> romfile = ""
> rombar = 1 (0x1)
> multifunction = false
> command_serr_enable = true
> class Serial port, addr 00:04.0, pci id 1b36:0003 (sub 1af4:1100)
> bar 0: i/o at 0x [0xe]
>
> Am I missing something?

Is your guest running and honoring ACPI unplug requests?

See also Paolo's reply, which points to a patch.



Re: [Qemu-devel] Hot unplug of pci-serial-2x fails assertion

2014-07-14 Thread Markus Armbruster
Paolo Bonzini  writes:

> Il 14/07/2014 13:10, Markus Armbruster ha scritto:
>> Watch this:
>>
>> (qemu) chardev-add file,path=foo2,id=foo2
>> (qemu) chardev-add file,path=foo3,id=foo3
>> (qemu) device_add id=gg,driver=pci-serial-2x,chardev1=foo2,chardev2=foo3
>> (qemu) device_del gg
>> (qemu) upstream-qemu: /work/armbru/qemu/memory.c:1259:
>> memory_region_finalize: Assertion `((&mr->subregions)->tqh_first ==
>> ((void *)0))' failed.
>
> I think this is a bug you had already reported, but
> http://permalink.gmane.org/gmane.comp.emulators.qemu/283063 fell
> through the cracks.

Oops :)

Thanks!



Re: [Qemu-devel] [PATCH] serial-pci: remove memory regions from BAR before destroying them

2014-07-14 Thread Peter Crosthwaite
On Thu, Jun 26, 2014 at 5:32 PM, Markus Armbruster  wrote:
> Paolo Bonzini  writes:
>
>> Otherwise, hot-unplug of pci-serial-2x trips the assertion
>> in memory_region_destroy:
>>
>> (qemu) device_del gg
>> (qemu) qemu-system-x86_64: /work/armbru/tmp/qemu/memory.c:1021: 
>> memory_region_destroy: Assertion `((&mr->subregions)->tqh_first == ((void 
>> *)0))' failed.
>> Aborted (core dumped)
>>
>> Reported-by: Markus Armbruster 
>> Signed-off-by: Paolo Bonzini 
>
> Reviewed-by: Markus Armbruster 
>

Reviewed-by: Peter Crosthwaite 

> Would it make sense to add a "must not contain subregions" to
> memory_region_destroy()'s function comment?
>

Any reason to just not patch the memory region finaliser to unparent
all contained subregions automatically rather than assert? Destroying
a container should imply removing the subregion relationship and
simply orphan the subregion.

Regards,
Peter



Re: [Qemu-devel] [PULL 3/3] cirrus: Fix host CPU blits

2014-07-14 Thread Peter Lieven

On 14.07.2014 11:53, Gerd Hoffmann wrote:

   Hi,


Do you see a way to work around this in the graphics driver. E.g. blacklisting 
24bpp modes
etc. Even if X.Org people actually merge the fixes there are 2 years of Linux 
releases out
there that have corrupted graphics.

For anything using kernel 3.14+ IMO the answer to pretty much *any* gfx
issue is "use stdvga instead of cirrus".  3.14 got a kms driver for the
qemu stdvga (bochsdrm), so the modesetting driver and all the modern
stuff such as root-less X server works with the stdvga too.  And the
constrains cirrus has (due to emulating existing, old hardware) are
gone.


Thats good news. For older Linuxs it seems that also -vga vmware is a good 
alternative.
The only thing that is a bit odd is that the X.Org driver automatically 
switches to the maximum
resolution at start. I will eventually add a patch to limit the maximum 
resolution on the qemu command
line.

-vga std was also a good choice, but for Win2012(R2) the maximum resolution is 
at 1024x768 so I
had to switch to -vga vmware there as well.

Peter




Re: [Qemu-devel] [PATCH] qom: Make object_child_foreach safe for objects removal

2014-07-14 Thread Alexey Kardashevskiy
On 07/14/2014 06:14 PM, Paolo Bonzini wrote:
> Il 13/07/2014 16:41, Alexey Kardashevskiy ha scritto:
>> Current object_child_foreach() uses QTAILQ_FOREACH() to walk
>> through children and that makes children removal from the callback
>> impossible.
>>
>> This makes object_child_foreach() use QTAILQ_FOREACH_SAFE().
>>
>> Signed-off-by: Alexey Kardashevskiy 
>> ---
>>
>> The problem I am trying to solve is:
>> there is a PHB with multiple DMA windows a.k.a. sPAPRTCETable's which are
>> QOM children of PHB. One of RTAS functions is "reset" which is supposed to
>> remove all windows (now just one) except the default one.
>>
>> I could call QTAILQ_FOREACH_SAFE in sPAPR PHB code but
>> object_property_is_child()
>> is static and we probably do not want to make it public.
>>
>>
>> ---
>>  qom/object.c | 4 ++--
>>  1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/qom/object.c b/qom/object.c
>> index 0e8267b..4a814dc 100644
>> --- a/qom/object.c
>> +++ b/qom/object.c
>> @@ -678,10 +678,10 @@ void object_class_foreach(void (*fn)(ObjectClass
>> *klass, void *opaque),
>>  int object_child_foreach(Object *obj, int (*fn)(Object *child, void
>> *opaque),
>>   void *opaque)
>>  {
>> -ObjectProperty *prop;
>> +ObjectProperty *prop, *next;
>>  int ret = 0;
>>
>> -QTAILQ_FOREACH(prop, &obj->properties, node) {
>> +QTAILQ_FOREACH_SAFE(prop, &obj->properties, node, next) {
>>  if (object_property_is_child(prop)) {
>>  ret = fn(prop->opaque, opaque);
>>  if (ret != 0) {
>>
> 
> The patch is certainly okay, do you need it in 2.1?


Nope, I will need it for dynamic DMA windows (VFIO, PPC) which are not for
2.1 for sure.



-- 
Alexey



Re: [Qemu-devel] [PATCH v3 0/2] spapr: Enable huge pages again

2014-07-14 Thread Alexey Kardashevskiy
On 07/11/2014 01:03 AM, Alexey Kardashevskiy wrote:
> This does small RMA allocation rework and enables huge pages.
> 
> Please comment, especially commit logs. Thanks!
> 
> Changes:
> v3:
> * split to 2 patches, one mechanical
> * tested on PPC970
> 
> v2:
> * moved RMA memory region out of KVM code


This is 2.2 stuff, right? :)


> 
> 
> Alexey Kardashevskiy (2):
>   spapr: Move RMA memory region registration code
>   spapr: Enable use of huge pages
> 
>  hw/ppc/spapr.c   | 19 ---
>  target-ppc/kvm.c | 13 +++--
>  target-ppc/kvm_ppc.h |  2 +-
>  3 files changed, 16 insertions(+), 18 deletions(-)
> 


-- 
Alexey



Re: [Qemu-devel] [Bug 1307473] Re: guest hang due to missing clock interrupt

2014-07-14 Thread Serge Hallyn
Quoting Ondergetekende (1307...@bugs.launchpad.net):
> We've resolved our issues by disabling KSM on the affected nodes. All of
> the non-affected nodes didn't have KSM enabled (due to a packaging bug
> elsewhere). After disabling KSM, our problems went away gradually in ~3
> days.
> 
> This means we're no longer affected by this issue (and given the other
> reports, probably never were).

And which specific kernel are you on?

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

Title:
  guest hang due to missing clock interrupt

Status in QEMU:
  New
Status in “linux” package in Ubuntu:
  Confirmed
Status in “qemu” package in Ubuntu:
  Confirmed

Bug description:
  
  I noticed on 2 different systems that after upgrade from precise to latest 
trusty VMs are crashing:

  - in case of Windows VMs I'm getting BSOD with error message: "A clock 
interrupt was not received on a secondary processor within the allocated time 
interval."
  - On linux VMs I'm noticing "hrtimer: interrupt took 2992229 ns" messages 
  - On some proprietary virtual appliances I'm noticing crashes an due to 
missing timer interrupts

  QEMU version is:
  QEMU emulator version 1.7.91 (Debian 2.0.0~rc1+dfsg-0ubuntu3)

  Full command line:

  qemu-system-x86_64 -enable-kvm -name win7eval -S -machine pc-
  i440fx-1.7,accel=kvm,usb=off -cpu host -m 4096 -realtime mlock=off
  -smp 4,sockets=1,cores=4,threads=1 -uuid 05e5089a-
  4aa1-6bb2-ef06-ab4d020a -no-user-config -nodefaults -chardev
  
socket,id=charmonitor,path=/var/lib/libvirt/qemu/win7eval.monitor,server,nowait
  -mon chardev=charmonitor,id=monitor,mode=control -rtc base=localtime
  -no-shutdown -boot strict=on -device piix3-usb-
  uhci,id=usb,bus=pci.0,addr=0x1.0x2 -drive
  file=/var/vm/win7eval.qcow2,if=none,id=drive-virtio-disk0,format=qcow2
  -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x4,drive=drive-virtio-
  disk0,id=virtio-disk0,bootindex=1 -drive
  file=/home/damarion/iso/7600.16385.090713-1255_x86fre_enterprise_en-
  us_EVAL_Eval_Enterprise-GRMCENEVAL_EN_DVD.iso,if=none,id=drive-
  ide0-0-0,readonly=on,format=raw -device ide-cd,bus=ide.0,unit=0,drive
  =drive-ide0-0-0,id=ide0-0-0 -drive file=/home/damarion/iso/virtio-
  win-0.1-74.iso,if=none,id=drive-ide0-1-0,readonly=on,format=raw
  -device ide-cd,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0
  -netdev tap,fd=24,id=hostnet0 -device
  e1000,netdev=hostnet0,id=net0,mac=52:54:00:38:31:0a,bus=pci.0,addr=0x3
  -chardev pty,id=charserial0 -device isa-
  serial,chardev=charserial0,id=serial0 -device usb-tablet,id=input0
  -vnc 127.0.0.1:1 -device VGA,id=video0,bus=pci.0,addr=0x2 -device
  virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5

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



Re: [Qemu-devel] [PATCH v3 0/2] spapr: Enable huge pages again

2014-07-14 Thread Paolo Bonzini

Il 14/07/2014 15:13, Alexey Kardashevskiy ha scritto:

On 07/11/2014 01:03 AM, Alexey Kardashevskiy wrote:

This does small RMA allocation rework and enables huge pages.

Please comment, especially commit logs. Thanks!

Changes:
v3:
* split to 2 patches, one mechanical
* tested on PPC970

v2:
* moved RMA memory region out of KVM code



This is 2.2 stuff, right? :)


For me it would be okay for 2.1, but Alex may disagree.

Paolo





Re: [Qemu-devel] [PATCH v5 00/12] KVM Support for MIPS32 Processors

2014-07-14 Thread James Hogan
Hi Peter,

On 10/07/14 13:17, Peter Maydell wrote:
> On 17 June 2014 23:10, James Hogan  wrote:
>> The patchset depends on v4 of "target-mips: implement UserLocal
>> Register". I'm aiming for QEMU 2.1, hopefully it isn't too late to get
>> some final review.
>>
>> Thanks to everybody who has already taken part in review.
>>
>> This patchset implements KVM support for MIPS32 processors, using Trap &
>> Emulation.
> 
> I was looking at what happens for MMIO accesses to nonexistent
> memory when we're running under KVM, and interestingly this
> patchset means MIPS is now the only CPU which both (a) supports
> KVM and (b) has an implementation of the do_unassigned_access()
> CPU hook. Does the current code support a guest attempt to
> access unassigned physical addresses? I had a look at the code
> and it seems like mips_cpu_unassigned_access() will end up
> calling cpu_restore_state() and cpu_loop_exit(), which I think
> will probably crash if you call them when using KVM rather than
> TCG...

Yes, I have observed this in the past when experimentally writing to the
Malta reset region from the guest (see the patch "mips/malta: allow
volatile writes to reset flash" which didn't get applied but worked
around the specific issue). That was because read only memory regions
were treated as unassigned from the point of view of writes (which tbh
seems wrong), but it could happen with any unassigned access >
0x8000 from the guest AFAICT.

So yeh, until mips_cpu_unassigned_access does something more portable
for KVM, conditionally setting do_unassigned_access only if
!kvm_enabled() looks sensible. I'll see if I can reproduce it and submit
a patch.

> More generally, there doesn't really seem to be provision in the
> KVM KVM_EXIT_MMIO API for returning "this access failed".
> I guess in theory userspace could do all the "figure out how
> to adjust CPU state to do exception entry and then run VCPU",
> but that seems like quite a lot of work which the kernel already
> knows how to do; is there some way to provide a simpler API
> that lets userspace just inform the kernel that it needs to
> fault the access?

Indeed. Paolo's idea would work well I think. A data bus error exception
would likely be the only sensible error response required other than
ignoring writes or returning a garbage value for a read (which the
current KVM MMIO API already allows).

Cheers
James



Re: [Qemu-devel] [PATCH] qemu-char: fix deadlock with "-monitor pty"

2014-07-14 Thread Fam Zheng
On Fri, 07/11 12:11, Paolo Bonzini wrote:
> qemu_chr_be_generic_open cannot be called with the write lock taken,
> because it calls client code that may call qemu_chr_fe_write.  This
> actually happens for the monitor:
> 
> 0x727dbf79 in __GI_raise (sig=sig@entry=6)
> 0x727df388 in __GI_abort ()
> 0x555ef489 in error_exit (err=, 
> msg=msg@entry=0x559796d0 <__func__.5959> "qemu_mutex_lock")
> 0x558f9080 in qemu_mutex_lock (mutex=mutex@entry=0x56248a30)
> 0x55713936 in qemu_chr_fe_write (s=0x56248a30, 
> buf=buf@entry=0x563d8870 "QEMU 2.0.90 monitor - type 'help' for more 
> information\r\n", len=56)
> 0x556217fd in monitor_flush_locked (mon=mon@entry=0x56251fd0)
> 0x55621a12 in monitor_flush_locked (mon=0x56251fd0)
> monitor_puts (mon=mon@entry=0x56251fd0, str=0x5634bfa7 "", 
> str@entry=0x5634bf70 "QEMU 2.0.90 monitor - type 'help' for more 
> information\n")
> 0x55624359 in monitor_vprintf (mon=0x56251fd0, fmt= out>, ap=)
> 0x55624414 in monitor_printf (mon=, 
> fmt=fmt@entry=0x559105a0 "QEMU %s monitor - type 'help' for more 
> information\n")
> 0x55629806 in monitor_event (opaque=0x56251fd0, 
> event=)
> 0x5571343c in qemu_chr_be_generic_open (s=0x56248a30)
> 
> To avoid this, defer the call to an idle callback, which will be
> called as soon as the main loop is re-entered.  In order to simplify
> the cleanup and do it in one place only, change pty_chr_close to
> call pty_chr_state.
> 
> To reproduce, run with "-monitor pty", then try to read from the
> slave /dev/pts/FOO that it creates.
> 
> Fixes: 9005b2a7589540a3733b3abdcfbccfe7746cd1a1
> Reported-by: Li Liang 
> Signed-off-by: Paolo Bonzini 
> ---
>  qemu-char.c | 23 +--
>  1 file changed, 21 insertions(+), 2 deletions(-)
> 
> diff --git a/qemu-char.c b/qemu-char.c
> index 51917de..5bf99d1 100644
> --- a/qemu-char.c
> +++ b/qemu-char.c
> @@ -1080,6 +1080,7 @@ typedef struct {
>  /* Protected by the CharDriverState chr_write_lock.  */
>  int connected;
>  guint timer_tag;
> +guint open_tag;
>  } PtyCharDriver;
>  
>  static void pty_chr_update_read_handler_locked(CharDriverState *chr);
> @@ -1092,6 +1093,7 @@ static gboolean pty_chr_timer(gpointer opaque)
>  
>  qemu_mutex_lock(&chr->chr_write_lock);
>  s->timer_tag = 0;
> +s->open_tag = 0;
>  if (!s->connected) {
>  /* Next poll ... */
>  pty_chr_update_read_handler_locked(chr);
> @@ -1194,12 +1196,26 @@ static gboolean pty_chr_read(GIOChannel *chan, 
> GIOCondition cond, void *opaque)
>  return TRUE;
>  }
>  
> +static gboolean qemu_chr_be_generic_open_func(gpointer opaque)
> +{
> +CharDriverState *chr = opaque;
> +PtyCharDriver *s = chr->opaque;
> +
> +s->open_tag = 0;
> +qemu_chr_be_generic_open(chr);
> +return FALSE;
> +}
> +
>  /* Called with chr_write_lock held.  */
>  static void pty_chr_state(CharDriverState *chr, int connected)
>  {
>  PtyCharDriver *s = chr->opaque;
>  
>  if (!connected) {
> +if (s->open_tag) {
> +g_source_remove(s->open_tag);
> +s->open_tag = 0;
> +}
>  remove_fd_in_watch(chr);
>  s->connected = 0;
>  /* (re-)connect poll interval for idle guests: once per second.
> @@ -1212,8 +1228,9 @@ static void pty_chr_state(CharDriverState *chr, int 
> connected)
>  s->timer_tag = 0;
>  }
>  if (!s->connected) {
> +g_assert(s->open_tag == 0);
>  s->connected = 1;
> -qemu_chr_be_generic_open(chr);
> +s->open_tag = g_idle_add(qemu_chr_be_generic_open_func, chr);
>  }
>  if (!chr->fd_in_tag) {
>  chr->fd_in_tag = io_add_watch_poll(s->fd, pty_chr_read_poll,
> @@ -1227,7 +1244,8 @@ static void pty_chr_close(struct CharDriverState *chr)
>  PtyCharDriver *s = chr->opaque;
>  int fd;
>  
> -remove_fd_in_watch(chr);
> +qemu_mutex_lock(&chr->chr_write_lock);
> +pty_chr_state(chr, 0);
>  fd = g_io_channel_unix_get_fd(s->fd);
>  g_io_channel_unref(s->fd);
>  close(fd);
> @@ -1235,6 +1253,7 @@ static void pty_chr_close(struct CharDriverState *chr)
>  g_source_remove(s->timer_tag);
>  s->timer_tag = 0;
>  }
> +qemu_mutex_unlock(&chr->chr_write_lock);
>  g_free(s);
>  qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
>  }
> -- 
> 1.8.3.1
> 
> 

Looks good and fixes the deadlock.

Reviewed-by: Fam Zheng 



Re: [Qemu-devel] [PATCH] tcg: add ability to dump /tmp/perf-.map files

2014-07-14 Thread Alex Bennée

Richard Henderson writes:

> On 07/11/2014 09:43 AM, Alex Bennée wrote:
>> +/* if I could put this in a header easily */
>> +void tb_enable_perfmap(void);
>
> How about next to tb_flush in exec/exec-all.h?

Including exec/exec-all.h trips up some sort of include prevention
magic:

  CCvl.o
In file included from vl.c:82:0:
/home/alex/lsrc/qemu/qemu.git/include/exec/exec-all.h:75:28: error: attempt to 
use poisoned "CPUArchState"
 void gen_intermediate_code(CPUArchState *env, struct TranslationBlock *tb);
^
>> +
>> +void tb_enable_perfmap(void) {
>
> Watch the { placement.
>
>> +gchar * map_file = g_strdup_printf("/tmp/perf-%d.map", getpid());
>> +tb_perfmap = fopen(map_file, "w");
>> +g_free(map_file);
>> +}
>
> And speaking of tb_flush, ought there be some marker in the perf file to reset
> things?  Otherwise you're just going to wind up with garbage if you let the
> guest run long enough.
>
> Of course, I have no idea how to link the flush with a timestamp that allows
> one to selectively choose which section of the perf file one uses...

The perf JIT format isn't really that smart so currently I'm not sure
how it would deal with it. Currently I suspect the best solution is
"don't do that then" :-/

>
>
> r~

-- 
Alex Bennée



Re: [Qemu-devel] [PATCH 0/5] PPC: Mac99 emulation fixes

2014-07-14 Thread Mark Cave-Ayland

On 13/07/14 17:17, Alexander Graf wrote:


While trying to get Mac OS X booting with our -M mac99 emulation I stumbled
over a few issues that prevented it from doing so.

With these patches applied I still can't properly boot Mac OS X with -M mac99,
but I get a lot further than before. The biggest issue that's left now is to
properly fake Mac OS X into believing our timebase frequency. If I hack up the
cuda timer I can successfully boot Mac OS X on mac99:


No complaints from me on this series (I see Paolo has already commented 
suggested some MemoryRegion changes). Is this part of a bug-fix series 
to fix a -M mac99 regression on KVM or is it 2.2 material?



ATB,

Mark.




Re: [Qemu-devel] [PATCH 0/5] PPC: Mac99 emulation fixes

2014-07-14 Thread Alexander Graf


On 14.07.14 15:58, Mark Cave-Ayland wrote:

On 13/07/14 17:17, Alexander Graf wrote:

While trying to get Mac OS X booting with our -M mac99 emulation I 
stumbled

over a few issues that prevented it from doing so.

With these patches applied I still can't properly boot Mac OS X with 
-M mac99,
but I get a lot further than before. The biggest issue that's left 
now is to
properly fake Mac OS X into believing our timebase frequency. If I 
hack up the

cuda timer I can successfully boot Mac OS X on mac99:


No complaints from me on this series (I see Paolo has already 
commented suggested some MemoryRegion changes). Is this part of a 
bug-fix series to fix a -M mac99 regression on KVM or is it 2.2 material?


Mac99 never really worked for me, so I think this can easily be 2.2 
material. Maybe we can get the PCI bus working during the 2.2 
development time frame too then.


I mostly CC'ed you for the NVRAM patch, as that depends on an OpenBIOS 
change :).



Alex




Re: [Qemu-devel] [PATCH 2/2] PPC: Cuda: Use cuda timer to expose tbfreq to guest

2014-07-14 Thread Mark Cave-Ayland

On 13/07/14 21:36, Alexander Graf wrote:


Mac OS X calibrates a number of frequencies on bootup based on reading
tb values on bootup and comparing them to via cuda timer values.

The only variable we can really steer well (thanks to KVM) is the cuda
frequency. So let's use that one to fake Mac OS X into believing the
bus frequency is tbfreq * 4. That way Mac OS X will automatically
calculate the correct timebase frequency.

With this patch and the patch set I posted earlier I can successfully
run Mac OS X 10.2, 10.3 and 10.4 guests with -M mac99 on TCG and KVM.


Fantastic! I thought you mentioned before that there was a problem with 
the way in which OS X used the MMU which meant it wouldn't be possible 
to run under KVM but I guess that has been fixed now?


Also do any of these changes help any of the *BSDs to boot further?


ATB,

Mark.




Re: [Qemu-devel] [PATCH 0/5] PPC: Mac99 emulation fixes

2014-07-14 Thread Mark Cave-Ayland

On 14/07/14 15:00, Alexander Graf wrote:


On 14.07.14 15:58, Mark Cave-Ayland wrote:

On 13/07/14 17:17, Alexander Graf wrote:


While trying to get Mac OS X booting with our -M mac99 emulation I
stumbled
over a few issues that prevented it from doing so.

With these patches applied I still can't properly boot Mac OS X with
-M mac99,
but I get a lot further than before. The biggest issue that's left
now is to
properly fake Mac OS X into believing our timebase frequency. If I
hack up the
cuda timer I can successfully boot Mac OS X on mac99:


No complaints from me on this series (I see Paolo has already
commented suggested some MemoryRegion changes). Is this part of a
bug-fix series to fix a -M mac99 regression on KVM or is it 2.2 material?


Mac99 never really worked for me, so I think this can easily be 2.2
material. Maybe we can get the PCI bus working during the 2.2
development time frame too then.

I mostly CC'ed you for the NVRAM patch, as that depends on an OpenBIOS
change :).


Yup, saw that commit go into SVN trunk. Okay so no need to worry about 
re-running my OpenBIOS boot tests before the 2.1 release then :)



ATB,

Mark.




Re: [Qemu-devel] [PATCH] serial-pci: remove memory regions from BAR before destroying them

2014-07-14 Thread Paolo Bonzini

Il 14/07/2014 14:36, Peter Crosthwaite ha scritto:

On Thu, Jun 26, 2014 at 5:32 PM, Markus Armbruster  wrote:

Paolo Bonzini  writes:


Otherwise, hot-unplug of pci-serial-2x trips the assertion
in memory_region_destroy:

(qemu) device_del gg
(qemu) qemu-system-x86_64: /work/armbru/tmp/qemu/memory.c:1021: 
memory_region_destroy: Assertion `((&mr->subregions)->tqh_first == ((void 
*)0))' failed.
Aborted (core dumped)

Reported-by: Markus Armbruster 
Signed-off-by: Paolo Bonzini 


Reviewed-by: Markus Armbruster 



Reviewed-by: Peter Crosthwaite 


Would it make sense to add a "must not contain subregions" to
memory_region_destroy()'s function comment?



Any reason to just not patch the memory region finaliser to unparent


Note that unparent for memory regions is _not_ 
memory_region_del_subregion.  It is memory_region_destroy.


The parent object of a memory region is a device; the _container_ of a 
memory region is another memory region.



all contained subregions automatically rather than assert? Destroying
a container should imply removing the subregion relationship and
simply orphan the subregion.


This makes sense since we will soon make memory_region_destroy optional 
(devices will automatically destroy their memory regions).  Before 
QOMification, however, I think the assert was a useful debugging tool, 
guaranteeing that owners of memory regions were destroyed in the right 
order.  So we could indeed revisit this in 2.2 and make 
memory_region_del_subregion also optional.


Paolo



Re: [Qemu-devel] [PATCH] serial-pci: remove memory regions from BAR before destroying them

2014-07-14 Thread Peter Crosthwaite
On Tue, Jul 15, 2014 at 12:20 AM, Paolo Bonzini  wrote:
> Il 14/07/2014 14:36, Peter Crosthwaite ha scritto:
>
>> On Thu, Jun 26, 2014 at 5:32 PM, Markus Armbruster 
>> wrote:
>>>
>>> Paolo Bonzini  writes:
>>>
 Otherwise, hot-unplug of pci-serial-2x trips the assertion
 in memory_region_destroy:

 (qemu) device_del gg
 (qemu) qemu-system-x86_64: /work/armbru/tmp/qemu/memory.c:1021:
 memory_region_destroy: Assertion `((&mr->subregions)->tqh_first == ((void
 *)0))' failed.
 Aborted (core dumped)

 Reported-by: Markus Armbruster 
 Signed-off-by: Paolo Bonzini 
>>>
>>>
>>> Reviewed-by: Markus Armbruster 
>>>
>>
>> Reviewed-by: Peter Crosthwaite 
>>
>>> Would it make sense to add a "must not contain subregions" to
>>> memory_region_destroy()'s function comment?
>>>
>>
>> Any reason to just not patch the memory region finaliser to unparent
>
>
> Note that unparent for memory regions is _not_ memory_region_del_subregion.
> It is memory_region_destroy.
>

Yes, bad choice of words by me. What I was going for was "un-contain" I guess.

Regards,
Peter

> The parent object of a memory region is a device; the _container_ of a
> memory region is another memory region.
>
>
>> all contained subregions automatically rather than assert? Destroying
>> a container should imply removing the subregion relationship and
>> simply orphan the subregion.
>
>
> This makes sense since we will soon make memory_region_destroy optional
> (devices will automatically destroy their memory regions).  Before
> QOMification, however, I think the assert was a useful debugging tool,
> guaranteeing that owners of memory regions were destroyed in the right
> order.  So we could indeed revisit this in 2.2 and make
> memory_region_del_subregion also optional.
>
> Paolo
>



[Qemu-devel] [PATCH] target-i386/FPU: wrong conversion infinity from float80 to int32/int64

2014-07-14 Thread Dmitry Poletaev
I executed test-i386 from tests folder from QEMU rep and according to the 
result, instructions fistl and fistpll returns maximum positive result 
(0x7fff...), if a FPU register stores a positive infinity, and minimum negative 
result (0x80...), if a negative infinity stores in a register. Real processor 
in both cases returns minimum negative result (0x80...). An Intel manual(Vol. 
2A 3-299 
(http://www.intel.ru/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-vol-2a-manual.pdf))
 tells us "If the invalid-operation exception is masked, the integer indefinite 
value is stored in memory." I not found what "integer indefinite value" 
obviously means, but I make conclusion that "integer indefinite value" is 
0x8000...

This patch fixes behaviour of fistl/fistpll instructions correct, and at least 
not adds new bugs(according to tcg tests), but I am not shure it doesn't breaks 
anything.

From: Dmitry Poletaev 
Signed-off-by: Dmitry Poletaev 

---
 fpu/softfloat.c | 8 +---
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 9274ebf..580c322 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -133,7 +133,7 @@ static int32 roundAndPackInt32( flag zSign, uint64_t absZ 
STATUS_PARAM)
 if ( zSign ) z = - z;
 if ( ( absZ>>32 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) {
 float_raise( float_flag_invalid STATUS_VAR);
-return zSign ? (int32_t) 0x8000 : 0x7FFF;
+return (int32_t) 0x8000;
 }
 if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact;
 return z;
@@ -4681,12 +4681,6 @@ int64 floatx80_to_int64( floatx80 a STATUS_PARAM )
 if ( shiftCount <= 0 ) {
 if ( shiftCount ) {
 float_raise( float_flag_invalid STATUS_VAR);
-if (! aSign
- || (( aExp == 0x7FFF )
-  && ( aSig != LIT64( 0x8000 ) ) )
-   ) {
-return LIT64( 0x7FFF );
-}
 return (int64_t) LIT64( 0x8000 );
 }
 aSigExtra = 0;
-- 
1.8.4.msysgit.0




Re: [Qemu-devel] [PATCH v5 00/12] KVM Support for MIPS32 Processors

2014-07-14 Thread Peter Maydell
On 14 July 2014 14:33, James Hogan  wrote:
> On 10/07/14 13:17, Peter Maydell wrote:
>> More generally, there doesn't really seem to be provision in the
>> KVM KVM_EXIT_MMIO API for returning "this access failed".
>> I guess in theory userspace could do all the "figure out how
>> to adjust CPU state to do exception entry and then run VCPU",
>> but that seems like quite a lot of work which the kernel already
>> knows how to do; is there some way to provide a simpler API
>> that lets userspace just inform the kernel that it needs to
>> fault the access?
>
> Indeed. Paolo's idea would work well I think. A data bus error exception
> would likely be the only sensible error response required other than
> ignoring writes or returning a garbage value for a read (which the
> current KVM MMIO API already allows).

I think we should make the API at least permit returning an
(architecture-specific) error code to the kernel, rather than just
a single boolean "failed" response. For instance on ARM the
fault status registers include a single ExT bit for classifying
the type of an external abort. (The meaning of the bit is
IMPDEF; on the Cortex-A15 it can be used to distinguish
AXI bus DECERR ("decode error", ie the interconnect doesn't
have anything attached at that address) and SLVERR ("slave
error", ie there was a device at that address but it chose to
reject the transaction for some reason, eg unsupported
transfer size, timeout, write to read-only location, FIFO
overrun or just because the device was in a bad mood.)

thanks
-- PMM



[Qemu-devel] [PATCH] linux-user: Add binfmt wrapper

2014-07-14 Thread Joakim Tjernlund
The popular binfmt-wrapper patch adds an additional
executable which mangle argv suitable for binfmt flag P.
In a chroot you need the both (statically linked) qemu-$arch
and qemu-$arch-binfmt-wrapper. This is sub optimal and a
better approach is to recognize the -binfmt-wrapper extension
within linux-user(qemu-$arch) and mangle argv there.
This just produces on executable which can be either copied to
the chroot or bind mounted with the appropriate -binfmt-wrapper
suffix.

Signed-off-by: Joakim Tjernlund 
---
 linux-user/main.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/linux-user/main.c b/linux-user/main.c
index 71a33c7..212067a 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -3828,6 +3828,19 @@ int main(int argc, char **argv, char **envp)
 int i;
 int ret;
 int execfd;
+char *binfmt;
+
+i = strlen( argv[0] ) - strlen ( "-binfmt-wrapper" );
+binfmt = argv[0] + i;
+if (i > 0 && strcmp ( binfmt, "-binfmt-wrapper" ) == 0) {
+   if (argc < 3 ) {
+   fprintf ( stderr, "%s: Please use me through binfmt with P flag\n", 
argv[0] );
+   exit(1);
+   }
+   handle_arg_argv0(argv[2]); /* binfmt wrapper */
+   memmove(&argv[2], &argv[3], (argc-2)*sizeof(argv));
+   argc--;
+}
 
 module_call_init(MODULE_INIT_QOM);
 
-- 
1.8.5.5




Re: [Qemu-devel] [PULL v2 for-2.1 00/22] Block patches for 2.1.0-rc2

2014-07-14 Thread Peter Maydell
On 14 July 2014 12:42, Kevin Wolf  wrote:
> v2:
> - Fixed assertion failure on 32 bit hosts triggered by qtests
>   (32 bit truncation of image file size in patch "block: Make qiov
>   match the request size until EOF")
>
>
> The following changes since commit 675879f6f3c9463e103735a4e41e9deb0bee9b39:
>
>   Update version for v2.1.0-rc1 release (2014-07-08 16:53:59 +0100)
>
> are available in the git repository at:
>
>   git://repo.or.cz/qemu/kevin.git tags/for-upstream
>
> for you to fetch changes up to 58ac321135af890b503ebe56d0d00e184779918f:
>
>   ide: Treat read/write beyond end as invalid (2014-07-14 12:03:21 +0200)
>
> 
> Block patches for 2.1.0-rc2 (v2)

Applied, thanks (and thanks for tracking down the 32-bit
assertion issue).

-- PMM



Re: [Qemu-devel] [PATCH] target-i386/FPU: wrong conversion infinity from float80 to int32/int64

2014-07-14 Thread Peter Maydell
On 14 July 2014 15:35, Dmitry Poletaev  wrote:
> I executed test-i386 from tests folder from QEMU rep and according to the 
> result, instructions fistl and fistpll returns maximum positive result 
> (0x7fff...), if a FPU register stores a positive infinity, and minimum 
> negative result (0x80...), if a negative infinity stores in a register. Real 
> processor in both cases returns minimum negative result (0x80...). An Intel 
> manual(Vol. 2A 3-299 
> (http://www.intel.ru/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-vol-2a-manual.pdf))
>  tells us "If the invalid-operation exception is masked, the integer 
> indefinite value is stored in memory." I not found what "integer indefinite 
> value" obviously means, but I make conclusion that "integer indefinite value" 
> is 0x8000...
>
> This patch fixes behaviour of fistl/fistpll instructions correct, and at 
> least not adds new bugs(according to tcg tests), but I am not shure it 
> doesn't breaks anything.

Yeah, this seems pretty likely to break all our other architectures
that use softfloat. (ARM at least gives MAXINT for +infinity
and MININT for -infinity.) This needs to either be done in the
target-i386/ code or by adding an option flag of some sort
to softfloat to permit the i386 code to specify the required
behaviour. (I checked the IEEE 754 spec and it looks like the
result value isn't specified for overflows, so this is all going
to be architecture-specific.)

The "integer indefinite value" is defined in volume 1 of the
Intel Architecture Software Developer's Manual, in table 4-1
(and also section 8.2.1); it is indeed a value with only the
most significant bit set.

I think that given that the manual says this is only done for
FIST/FISTP I would start by trying to deal with this in the
target-i386 code for those insns: call the softfloat conversion
function as usual, but if it sets the invalid flag then ignore
what softfloat returns you and use the integer-indefinite-value
instead. (Since softfloat's status flags are sticky you may need
to do a save-old-flag-value/clear-flags/softfloat op/check-flags/
merge-flag-values dance.)

thanks
-- PMM



  1   2   >