[Qemu-devel] [PATCH 1/2] i386: Add an ACPI_EXTRACT_NAME_BUFFER16 directive.

2014-09-13 Thread Gal Hammer
Add a 16-bytes buffer to allow storing a 128-bit UUID value in an
ACPI table.

Signed-off-by: Gal Hammer 
---
 scripts/acpi_extract.py | 23 ++-
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/scripts/acpi_extract.py b/scripts/acpi_extract.py
index 22ea468..88314fc 100755
--- a/scripts/acpi_extract.py
+++ b/scripts/acpi_extract.py
@@ -139,13 +139,16 @@ def aml_name_string(offset):
 offset += 1
 return offset;
 
-# Given data offset, find 8 byte buffer offset
-def aml_data_buffer8(offset):
-#0x08 NameOp NameString DataRef
-expect = [0x11, 0x0B, 0x0A, 0x08]
+# Given data offset, find variable length byte buffer offset
+def aml_data_buffer(offset, length):
+#0x11 PkgLength BufferSize ByteList
+if (length > 63):
+die( "Name offset 0x%x: expected an one byte PkgLength (length<=63)" %
+ (offset));
+expect = [0x11, length+3, 0x0A, length]
 if (aml[offset:offset+4] != expect):
 die( "Name offset 0x%x: expected %s actual %s" %
- (offset, aml[offset:offset+4], expect))
+ (offset, expect, aml[offset:offset+4]))
 return offset + len(expect)
 
 # Given data offset, find dword const offset
@@ -172,9 +175,9 @@ def aml_data_byte_const(offset):
  (offset, aml[offset]));
 return offset + 1;
 
-# Find name'd buffer8
-def aml_name_buffer8(offset):
-return aml_data_buffer8(aml_name_string(offset) + 4)
+# Find name'd buffer
+def aml_name_buffer(offset, length):
+return aml_data_buffer(aml_name_string(offset) + 4, length)
 
 # Given name offset, find dword const offset
 def aml_name_dword_const(offset):
@@ -308,7 +311,9 @@ for i in range(len(asl)):
 output[array] = aml
 continue
 if (directive == "ACPI_EXTRACT_NAME_BUFFER8"):
-offset = aml_name_buffer8(offset)
+offset = aml_name_buffer(offset, 8)
+elif (directive == "ACPI_EXTRACT_NAME_BUFFER16"):
+offset = aml_name_buffer(offset, 16)
 elif (directive == "ACPI_EXTRACT_NAME_DWORD_CONST"):
 offset = aml_name_dword_const(offset)
 elif (directive == "ACPI_EXTRACT_NAME_WORD_CONST"):
-- 
1.9.3




[Qemu-devel] [PATCH RESEND 0/2 V2] Virtual Machine Generation ID

2014-09-13 Thread Gal Hammer
Hi,

A two parts patch to add a QEmu support for Microsoft's Virtual Machine
Generation ID device.

The first one add a new ACPI directive which allow to use a 16-bytes
buffer in an ACPI table. This buffer is for storing the VM's UUID.

The second is the ACPI tables changes and the actual device.

Your comment are welcomed.

Thanks,

Gal.

V2: - Remove "-uuid" command line parameter.
- Move device's description from SSDT to DDST table.
- Add new "vmgenid" sysbus device.

Gal Hammer (2):
  i386: Add an ACPI_EXTRACT_NAME_BUFFER16 directive.
  i386: Add a Virtual Machine Generation ID device.

 default-configs/i386-softmmu.mak   |  1 +
 default-configs/x86_64-softmmu.mak |  1 +
 hw/i386/acpi-build.c   | 23 ++-
 hw/i386/acpi-dsdt.dsl  | 37 +
 hw/misc/Makefile.objs  |  1 +
 hw/misc/vmgenid.c  | 85 ++
 include/hw/i386/pc.h   |  3 ++
 scripts/acpi_extract.py| 23 +++
 8 files changed, 163 insertions(+), 11 deletions(-)
 create mode 100644 hw/misc/vmgenid.c

-- 
1.9.3




[Qemu-devel] [PATCH 2/2] i386: Add a Virtual Machine Generation ID device.

2014-09-13 Thread Gal Hammer
Based on Microsoft's sepecifications (paper can be dowloaded from
http://go.microsoft.com/fwlink/?LinkId=260709), add a device
description to the DSDT ACPI table.

The GUID is set using a new "vmgenid" device.

Signed-off-by: Gal Hammer 

---
 default-configs/i386-softmmu.mak   |  1 +
 default-configs/x86_64-softmmu.mak |  1 +
 hw/i386/acpi-build.c   | 23 ++-
 hw/i386/acpi-dsdt.dsl  | 37 +
 hw/misc/Makefile.objs  |  1 +
 hw/misc/vmgenid.c  | 85 ++
 include/hw/i386/pc.h   |  3 ++
 7 files changed, 149 insertions(+), 2 deletions(-)
 create mode 100644 hw/misc/vmgenid.c

diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak
index 8e08841..bd33c75 100644
--- a/default-configs/i386-softmmu.mak
+++ b/default-configs/i386-softmmu.mak
@@ -45,3 +45,4 @@ CONFIG_IOAPIC=y
 CONFIG_ICC_BUS=y
 CONFIG_PVPANIC=y
 CONFIG_MEM_HOTPLUG=y
+CONFIG_VMGENID=y
diff --git a/default-configs/x86_64-softmmu.mak 
b/default-configs/x86_64-softmmu.mak
index 66557ac..006fc7c 100644
--- a/default-configs/x86_64-softmmu.mak
+++ b/default-configs/x86_64-softmmu.mak
@@ -45,3 +45,4 @@ CONFIG_IOAPIC=y
 CONFIG_ICC_BUS=y
 CONFIG_PVPANIC=y
 CONFIG_MEM_HOTPLUG=y
+CONFIG_VMGENID=y
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 85e5834..153dadc 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1390,15 +1390,34 @@ build_mcfg_q35(GArray *table_data, GArray *linker, 
AcpiMcfgInfo *info)
 static void
 build_dsdt(GArray *table_data, GArray *linker, AcpiMiscInfo *misc)
 {
-AcpiTableHeader *dsdt;
+int dsdt_start = table_data->len;
+uint8_t *dsdt;
+uint8_t *vm_gid_ptr;
+uint32_t vm_gid_physical_address;
 
 assert(misc->dsdt_code && misc->dsdt_size);
 
 dsdt = acpi_data_push(table_data, misc->dsdt_size);
 memcpy(dsdt, misc->dsdt_code, misc->dsdt_size);
 
+vm_gid_ptr = acpi_data_get_ptr(dsdt, misc->dsdt_size,
+   *dsdt_acpi_vm_gid, 16);
+if (vm_generation_id(vm_gid_ptr)) {
+vm_gid_physical_address = dsdt_start + *dsdt_acpi_vm_gid;
+bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE,
+   ACPI_BUILD_TABLE_FILE,
+   table_data,
+   dsdt + *dsdt_acpi_vm_gid_addr,
+   sizeof(uint32_t));
+} else {
+vm_gid_physical_address = 0;
+}
+
+ACPI_BUILD_SET_LE(dsdt, misc->dsdt_size,
+  *dsdt_acpi_vm_gid_addr, 32, vm_gid_physical_address);
+
 memset(dsdt, 0, sizeof *dsdt);
-build_header(linker, table_data, dsdt, "DSDT",
+build_header(linker, table_data, (AcpiTableHeader *)dsdt, "DSDT",
  misc->dsdt_size, 1);
 }
 
diff --git a/hw/i386/acpi-dsdt.dsl b/hw/i386/acpi-dsdt.dsl
index 559f4b6..9015881 100644
--- a/hw/i386/acpi-dsdt.dsl
+++ b/hw/i386/acpi-dsdt.dsl
@@ -294,6 +294,43 @@ DefinitionBlock (
 }
 }
 
+/
+ * Virtual Machine Generation ID Device
+ /
+Scope(\_SB) {
+
+Device(VMGI) {
+Name(_HID, "QEMU0002")
+Name(_CID, "VM_Gen_Counter")
+Name(_DDN, "VM_Gen_Counter")
+
+ACPI_EXTRACT_NAME_DWORD_CONST dsdt_acpi_vm_gid_addr
+Name(VGIA, 0x12345678)
+
+ACPI_EXTRACT_NAME_BUFFER16 dsdt_acpi_vm_gid
+Name(VGID, Buffer(16) {
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })
+
+Method(_STA, 0, NotSerialized) {
+Store(VGIA, Local0)
+If (LEqual(Local0, Zero)) {
+Return (0x00)
+} Else {
+Return (0x0F)
+}
+}
+
+Method(ADDR, 0, Serialized) {
+Store(Package(2) { }, Local0)
+Store(VGIA, Index(Local0, 0))
+Store(0x, Index(Local0, 1))
+return (Local0)
+}
+}
+}
+
+
 #include "hw/acpi/pc-hotplug.h"
 #define CPU_STATUS_BASE PIIX4_CPU_HOTPLUG_IO_BASE
 #include "acpi-dsdt-cpu-hotplug.dsl"
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 979e532..c18b800 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -41,3 +41,4 @@ obj-$(CONFIG_SLAVIO) += slavio_misc.o
 obj-$(CONFIG_ZYNQ) += zynq_slcr.o
 
 obj-$(CONFIG_PVPANIC) += pvpanic.o
+obj-$(CONFIG_VMGENID) += vmgenid.o
diff --git a/hw/misc/vmgenid.c b/hw/misc/vmgenid.c
new file mode 100644
index 000..76956d1
--- /dev/null
+++ b/hw/misc/vmgenid.c
@@ -0,0 +1,85 @@
+/*
+ *  Virtual Machine Generation ID Device
+ *
+ *  Copyright (C) 2014 Red Hat Inc.
+ *
+ *  Authors: Gal Hammer 
+ *
+ * This work is licensed 

[Qemu-devel] [Bug 1307225] Re: Running a virtual machine on a Haswell system produces machine check events

2014-09-13 Thread Paul Bredbury
Try adding this to the Linux commandline, in your bootloader:

mce=nobootlog

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

Title:
  Running a virtual machine on a Haswell system produces machine check
  events

Status in QEMU:
  New

Bug description:
  I'm running a virtual Windows SBS 2003 installation on a Xeon E3
  Haswell system running Gentoo Linux. First, I used Qemu 1.5.3 (the
  latest stable version on Gentoo). I got a lot of machine check events
  ("mce: [Hardware Error]: Machine check events logged") in dmesg that
  always looked like (using mcelog):

  Hardware event. This is not a software error.
  MCE 0
  CPU 3 BANK 0
  TIME 1397455091 Mon Apr 14 07:58:11 2014
  MCG status:
  MCi status:
  Corrected error
  Error enabled
  MCA: Internal parity error
  STATUS 904f0005 MCGSTATUS 0
  MCGCAP c09 APICID 6 SOCKETID 0
  CPUID Vendor Intel Family 6 Model 60

  I found this discussion on the vmware community:
  https://communities.vmware.com/thread/452344

  It seems that this is (at least partly) caused by the Qemu machine. I
  switched to Qemu 1.7.0, the first version to use "pc-i440fx-1.7". With
  this version, the errors almost disappeared, but from time to time, I
  still get machine check events. Anyways, they so not seem to affect
  neither the vm, nor the host.

  The Haswell machine has been set up and running for several days
  without a single error message. They only appear when the VM is
  running. so I think this is actually some problem with the Haswell
  architecture (and not a real hardware error).

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



[Qemu-devel] [Bug 1307225] Re: Running a virtual machine on a Haswell system produces machine check events

2014-09-13 Thread Thomas
I got a new Haswell based system a few days ago. It has been running
fine without warnings but today I started a VirtualBox VM and got a MCE
soon afterwards. "MCA: Internal parity error" like everyone else. From
reading this bug and the vmware link in the first post it seems like
this problem occurs on all virtualization solutions using hardware
acceleration on Haswell based systems. It happens on Qemu, Virtualbox
and Vmware and it happens on both Linux and Windows.

Do anyone have connections within Intel and can pull some strings to
have them look at this? It looks like the MCE is always non fatal but
perhaps there are other unknown side effects. A microcode update might
solve it.

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

Title:
  Running a virtual machine on a Haswell system produces machine check
  events

Status in QEMU:
  New

Bug description:
  I'm running a virtual Windows SBS 2003 installation on a Xeon E3
  Haswell system running Gentoo Linux. First, I used Qemu 1.5.3 (the
  latest stable version on Gentoo). I got a lot of machine check events
  ("mce: [Hardware Error]: Machine check events logged") in dmesg that
  always looked like (using mcelog):

  Hardware event. This is not a software error.
  MCE 0
  CPU 3 BANK 0
  TIME 1397455091 Mon Apr 14 07:58:11 2014
  MCG status:
  MCi status:
  Corrected error
  Error enabled
  MCA: Internal parity error
  STATUS 904f0005 MCGSTATUS 0
  MCGCAP c09 APICID 6 SOCKETID 0
  CPUID Vendor Intel Family 6 Model 60

  I found this discussion on the vmware community:
  https://communities.vmware.com/thread/452344

  It seems that this is (at least partly) caused by the Qemu machine. I
  switched to Qemu 1.7.0, the first version to use "pc-i440fx-1.7". With
  this version, the errors almost disappeared, but from time to time, I
  still get machine check events. Anyways, they so not seem to affect
  neither the vm, nor the host.

  The Haswell machine has been set up and running for several days
  without a single error message. They only appear when the VM is
  running. so I think this is actually some problem with the Haswell
  architecture (and not a real hardware error).

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



Re: [Qemu-devel] [synnefo-devel] Re: [PATCH resend 1/2] monitor: Reset HMP mon->rs on CHR_EVENT_CLOSED

2014-09-13 Thread Luiz Capitulino
On Sat, 13 Sep 2014 19:27:46 +0300
Stratos Psomadakis  wrote:

> On 12/09/2014 08:19 μμ, Luiz Capitulino wrote:
> > On Fri, 12 Sep 2014 20:01:04 +0300
> > Stratos Psomadakis  wrote:
> >
> >> On 12/09/2014 06:21 μμ, Luiz Capitulino wrote:
> >>> On Fri, 12 Sep 2014 17:07:32 +0300
> >>> Stratos Psomadakis  wrote:
> >>>
>  Commit cdaa86a54 ("Add G_IO_HUP handler for socket chardev") exposed a 
>  bug in
>  the way the HMP monitor handles its command buffer. When a client closes 
>  the
>  connection to the monitor, tcp_chr_read() will detect the G_IO_HUP 
>  condition
>  and call tcp_chr_disconnect() to close the server-side connection too. 
>  Due to
>  the fact that monitor reads 1 byte at a time (for each tcp_chr_read()), 
>  the
>  monitor readline state / buffers might contain junk (i.e. a half-finished
>  command).  Thus, without calling readline_restart() on mon->rs upon
>  CHR_EVENT_CLOSED, future HMP commands will fail.
> >>> What's your reproducer?
> >> We have a script that opens a connection to the HMP socket and starts
> >> sending 'info version' commands to the monitor in a loop. If we kill the
> >> script (in the middle of the loop) and re-run it, we get "unknown
> >> command" errors from the HMP ("unknown command: 'infinfo'" for example).
> >>
> >>> Are you using the mux feature?
> >> Nope (on the cli we use '-monitor unix:.mon,server,nowait' for the
> >> HMP).
> >>
> >>> We also reset it
> >>> in CHR_EVENT_OPENED if the mux feature is not used, why isn't that
> >>> good enough?
> >> I checked the code and on CHR_EVENT_OPENED the monitor calls
> >> readline_show_prompt (when not using mux). This resets the
> >> last_cmd_index/size readline variables, but the cmd_buf_index/size
> >> remains intact. I think that readline_restart() is necessary in order to
> >> cleanup the readline cmd buf (either in CHR_EVENT_OPENED or in
> >> CHR_EVENT_CLOSED).
> > I'm wondering if calling readline_restart() in the CHR_EVENT_CLOSED
> > can break mux support. But I won't have time to check it today. Maybe
> > moving the readline_restart() call to right before the
> > readline_show_prompt() call in the OPENED event is the best thing to do?
> 
> I did some quick tests with a mux chardev (I tried two mux'ed HMP
> monitors and a serial and an HMP). Calling readline_restart() in
> CHR_EVENT_CLOSED didn't seem to affect mux support (as far as I could
> tell). However, calling readline_restart() in CHR_EVENT_OPENED, just
> before readline_show_prompt(), resolves the issue too, and I think it
> makes more sense to be called at that point. If you agree, I can resend
> the modified patch.

Yes, I think that's the best. I'll just apply your respin.

> 
> >
> >> Thanks,
> >> Stratos
> >>
>  Signed-off-by: Stratos Psomadakis 
>  Signed-off-by: Dimitris Aragiorgis 
>  ---
>   monitor.c |1 +
>   1 file changed, 1 insertion(+)
> 
>  diff --git a/monitor.c b/monitor.c
>  index 34cee74..7857300 100644
>  --- a/monitor.c
>  +++ b/monitor.c
>  @@ -5252,6 +5252,7 @@ static void monitor_event(void *opaque, int event)
>   break;
>   
>   case CHR_EVENT_CLOSED:
>  +readline_restart(mon->rs);
>   mon_refcount--;
>   monitor_fdsets_cleanup();
>   break;
> >>
> 
> 




Re: [Qemu-devel] [PATCH v2 03/23] block: Connect BlockBackend to BlockDriverState

2014-09-13 Thread Max Reitz

On 13.09.2014 17:00, Markus Armbruster wrote:

The pointer from BlockBackend to BlockDriverState is a strong
reference, managed with bdrv_ref() / bdrv_unref(), the back-pointer is
a weak one.

Convenience function blk_new_with_bs() creates a BlockBackend with its
BlockDriverState.  Callers have to unref both.  The commit after next
will relieve them of the need to unref the BlockDriverState.

Complication: due to the silly way drive_del works, we need a way to
hide a BlockBackend, just like bdrv_make_anon().  To emphasize its
"special" status, give the function a suitably off-putting name:


So you're trying to force people with a sense of aesthetics to solve 
this problem? I don't know why this isn't taught in Software Engineering 
in university, but it definitely should be.



blk_hide_on_behalf_of_do_drive_del().  Unfortunately, hiding turns the
BlockBackend's name into the empty string.  Can't avoid that without
breaking the blk->bs->device_name equals blk->name invariant.

Signed-off-by: Markus Armbruster 
---
  block.c|  10 ++--
  block/block-backend.c  |  70 ++-
  blockdev.c |  26 +++--
  hw/block/xen_disk.c|   8 +--
  include/block/block_int.h  |   2 +
  include/sysemu/block-backend.h |   5 ++
  qemu-img.c | 125 +++--
  qemu-io.c  |   4 +-
  qemu-nbd.c |   2 +-
  9 files changed, 152 insertions(+), 100 deletions(-)


[snip]


diff --git a/block/block-backend.c b/block/block-backend.c
index 919dd4c..b118b38 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -16,10 +16,11 @@
  struct BlockBackend {
  char *name;
  int refcnt;
+BlockDriverState *bs;
  QTAILQ_ENTRY(BlockBackend) link; /* for blk_backends */
  };
  
-/* All the BlockBackends */

+/* All the BlockBackends (except for hidden ones) */
  static QTAILQ_HEAD(, BlockBackend) blk_backends =
  QTAILQ_HEAD_INITIALIZER(blk_backends);
  
@@ -47,10 +48,43 @@ BlockBackend *blk_new(const char *name, Error **errp)

  return blk;
  }
  
+/*

+ * Create a new BlockBackend with a new BlockDriverState attached.
+ * Both have a reference count of one.  Caller owns *both* references.
+ * TODO Let caller own only the BlockBackend reference
+ * Otherwise just like blk_new(), which see.


Could be my lack of profoundness in English, but I don't understand what 
"which see" is supposed to mean or how its grammar works. An imperative?



+ */
+BlockBackend *blk_new_with_bs(const char *name, Error **errp)
+{
+BlockBackend *blk;
+BlockDriverState *bs;
+
+blk = blk_new(name, errp);
+if (!blk) {
+return NULL;
+}
+
+bs = bdrv_new_root(name, errp);
+if (!bs) {
+blk_unref(blk);
+return NULL;
+}
+
+blk->bs = bs;
+bs->blk = blk;
+return blk;
+}
+


[snip]


diff --git a/blockdev.c b/blockdev.c
index 5873205..21f4c67 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -229,14 +229,7 @@ void drive_info_del(DriveInfo *dinfo)
  qemu_opts_del(dinfo->opts);
  }
  
-/*

- * Hairy special case: if do_drive_del() has made dinfo->bdrv
- * anonymous, it also unref'ed the associated BlockBackend.
- */
-if (dinfo->bdrv->device_name[0]) {
-blk_unref(blk_by_name(dinfo->bdrv->device_name));
-}
-
+blk_unref(blk_by_name(dinfo->bdrv->device_name));


So if !device_name[0], the BB is hidden. Hidden BBs are removed from the 
BB list and therefore not returned by blk_by_name(). Therefore, the BB 
is leaked here.


I guess this will be fixed up in a later patch, though...


  g_free(dinfo->id);
  QTAILQ_REMOVE(&drives, dinfo, next);
  g_free(dinfo->serial);


[snip]


diff --git a/qemu-nbd.c b/qemu-nbd.c
index ff95da6..fa8a7d0 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -689,7 +689,7 @@ int main(int argc, char **argv)
  }
  
  blk = blk_new("hda", &error_abort);

-bs = bdrv_new_root("hda", &error_abort);
+bs = blk_bs(blk);


Shouldn't that be a blk_new_with_bs() then, just like every other case?


  srcpath = argv[optind];
  ret = bdrv_open(&bs, srcpath, NULL, NULL, flags, drv, &local_err);


Max



Re: [Qemu-devel] [PATCH v2 02/23] block: New BlockBackend

2014-09-13 Thread Max Reitz

On 13.09.2014 17:00, Markus Armbruster wrote:

A block device consists of a frontend device model and a backend.

A block backend has a tree of block drivers doing the actual work.
The tree is managed by the block layer.

We currently use a single abstraction BlockDriverState both for tree
nodes and the backend as a whole.  Drawbacks:

* Its API includes both stuff that makes sense only at the block
   backend level (root of the tree) and stuff that's only for use
   within the block layer.  This makes the API bigger and more complex
   than necessary.  Moreover, it's not obvious which interfaces are
   meant for device models, and which really aren't.

* Since device models keep a reference to their backend, the backend
   object can't just be destroyed.  But for media change, we need to
   replace the tree.  Our solution is to make the BlockDriverState
   generic, with actual driver state in a separate object, pointed to
   by member opaque.  That lets us replace the tree by deinitializing
   and reinitializing its root.  This special need of the root makes
   the data structure awkward everywhere in the tree.

The general plan is to separate the APIs into "block backend", for use
by device models, monitor and whatever other code dealing with block
backends, and "block driver", for use by the block layer and whatever
other code (if any) dealing with trees and tree nodes.

Code dealing with block backends, device models in particular, should
become completely oblivious of BlockDriverState.  This should let us
clean up both APIs, and the tree data structures.

This commit is a first step.  It creates a minimal "block backend"
API: type BlockBackend and functions to create, destroy and find them.

BlockBackend objects are created and destroyed exactly when root
BlockDriverState objects are created and destroyed.  "Root" in the
sense of "in bdrv_states".  They're not yet used for anything; that'll
come shortly.

BlockBackend is reference-counted.  Its reference count never exceeds
one so far, but that's going to change.

Signed-off-by: Markus Armbruster 
---
  block.c|   3 +-
  block/Makefile.objs|   2 +-
  block/block-backend.c  | 119 +
  blockdev.c |  21 +++-
  hw/block/xen_disk.c|  11 
  include/qemu/typedefs.h|   1 +
  include/sysemu/block-backend.h |  26 +
  qemu-img.c |  70 +---
  qemu-io.c  |   8 +++
  qemu-nbd.c |   5 +-
  10 files changed, 253 insertions(+), 13 deletions(-)
  create mode 100644 block/block-backend.c
  create mode 100644 include/sysemu/block-backend.h


[snip]


diff --git a/qemu-img.c b/qemu-img.c
index 58d59d0..acb272e 100644
--- a/qemu-img.c
+++ b/qemu-img.c


[snip]


@@ -942,6 +952,7 @@ static int check_empty_sectors(BlockDriverState *bs, 
int64_t sect_num,
  static int img_compare(int argc, char **argv)
  {
  const char *fmt1 = NULL, *fmt2 = NULL, *cache, *filename1, *filename2;
+BlockBackend *blk1, *blk2;
  BlockDriverState *bs1, *bs2;


By initializing all of these to NULL we could remove out1, out2 and 
out3, and just always go to out. But of course it's not wrong this way.


Reviewed-by: Max Reitz 



Re: [Qemu-devel] [PATCH v2 01/23] block: Split bdrv_new_root() off bdrv_new()

2014-09-13 Thread Max Reitz

On 13.09.2014 17:00, Markus Armbruster wrote:

Creating an anonymous BDS can't fail.  Make that obvious.

Signed-off-by: Markus Armbruster 
---
  block.c   | 28 +++-
  block/iscsi.c |  2 +-
  block/vvfat.c |  2 +-
  blockdev.c|  2 +-
  hw/block/xen_disk.c   |  2 +-
  include/block/block.h |  3 ++-
  qemu-img.c|  6 +++---
  qemu-io.c |  2 +-
  qemu-nbd.c|  2 +-
  9 files changed, 30 insertions(+), 19 deletions(-)


Reviewed-by: Max Reitz 



Re: [Qemu-devel] [PATCH 00/23] qom hooks to clean up cpu_exec

2014-09-13 Thread Paolo Bonzini
Il 13/09/2014 18:44, Richard Henderson ha scritto:
> 
> After the 23 patches, there's one (interesting) ifdef left.
> That is, i386 redefining CPU_INTERRUPT_RESET as CPU_INTERRUPT_INIT
> for its own purposes.  I'm not sure why all that couldn't be done
> under whatever hooks cpu_reset allows.

There are two reasons.

One is because INIT is intentionally weaker than RESET.  For example, it
doesn't clear many MSRs and the FPU state.

The second is because INIT can be intercepted by the virtual machine
monitor if SVM is enabled (KVM doesn't use it, but it is useful for
example when the virtual machine monitor is letting the virtual machine
use the hardware APIC).

The latter could well happen on more targets than just x86, so perhaps
we can have a reset_interrupt method that defaults to reset and is
overridden by x86?

> Failing that, we might be
> able to redefine C_I_I as a new CPU_INTERRUPT_TGT_INT_3 bit.

That would break migration, though admittedly only in a somewhat remote
case.

Paolo



Re: [Qemu-devel] [RFC 03/10] AHCI: Add PRD interrupt

2014-09-13 Thread Paolo Bonzini
Il 13/09/2014 15:26, Paolo Bonzini ha scritto:
>> >  
>> > +if (ad->dp_intr_req) {
>> > +ahci_trigger_irq(ad->hba, ad, PORT_IRQ_SG_DONE);
>> > +ad->dp_intr_req = 0;
>> > +}
> Is it also needed in the error case?  Especially the short-PRDT case
> that you are adding in the next patch.
> 

... and is it also needed for NCQ, albeit with a separate flag?

Paolo



Re: [Qemu-devel] [PATCH 2/4] block: Keep DriveInfo alive until BlockDriverState dies

2014-09-13 Thread Max Reitz

On 12.09.2014 21:26, Markus Armbruster wrote:

If the BDS's refcnt > 0, drive_del() destroys the DriveInfo, but not
the BDS.  This can happen in three places:

* Device model destruction during unplug: blockdev_auto_del()

* Xen IDE unplug: pci_piix3_xen_ide_unplug()

* drive_del command when no device model is attached: do_drive_del()

The other callers of drive_del are on error paths where refcnt == 1.

If the user somehow manages to plug in a device model using a BDS that
has gone through drive_del(), the legacy configuration passed in
DriveInfo doesn't reach the device model, and automatic deletion on
unplug doesn't work.  Worse, some device models such as scsi-disk
crash when DriveInfo doesn't exist.

This is theoretical; I didn't research an actual reproducer.

Fix by keeping DriveInfo alive until its BDS dies.

This affects qemu_drive_opts: now you can't reuse the same ID for new
drive options until the BDS dies.  Before, you could, but since the
code always attempts to create a BDS with the same ID next, the
enclosing operation "create a new drive" failed anyway.  Different
error path, same result.

Unfortunately, the fix involves use of blockdev.c stuff from block.c,
which is a layering violation.  Fortunately, my forthcoming
BlockBackend work will get rid of it again.

Signed-off-by: Markus Armbruster 
---
  block.c   |  2 ++
  blockdev.c| 13 -
  include/sysemu/blockdev.h |  1 +
  stubs/Makefile.objs   |  1 +
  stubs/blockdev.c  | 12 
  5 files changed, 24 insertions(+), 5 deletions(-)
  create mode 100644 stubs/blockdev.c


Seems reasonable.

Reviewed-by: Max Reitz 



Re: [Qemu-devel] [PATCH 4/4] block: Improve message for device name clashing with node name

2014-09-13 Thread Benoît Canet
The Friday 12 Sep 2014 à 21:26:24 (+0200), Markus Armbruster wrote :
> Suggested-by: Benoit Canet 
> Signed-off-by: Markus Armbruster 
> ---
>  block.c| 3 ++-
>  tests/qemu-iotests/087.out | 2 +-
>  2 files changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/block.c b/block.c
> index 6faf36f..02ea90f 100644
> --- a/block.c
> +++ b/block.c
> @@ -347,7 +347,8 @@ BlockDriverState *bdrv_new(const char *device_name, Error 
> **errp)
>  return NULL;
>  }
>  if (bdrv_find_node(device_name)) {
> -error_setg(errp, "Device with node-name '%s' already exists",
> +error_setg(errp,
> +   "Device name '%s' conflicts with an existing node name",
> device_name);
>  return NULL;
>  }
> diff --git a/tests/qemu-iotests/087.out b/tests/qemu-iotests/087.out
> index 7fbee3f..75a54e0 100644
> --- a/tests/qemu-iotests/087.out
> +++ b/tests/qemu-iotests/087.out
> @@ -20,7 +20,7 @@ QMP_VERSION
>  {"return": {}}
>  {"return": {}}
>  {"error": {"class": "GenericError", "desc": "Device with id 'disk' already 
> exists"}}
> -{"error": {"class": "GenericError", "desc": "Device with node-name 
> 'test-node' already exists"}}
> +{"error": {"class": "GenericError", "desc": "Device name 'test-node' 
> conflicts with an existing node name"}}
>  main-loop: WARNING: I/O thread spun for 1000 iterations
>  {"error": {"class": "GenericError", "desc": "could not open disk image 
> disk2: node-name=disk is conflicting with a device id"}}
>  {"error": {"class": "GenericError", "desc": "could not open disk image 
> disk2: Duplicate node name"}}
> -- 
> 1.9.3
> 

Reviewed-by: Benoît Canet 



Re: [Qemu-devel] [PATCH 1/4] blockdev: Disentangle BlockDriverState and DriveInfo creation

2014-09-13 Thread Max Reitz

On 12.09.2014 21:26, Markus Armbruster wrote:

blockdev_init() mixes up BlockDriverState and DriveInfo initialization
Finish the BlockDriverState job before starting to mess with
DriveInfo.  Easier on the eyes.

Signed-off-by: Markus Armbruster 
---
  blockdev.c | 43 +++
  1 file changed, 23 insertions(+), 20 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index b361fbb..5ec4635 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -301,6 +301,7 @@ static DriveInfo *blockdev_init(const char *file, QDict 
*bs_opts,
  int ro = 0;
  int bdrv_flags = 0;
  int on_read_error, on_write_error;
+BlockDriverState *bs;
  DriveInfo *dinfo;
  ThrottleConfig cfg;
  int snapshot = 0;
@@ -456,26 +457,27 @@ static DriveInfo *blockdev_init(const char *file, QDict 
*bs_opts,
  }
  
  /* init */

+bs = bdrv_new(qemu_opts_id(opts), errp);
+if (!bs) {
+goto early_err;
+}
+bs->open_flags = snapshot ? BDRV_O_SNAPSHOT : 0;
+bs->read_only = ro;
+bs->detect_zeroes = detect_zeroes;
+
+bdrv_set_on_error(bs, on_read_error, on_write_error);
+
+/* disk I/O throttling */
+if (throttle_enabled(&cfg)) {
+bdrv_io_limits_enable(bs);
+bdrv_set_io_limits(bs, &cfg);
+}
+
  dinfo = g_malloc0(sizeof(*dinfo));


Could've changed this to g_new0 in the process, but you're the expert 
for that, so I'll leave it up to you. ;-)



  dinfo->id = g_strdup(qemu_opts_id(opts));
-dinfo->bdrv = bdrv_new(dinfo->id, &error);
-if (error) {
-error_propagate(errp, error);
-goto bdrv_new_err;
-}
-dinfo->bdrv->open_flags = snapshot ? BDRV_O_SNAPSHOT : 0;
-dinfo->bdrv->read_only = ro;
-dinfo->bdrv->detect_zeroes = detect_zeroes;
+dinfo->bdrv = bs;
  QTAILQ_INSERT_TAIL(&drives, dinfo, next);
  
-bdrv_set_on_error(dinfo->bdrv, on_read_error, on_write_error);

-
-/* disk I/O throttling */
-if (throttle_enabled(&cfg)) {
-bdrv_io_limits_enable(dinfo->bdrv);
-bdrv_set_io_limits(dinfo->bdrv, &cfg);
-}
-
  if (!file || !*file) {
  if (has_driver_specific_opts) {
  file = NULL;
@@ -502,7 +504,8 @@ static DriveInfo *blockdev_init(const char *file, QDict 
*bs_opts,
  bdrv_flags |= ro ? 0 : BDRV_O_RDWR;
  
  QINCREF(bs_opts);

-ret = bdrv_open(&dinfo->bdrv, file, NULL, bs_opts, bdrv_flags, drv, 
&error);
+ret = bdrv_open(&bs, file, NULL, bs_opts, bdrv_flags, drv, &error);
+assert(bs == dinfo->bdrv);


Well, this is guaranteed by bdrv_open(), but of course better having too 
many assertions than too few.


With or without g_new0:

Reviewed-by: Max Reitz 



Re: [Qemu-devel] [PATCH] vmdk: Fix integer overflow in offset calculation

2014-09-13 Thread Max Reitz

On 12.09.2014 11:51, Fam Zheng wrote:

This fixes the bug introduced by commit c6ac36e (vmdk: Optimize cluster
allocation).

$ ~/build/master/qemu-io /stor/vm/arch.vmdk -c 'write 2G 1k'
write failed: Invalid argument

Reported-by: Mark Cave-Ayland 
Signed-off-by: Fam Zheng 
---
  block/vmdk.c   | 2 +-
  tests/qemu-iotests/059 | 6 ++
  tests/qemu-iotests/059.out | 7 +++
  3 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index a1cb911..3fd7738 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1113,7 +1113,7 @@ static int get_cluster_offset(BlockDriverState *bs,
  uint32_t min_count, *l2_table;
  bool zeroed = false;
  int64_t ret;
-int32_t cluster_sector;
+int64_t cluster_sector;
  
  if (m_data) {

  m_data->valid = 0;


The fix is okay.


diff --git a/tests/qemu-iotests/059 b/tests/qemu-iotests/059
index 3c053c2..6ed2a25 100755
--- a/tests/qemu-iotests/059
+++ b/tests/qemu-iotests/059
@@ -126,6 +126,12 @@ _img_info
  $QEMU_IO -c "write -P 0xa 900G 512" "$TEST_IMG" | _filter_qemu_io
  $QEMU_IO -c "read -v 900G 1024" "$TEST_IMG" | _filter_qemu_io
  
+echo

+echo "=== Testing reading and writing at big offset ==="
+_make_test_img 4T
+$QEMU_IO -c "write -P 0xa 1T 1024" "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c "read -P 0xa 1T 1024" "$TEST_IMG" | _filter_qemu_io
+
  # success, all done
  echo "*** done"
  rm -f $seq.full
diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out
index 0dadba6..51c72a6 100644
--- a/tests/qemu-iotests/059.out
+++ b/tests/qemu-iotests/059.out
@@ -2332,4 +2332,11 @@ e103e0:  00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00  
  e103f0:  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
  read 1024/1024 bytes at offset 966367641600
  1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+=== Testing reading and writing at big offset ===
+Formatting 'TEST_DIR/iotest-version3.IMGFMT', fmt=IMGFMT size=4398046511104
+wrote 1024/1024 bytes at offset 1099511627776
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 1024/1024 bytes at offset 1099511627776
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
  *** done


This test is not. It works even without the fix for me. The problem is 
that this does not depend on the guest disk size or the guest offset, 
but on the host offset. So the problem only appears if the image has 
been filled enough so that the host offsets grow large enough 
(apparently, at least).


However, the first host offset written to does depend on the image size. 
For 2 GB images, it's 0x9; for 4 TB images, it's 0x2011; and for 
16 TB images, it finally overflows, *independently* on the guest offset 
written to. So I suggest you create a 16 TB image here (or maybe an 
image which is as large as possible, for testing purposes) and then you 
can write anywhere (maybe once at the very beginning and once at the 
very end, if that works).


Max



Re: [Qemu-devel] [question] virtio-blk performance degradation happened with virito-serial

2014-09-13 Thread Max Reitz

On 12.09.2014 14:38, Stefan Hajnoczi wrote:

Max: Unrelated to this performance issue but I notice that the qcow2
metadata overlap check is high in the host CPU profile.  Have you had
any thoughts about optimizing the check?

Stefan


In fact, I have done so (albeit only briefly). Instead of gathering all 
the information in the overlap function itself, we could either have a 
generic list of typed ranges (e.g. "cluster 0: header", "clusters 1 to 
5: L1 table", etc.) or a not-really-bitmap (with 4 bits per entry 
specifying the cluster type (header, L1 table, free or data cluster, etc.)).


The disadvantage of the former would be that in its simplest form we'd 
have to run through the whole list to find out whether a cluster is 
already reserved for metadata or not. We could easily optimize this by 
keeping the list in order and then performing a binary search.


The disadvantage of the latter would obviously be its memory size. For a 
1 TB image with 64 kB clusters, it would be 8 MB in size. Could be 
considered acceptable, but I deem it too large. The advantage would be 
constant access time, of course.


We could combine both approaches, that is, using the bitmap as a cache: 
Whenever a cluster is overlap checked, the corresponding bitmap range 
(or "bitmap window") is requested; if that is not available, it is 
generated from the range list and then put into the cache.


The remaining question is how large the range list would be in memory. 
Basically, its size would be comparable to an RLE version of the bitmap. 
In contrast to a raw RLE version, however, we'd have to add the start 
cluster to each entry in order to be able to perform binary search and 
we'd omit free and/or data clusters. So, we'd have 4 bits for the 
cluster type, let's say 12 bits for the cluster count and of course 64 
bits for the first cluster index. Or, for maximum efficiency, we'd have 
64 - 9 - 1 = 54 bits for the cluster index, 4 bits for the type and then 
6 bits for the cluster count. The first variant gives us 10 bytes per 
metadata range, the second 8. Considering one refcount block can handle 
cluster_size / 2 entries and one L2 table can handle cluster_size / 8 
entries, we have (for images with a cluster size of 64 kB) a ratio of 
about 1/32768 refcount blocks per cluster and 1/8192 L2 tables per 
cluster. I guess we therefore have a metadata ratio of about 1/6000. At 
the worst, each metadata cluster requires its own range list entry, 
which for 10 bytes per entry means less than 30 kB for the list of a 1 
TB image with 64 kB clusters. I think that's acceptable.


We could compress that list even more by making it a real RLE version of 
the bitmap, removing the cluster index from each entry; remember that 
for this mixed range list/bitmap approach we no longer need to be able 
to perform exact binary search but only need to be able to quickly seek 
to the beginning of a bitmap window. This can be achieved by forcing 
breaks in the range list at every window border and keeping track of 
those offsets along with the corresponding bitmap window index. When we 
want to generate a bitmap window, we look up the start offset in the 
range list (constant time), then generate it (linear to window size) and 
can then perform constant-time lookups for each overlap checks in that 
window.


I think that could greatly speed things up and also allow us to always 
perform range checks on data structures not kept in memory (inactive L1 
and L2 tables). The only question now remaining to me is whether that 
caching is actually feasible or whether binary search into the range 
list (which then would have to include the cluster index for each entry) 
would be faster than generating bitmap windows which might suffer from 
ping-pong effects.


Max



[Qemu-devel] BB name vs. BDS name in the QAPI schema

2014-09-13 Thread Markus Armbruster
This has been discussed on IRC, but I want it on the list for further
discussion and later reference.

Terminology: BDS = BlockDriverState, BB = BlockBackend

Traditionally, only root BDSes could be named.  They're always uniquely
named; if the user doesn't supply a name via -drive parameter "id", the
system makes one up.  This name is stored in BDS member device_name[].
In the QAPI schema, it's called "device", both in arguments and in
results.

Having a name is not the only property that makes root BDSes special.
More on that below.

Kevin's "blockdev-add QMP command" series (commit 52c8d62..b681072, Sep
2013) adds a way to name interior nodes, not just roots.  It names the
blockdev-add parameter "id" rather to the "device".

Benoît's "Giving names to graph's BlockDriverState" series (commit
c8059b9..0901f67, Jan 2014) adds the node-name concept.  When define
BDSes, the user can give them a unique node-name, with blockdev-add
parameter "node-name".  -drive supports it, too.  This name is stored in
BDS member node_name[].  In the QAPI schema, it's usually called
"node-name".

Aside: a couple of QMP commands predating node names identify an
interior BDS by its BB name and a backing "filename".  Resolves to the
first BDSes below BB whose "filename" matches.  These should all be
updated to work with BDS names instead.

Node names are in the same name space as the device names.  Without
that, a name could be ambiguous unless you know whether it's a device
name or a node name.

We exploit that in the schema: anonymous union BlockdevRef has a string
member "reference", and both kinds of names are valid there.  Introduced
by Kevin's blockdev-add series, i.e. it predates node names.  Used to
connect sub-trees with blockdev-add.

In other words, the node names series extends BlockdevRef to accept node
names in addition to device names.  Good, because *want* to be able to
use them to connect sub-trees with blockdev-add.

Wherever else the ability to use both device and node names is wanted,
however, we use a pair of parameters, usually "device" and "node-name".
You can use either one or the other, not both.

I'm currently working on putting a BB on top of each root BDS[*].  First
step towards moving all the "root specialness" from BDS to BB, leaving
the root BDS non-special.  In this world, device_name[] moves from BDS
to BB.

Thus, the two kinds of names become BB names (a.k.a. device names) and
BDS names (a.k.a. node-names).

Since BB names and BDS names share a namespace, a name unambiguously
resolves either to a BB, a BDS, or nothing.

In places where we want to name a BB, the schema has a parameter,
usually named "device", and its valid values are the BB names.

In places where we want to name a BDS, the schema has either

* Two parameters, usually named "device" and "node-name", valid values
  for the former are the BB names, and for the latter the BDS names.

* A single parameter, and both BB names and BDS names are valid values.

Either way, naming a BB really names its BDS.  No change from before the
introduction of BBs, because then the name still belonged to that BDS.

Having two different ways to do the same thing bothers me.  What about
you?

If it bothers us: can we do something about it?

I actually like having separate parameters for separate kinds of names.  

However, BlockdevRef appears to tie our hand: it's an anonymous union,
which means only the value is on the wire, and the receiving end uses
its type to determine which union member it is.  Both kinds of names are
strings, so we can't have separate union members for them.

Opinions?


[*] [PATCH v2 00/23] Split BlockBackend off BDS with an axe



Re: [Qemu-devel] [RFC 01/10] ide: add is_write() macro for semantic consistency

2014-09-13 Thread John Snow



On 09/13/2014 08:54 AM, Paolo Bonzini wrote:

Il 13/09/2014 06:34, John Snow ha scritto:

The prepare_buf callback takes an argument named /is_write/,
however in core.c we are checking to see if this DMA command
is /is_read/. I am adding a small macro to correct this oversight.

Impact: Nothing, yet.
-The prepare_buf callback is only used in ahci and pci, and both
  versions of this callback name the incoming argument is_write.
-Both functions ignore this hint currently, anyway.

This is therefore a simple patch to avoid future mistakes.

Signed-off-by: John Snow 
---
  hw/ide/core.c | 2 +-
  hw/ide/internal.h | 2 ++
  2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/ide/core.c b/hw/ide/core.c
index 191f893..3d682e2 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -718,7 +718,7 @@ void ide_dma_cb(void *opaque, int ret)
  n = s->nsector;
  s->io_buffer_index = 0;
  s->io_buffer_size = n * 512;
-if (s->bus->dma->ops->prepare_buf(s->bus->dma, ide_cmd_is_read(s)) == 0) {
+if (s->bus->dma->ops->prepare_buf(s->bus->dma, ide_cmd_is_write(s)) == 0) {
  /* The PRDs were too short. Reset the Active bit, but don't raise an
   * interrupt. */
  s->status = READY_STAT | SEEK_STAT;
diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index 5c19f79..72d0147 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -338,6 +338,8 @@ enum ide_dma_cmd {

  #define ide_cmd_is_read(s) \
((s)->dma_cmd == IDE_DMA_READ)
+#define ide_cmd_is_write(s) \
+((s)->dma_cmd == IDE_DMA_WRITE)

  /* NOTE: IDEState represents in fact one drive */
  struct IDEState {



Actually the code is right (!).

A read command corresponds to a DMA write.  A write or trim will read
data from memory, so it is a DMA read.

See for example how rw_buf is only used from the READ CD command, but
passes 1 for the second argument of prepare_buf.

Paolo



Ah, okay ... It didn't seem as if this argument was actually getting 
/used/ anywhere yet, so it wasn't really clear what it was intended to 
mean or for whom. None of the prepare_buf implementations actually seem 
to use this bit.


If you think this is correct the way it is, we should probably add some 
documentation to the prepare_buf callback to explain the nature of the 
argument to prevent someone from being helpful and trying to fix it 
again in the future.


Thanks for reviewing, this series is RFC for a reason :)



[Qemu-devel] [PATCH 18/23] target-mips: Use cpu_exec_interrupt qom hook

2014-09-13 Thread Richard Henderson
Cc: Aurelien Jarno 
Signed-off-by: Richard Henderson 
---
 cpu-exec.c|  9 -
 target-mips/cpu-qom.h |  1 +
 target-mips/cpu.c |  1 +
 target-mips/helper.c  | 17 +
 4 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 7e9f4cd..60f7270 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -514,15 +514,6 @@ int cpu_exec(CPUArchState *env)
 cc->do_interrupt(cpu);
 next_tb = 0;
 }
-#elif defined(TARGET_MIPS)
-if ((interrupt_request & CPU_INTERRUPT_HARD) &&
-cpu_mips_hw_interrupts_pending(env)) {
-/* Raise it */
-cpu->exception_index = EXCP_EXT_INTERRUPT;
-env->error_code = 0;
-cc->do_interrupt(cpu);
-next_tb = 0;
-}
 #endif
 /* The target hook has 3 exit conditions:
False when the interrupt isn't processed,
diff --git a/target-mips/cpu-qom.h b/target-mips/cpu-qom.h
index 2cff15a..2ffc1bf 100644
--- a/target-mips/cpu-qom.h
+++ b/target-mips/cpu-qom.h
@@ -75,6 +75,7 @@ static inline MIPSCPU *mips_env_get_cpu(CPUMIPSState *env)
 #define ENV_OFFSET offsetof(MIPSCPU, env)
 
 void mips_cpu_do_interrupt(CPUState *cpu);
+bool mips_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void mips_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
  int flags);
 hwaddr mips_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target-mips/cpu.c b/target-mips/cpu.c
index b3e0e6c..5ed60f7 100644
--- a/target-mips/cpu.c
+++ b/target-mips/cpu.c
@@ -136,6 +136,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
 
 cc->has_work = mips_cpu_has_work;
 cc->do_interrupt = mips_cpu_do_interrupt;
+cc->cpu_exec_interrupt = mips_cpu_exec_interrupt;
 cc->dump_state = mips_cpu_dump_state;
 cc->set_pc = mips_cpu_set_pc;
 cc->synchronize_from_tb = mips_cpu_synchronize_from_tb;
diff --git a/target-mips/helper.c b/target-mips/helper.c
index 8a997e4..fe16820 100644
--- a/target-mips/helper.c
+++ b/target-mips/helper.c
@@ -675,6 +675,23 @@ void mips_cpu_do_interrupt(CPUState *cs)
 cs->exception_index = EXCP_NONE;
 }
 
+bool mips_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+{
+if (interrupt_request & CPU_INTERRUPT_HARD) {
+MIPSCPU *cpu = MIPS_CPU(cs);
+CPUMIPSState *env = &cpu->env;
+
+if (cpu_mips_hw_interrupts_pending(env)) {
+/* Raise it */
+cs->exception_index = EXCP_EXT_INTERRUPT;
+env->error_code = 0;
+mips_cpu_do_interrupt(cs);
+return true;
+}
+}
+return false;
+}
+
 #if !defined(CONFIG_USER_ONLY)
 void r4k_invalidate_tlb (CPUMIPSState *env, int idx, int use_extra)
 {
-- 
1.9.3




[Qemu-devel] [PATCH 13/23] target-unicore32: Use cpu_exec_interrupt qom hook

2014-09-13 Thread Richard Henderson
Cc: Guan Xuetao 
Signed-off-by: Richard Henderson 
---
 cpu-exec.c |  7 ---
 target-unicore32/cpu-qom.h |  1 +
 target-unicore32/cpu.c |  1 +
 target-unicore32/helper.c  | 15 +++
 4 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index d7f7686..b7b012b 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -585,13 +585,6 @@ int cpu_exec(CPUArchState *env)
 cc->do_interrupt(cpu);
 next_tb = 0;
 }
-#elif defined(TARGET_UNICORE32)
-if (interrupt_request & CPU_INTERRUPT_HARD
-&& !(env->uncached_asr & ASR_I)) {
-cpu->exception_index = UC32_EXCP_INTR;
-cc->do_interrupt(cpu);
-next_tb = 0;
-}
 #endif
 /* The target hook has 3 exit conditions:
False when the interrupt isn't processed,
diff --git a/target-unicore32/cpu-qom.h b/target-unicore32/cpu-qom.h
index f727760..ea65b83 100644
--- a/target-unicore32/cpu-qom.h
+++ b/target-unicore32/cpu-qom.h
@@ -61,6 +61,7 @@ static inline UniCore32CPU 
*uc32_env_get_cpu(CPUUniCore32State *env)
 #define ENV_OFFSET offsetof(UniCore32CPU, env)
 
 void uc32_cpu_do_interrupt(CPUState *cpu);
+bool uc32_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void uc32_cpu_dump_state(CPUState *cpu, FILE *f,
  fprintf_function cpu_fprintf, int flags);
 hwaddr uc32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target-unicore32/cpu.c b/target-unicore32/cpu.c
index 2d2c429..5b32987 100644
--- a/target-unicore32/cpu.c
+++ b/target-unicore32/cpu.c
@@ -146,6 +146,7 @@ static void uc32_cpu_class_init(ObjectClass *oc, void *data)
 cc->class_by_name = uc32_cpu_class_by_name;
 cc->has_work = uc32_cpu_has_work;
 cc->do_interrupt = uc32_cpu_do_interrupt;
+cc->cpu_exec_interrupt = uc32_cpu_exec_interrupt;
 cc->dump_state = uc32_cpu_dump_state;
 cc->set_pc = uc32_cpu_set_pc;
 #ifdef CONFIG_USER_ONLY
diff --git a/target-unicore32/helper.c b/target-unicore32/helper.c
index e5ebbf4..b4654fa 100644
--- a/target-unicore32/helper.c
+++ b/target-unicore32/helper.c
@@ -250,3 +250,18 @@ int uc32_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
 return 1;
 }
 #endif
+
+bool uc32_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+{
+if (interrupt_request & CPU_INTERRUPT_HARD) {
+UniCore32CPU *cpu = UNICORE32_CPU(cs);
+CPUUniCore32State *env = &cpu->env;
+
+if (!(env->uncached_asr & ASR_I)) {
+cs->exception_index = UC32_EXCP_INTR;
+uc32_cpu_do_interrupt(cs);
+return true;
+}
+}
+return false;
+}
-- 
1.9.3




[Qemu-devel] [PATCH 22/23] target-i386: Use cpu_exec_interrupt qom hook

2014-09-13 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 cpu-exec.c   | 64 
 target-i386/cpu-qom.h|  1 +
 target-i386/cpu.c|  1 +
 target-i386/seg_helper.c | 69 
 4 files changed, 71 insertions(+), 64 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index a423ac3..b977481 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -427,70 +427,6 @@ int cpu_exec(CPUArchState *env)
 cpu_reset(cpu);
 }
 #endif
-#if defined(TARGET_I386)
-#if !defined(CONFIG_USER_ONLY)
-if (interrupt_request & CPU_INTERRUPT_POLL) {
-cpu->interrupt_request &= ~CPU_INTERRUPT_POLL;
-apic_poll_irq(x86_cpu->apic_state);
-}
-#endif
-if (interrupt_request & CPU_INTERRUPT_SIPI) {
-do_cpu_sipi(x86_cpu);
-} else if (env->hflags2 & HF2_GIF_MASK) {
-if ((interrupt_request & CPU_INTERRUPT_SMI) &&
-!(env->hflags & HF_SMM_MASK)) {
-cpu_svm_check_intercept_param(env, SVM_EXIT_SMI,
-  0);
-cpu->interrupt_request &= ~CPU_INTERRUPT_SMI;
-do_smm_enter(x86_cpu);
-next_tb = 0;
-} else if ((interrupt_request & CPU_INTERRUPT_NMI) &&
-   !(env->hflags2 & HF2_NMI_MASK)) {
-cpu->interrupt_request &= ~CPU_INTERRUPT_NMI;
-env->hflags2 |= HF2_NMI_MASK;
-do_interrupt_x86_hardirq(env, EXCP02_NMI, 1);
-next_tb = 0;
-} else if (interrupt_request & CPU_INTERRUPT_MCE) {
-cpu->interrupt_request &= ~CPU_INTERRUPT_MCE;
-do_interrupt_x86_hardirq(env, EXCP12_MCHK, 0);
-next_tb = 0;
-} else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
-   (((env->hflags2 & HF2_VINTR_MASK) && 
- (env->hflags2 & HF2_HIF_MASK)) ||
-(!(env->hflags2 & HF2_VINTR_MASK) && 
- (env->eflags & IF_MASK && 
-  !(env->hflags & HF_INHIBIT_IRQ_MASK) 
{
-int intno;
-cpu_svm_check_intercept_param(env, SVM_EXIT_INTR,
-  0);
-cpu->interrupt_request &= ~(CPU_INTERRUPT_HARD |
-CPU_INTERRUPT_VIRQ);
-intno = cpu_get_pic_interrupt(env);
-qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing 
hardware INT=0x%02x\n", intno);
-do_interrupt_x86_hardirq(env, intno, 1);
-/* ensure that no TB jump will be modified as
-   the program flow was changed */
-next_tb = 0;
-#if !defined(CONFIG_USER_ONLY)
-} else if ((interrupt_request & CPU_INTERRUPT_VIRQ) &&
-   (env->eflags & IF_MASK) && 
-   !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
-int intno;
-/* FIXME: this should respect TPR */
-cpu_svm_check_intercept_param(env, SVM_EXIT_VINTR,
-  0);
-intno = ldl_phys(cpu->as,
- env->vm_vmcb
- + offsetof(struct vmcb,
-control.int_vector));
-qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing 
virtual hardware INT=0x%02x\n", intno);
-do_interrupt_x86_hardirq(env, intno, 1);
-cpu->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
-next_tb = 0;
-#endif
-}
-}
-#endif
 /* The target hook has 3 exit conditions:
False when the interrupt isn't processed,
True when it is, and we should restart on a new TB,
diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
index b242cb0..b557b61 100644
--- a/target-i386/cpu-qom.h
+++ b/target-i386/cpu-qom.h
@@ -130,6 +130,7 @@ extern struct VMStateDescription vmstate_x86_cpu;
  * @cpu: vCPU the interrupt is to be handled by.
  */
 void x86_cpu_do_interrupt(CPUState *cpu);
+bool x86_cpu_exec

[Qemu-devel] [PATCH 12/23] target-sh4: Use cpu_exec_interrupt qom hook

2014-09-13 Thread Richard Henderson
Cc: Aurelien Jarno 
Signed-off-by: Richard Henderson 
---
 cpu-exec.c   | 5 -
 target-sh4/cpu-qom.h | 1 +
 target-sh4/cpu.c | 1 +
 target-sh4/helper.c  | 9 +
 4 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 2f73be4..d7f7686 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -592,11 +592,6 @@ int cpu_exec(CPUArchState *env)
 cc->do_interrupt(cpu);
 next_tb = 0;
 }
-#elif defined(TARGET_SH4)
-if (interrupt_request & CPU_INTERRUPT_HARD) {
-cc->do_interrupt(cpu);
-next_tb = 0;
-}
 #endif
 /* The target hook has 3 exit conditions:
False when the interrupt isn't processed,
diff --git a/target-sh4/cpu-qom.h b/target-sh4/cpu-qom.h
index c04e786..6341238 100644
--- a/target-sh4/cpu-qom.h
+++ b/target-sh4/cpu-qom.h
@@ -84,6 +84,7 @@ static inline SuperHCPU *sh_env_get_cpu(CPUSH4State *env)
 #define ENV_OFFSET offsetof(SuperHCPU, env)
 
 void superh_cpu_do_interrupt(CPUState *cpu);
+bool superh_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void superh_cpu_dump_state(CPUState *cpu, FILE *f,
fprintf_function cpu_fprintf, int flags);
 hwaddr superh_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c
index e7f0521..d187a2b 100644
--- a/target-sh4/cpu.c
+++ b/target-sh4/cpu.c
@@ -276,6 +276,7 @@ static void superh_cpu_class_init(ObjectClass *oc, void 
*data)
 cc->class_by_name = superh_cpu_class_by_name;
 cc->has_work = superh_cpu_has_work;
 cc->do_interrupt = superh_cpu_do_interrupt;
+cc->cpu_exec_interrupt = superh_cpu_exec_interrupt;
 cc->dump_state = superh_cpu_dump_state;
 cc->set_pc = superh_cpu_set_pc;
 cc->synchronize_from_tb = superh_cpu_synchronize_from_tb;
diff --git a/target-sh4/helper.c b/target-sh4/helper.c
index 9ebdd5c..5811360 100644
--- a/target-sh4/helper.c
+++ b/target-sh4/helper.c
@@ -863,3 +863,12 @@ int cpu_sh4_is_cached(CPUSH4State * env, target_ulong addr)
 }
 
 #endif
+
+bool superh_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+{
+if (interrupt_request & CPU_INTERRUPT_HARD) {
+superh_cpu_do_interrupt(cs);
+return true;
+}
+return false;
+}
-- 
1.9.3




[Qemu-devel] [PATCH 21/23] target-ppc: Use cpu_exec_interrupt qom hook

2014-09-13 Thread Richard Henderson
Cc: qemu-...@nongnu.org
Signed-off-by: Richard Henderson 
---
 cpu-exec.c  |  8 
 target-ppc/cpu-qom.h|  1 +
 target-ppc/cpu.h|  1 -
 target-ppc/excp_helper.c| 19 +--
 target-ppc/translate_init.c |  1 +
 5 files changed, 19 insertions(+), 11 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index abffbe5..a423ac3 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -490,14 +490,6 @@ int cpu_exec(CPUArchState *env)
 #endif
 }
 }
-#elif defined(TARGET_PPC)
-if (interrupt_request & CPU_INTERRUPT_HARD) {
-ppc_hw_interrupt(env);
-if (env->pending_interrupts == 0) {
-cpu->interrupt_request &= ~CPU_INTERRUPT_HARD;
-}
-next_tb = 0;
-}
 #endif
 /* The target hook has 3 exit conditions:
False when the interrupt isn't processed,
diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h
index a379f79..6967a80 100644
--- a/target-ppc/cpu-qom.h
+++ b/target-ppc/cpu-qom.h
@@ -113,6 +113,7 @@ PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr);
 PowerPCCPUClass *ppc_cpu_class_by_pvr_mask(uint32_t pvr);
 
 void ppc_cpu_do_interrupt(CPUState *cpu);
+bool ppc_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void ppc_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
 int flags);
 void ppc_cpu_dump_statistics(CPUState *cpu, FILE *f,
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index b64c652..8724561 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1147,7 +1147,6 @@ int cpu_ppc_exec (CPUPPCState *s);
is returned if the signal was handled by the virtual CPU.  */
 int cpu_ppc_signal_handler (int host_signum, void *pinfo,
 void *puc);
-void ppc_hw_interrupt (CPUPPCState *env);
 #if defined(CONFIG_USER_ONLY)
 int ppc_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
  int mmu_idx);
diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
index 922e86d..b803475 100644
--- a/target-ppc/excp_helper.c
+++ b/target-ppc/excp_helper.c
@@ -48,7 +48,7 @@ void ppc_cpu_do_interrupt(CPUState *cs)
 env->error_code = 0;
 }
 
-void ppc_hw_interrupt(CPUPPCState *env)
+static void ppc_hw_interrupt(CPUPPCState *env)
 {
 CPUState *cs = CPU(ppc_env_get_cpu(env));
 
@@ -692,7 +692,7 @@ void ppc_cpu_do_interrupt(CPUState *cs)
 powerpc_excp(cpu, env->excp_model, cs->exception_index);
 }
 
-void ppc_hw_interrupt(CPUPPCState *env)
+static void ppc_hw_interrupt(CPUPPCState *env)
 {
 PowerPCCPU *cpu = ppc_env_get_cpu(env);
 int hdice;
@@ -820,6 +820,21 @@ void ppc_cpu_do_system_reset(CPUState *cs)
 }
 #endif /* !CONFIG_USER_ONLY */
 
+bool ppc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+{
+PowerPCCPU *cpu = POWERPC_CPU(cs);
+CPUPPCState *env = &cpu->env;
+
+if (interrupt_request & CPU_INTERRUPT_HARD) {
+ppc_hw_interrupt(env);
+if (env->pending_interrupts == 0) {
+cs->interrupt_request &= ~CPU_INTERRUPT_HARD;
+}
+return true;
+}
+return false;
+}
+
 #if defined(DEBUG_OP)
 static void cpu_dump_rfi(target_ulong RA, target_ulong msr)
 {
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index e577e03..65b840d 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -9631,6 +9631,7 @@ static void ppc_cpu_class_init(ObjectClass *oc, void 
*data)
 cc->class_by_name = ppc_cpu_class_by_name;
 cc->has_work = ppc_cpu_has_work;
 cc->do_interrupt = ppc_cpu_do_interrupt;
+cc->cpu_exec_interrupt = ppc_cpu_exec_interrupt;
 cc->dump_state = ppc_cpu_dump_state;
 cc->dump_statistics = ppc_cpu_dump_statistics;
 cc->set_pc = ppc_cpu_set_pc;
-- 
1.9.3




[Qemu-devel] [PATCH 10/23] target-cris: Use cpu_exec_interrupt qom hook

2014-09-13 Thread Richard Henderson
Cc: Edgar E. Iglesias 
Signed-off-by: Richard Henderson 
---
 cpu-exec.c| 21 -
 target-cris/cpu-qom.h |  1 +
 target-cris/cpu.c |  1 +
 target-cris/helper.c  | 31 +++
 4 files changed, 33 insertions(+), 21 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 8ff85ba..7efcf27 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -629,27 +629,6 @@ int cpu_exec(CPUArchState *env)
 next_tb = 0;
 }
 }
-#elif defined(TARGET_CRIS)
-if (interrupt_request & CPU_INTERRUPT_HARD
-&& (env->pregs[PR_CCS] & I_FLAG)
-&& !env->locked_irq) {
-cpu->exception_index = EXCP_IRQ;
-cc->do_interrupt(cpu);
-next_tb = 0;
-}
-if (interrupt_request & CPU_INTERRUPT_NMI) {
-unsigned int m_flag_archval;
-if (env->pregs[PR_VR] < 32) {
-m_flag_archval = M_FLAG_V10;
-} else {
-m_flag_archval = M_FLAG_V32;
-}
-if ((env->pregs[PR_CCS] & m_flag_archval)) {
-cpu->exception_index = EXCP_NMI;
-cc->do_interrupt(cpu);
-next_tb = 0;
-}
-}
 #endif
 /* The target hook has 3 exit conditions:
False when the interrupt isn't processed,
diff --git a/target-cris/cpu-qom.h b/target-cris/cpu-qom.h
index 7559366..6fc30c2 100644
--- a/target-cris/cpu-qom.h
+++ b/target-cris/cpu-qom.h
@@ -75,6 +75,7 @@ static inline CRISCPU *cris_env_get_cpu(CPUCRISState *env)
 
 void cris_cpu_do_interrupt(CPUState *cpu);
 void crisv10_cpu_do_interrupt(CPUState *cpu);
+bool cris_cpu_exec_interrupt(CPUState *cpu, int int_req);
 
 void cris_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
  int flags);
diff --git a/target-cris/cpu.c b/target-cris/cpu.c
index 20d8809..528e458 100644
--- a/target-cris/cpu.c
+++ b/target-cris/cpu.c
@@ -279,6 +279,7 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data)
 cc->class_by_name = cris_cpu_class_by_name;
 cc->has_work = cris_cpu_has_work;
 cc->do_interrupt = cris_cpu_do_interrupt;
+cc->cpu_exec_interrupt = cris_cpu_exec_interrupt;
 cc->dump_state = cris_cpu_dump_state;
 cc->set_pc = cris_cpu_set_pc;
 cc->gdb_read_register = cris_cpu_gdb_read_register;
diff --git a/target-cris/helper.c b/target-cris/helper.c
index e8b8261..e901c3a 100644
--- a/target-cris/helper.c
+++ b/target-cris/helper.c
@@ -283,3 +283,34 @@ hwaddr cris_cpu_get_phys_page_debug(CPUState *cs, vaddr 
addr)
 return phy;
 }
 #endif
+
+bool cris_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+{
+CPUClass *cc = CPU_GET_CLASS(cs);
+CRISCPU *cpu = CRIS_CPU(cs);
+CPUCRISState *env = &cpu->env;
+bool ret = false;
+
+if (interrupt_request & CPU_INTERRUPT_HARD
+&& (env->pregs[PR_CCS] & I_FLAG)
+&& !env->locked_irq) {
+cs->exception_index = EXCP_IRQ;
+cc->do_interrupt(cs);
+ret = true;
+}
+if (interrupt_request & CPU_INTERRUPT_NMI) {
+unsigned int m_flag_archval;
+if (env->pregs[PR_VR] < 32) {
+m_flag_archval = M_FLAG_V10;
+} else {
+m_flag_archval = M_FLAG_V32;
+}
+if ((env->pregs[PR_CCS] & m_flag_archval)) {
+cs->exception_index = EXCP_NMI;
+cc->do_interrupt(cs);
+ret = true;
+}
+}
+
+return ret;
+}
-- 
1.9.3




[Qemu-devel] [PATCH 20/23] target-lm32: Use cpu_exec_interrupt qom hook

2014-09-13 Thread Richard Henderson
Cc: Michael Walle 
Signed-off-by: Richard Henderson 
---
 cpu-exec.c|  7 ---
 target-lm32/cpu-qom.h |  1 +
 target-lm32/cpu.c |  1 +
 target-lm32/helper.c  | 13 +
 4 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 5c93a5f..abffbe5 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -498,13 +498,6 @@ int cpu_exec(CPUArchState *env)
 }
 next_tb = 0;
 }
-#elif defined(TARGET_LM32)
-if ((interrupt_request & CPU_INTERRUPT_HARD)
-&& (env->ie & IE_IE)) {
-cpu->exception_index = EXCP_IRQ;
-cc->do_interrupt(cpu);
-next_tb = 0;
-}
 #endif
 /* The target hook has 3 exit conditions:
False when the interrupt isn't processed,
diff --git a/target-lm32/cpu-qom.h b/target-lm32/cpu-qom.h
index 9f15093..77bc7b2 100644
--- a/target-lm32/cpu-qom.h
+++ b/target-lm32/cpu-qom.h
@@ -82,6 +82,7 @@ extern const struct VMStateDescription vmstate_lm32_cpu;
 #endif
 
 void lm32_cpu_do_interrupt(CPUState *cpu);
+bool lm32_cpu_exec_interrupt(CPUState *cs, int int_req);
 void lm32_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
  int flags);
 hwaddr lm32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c
index 419d664..6c5de66 100644
--- a/target-lm32/cpu.c
+++ b/target-lm32/cpu.c
@@ -261,6 +261,7 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data)
 cc->class_by_name = lm32_cpu_class_by_name;
 cc->has_work = lm32_cpu_has_work;
 cc->do_interrupt = lm32_cpu_do_interrupt;
+cc->cpu_exec_interrupt = lm32_cpu_exec_interrupt;
 cc->dump_state = lm32_cpu_dump_state;
 cc->set_pc = lm32_cpu_set_pc;
 cc->gdb_read_register = lm32_cpu_gdb_read_register;
diff --git a/target-lm32/helper.c b/target-lm32/helper.c
index ad724ae..7a41f29 100644
--- a/target-lm32/helper.c
+++ b/target-lm32/helper.c
@@ -202,6 +202,19 @@ void lm32_cpu_do_interrupt(CPUState *cs)
 }
 }
 
+bool lm32_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+{
+LM32CPU *cpu = LM32_CPU(cs);
+CPULM32State *env = &cpu->env;
+
+if ((interrupt_request & CPU_INTERRUPT_HARD) && (env->ie & IE_IE)) {
+cs->exception_index = EXCP_IRQ;
+lm32_cpu_do_interrupt(cs);
+return true;
+}
+return false;
+}
+
 LM32CPU *cpu_lm32_init(const char *cpu_model)
 {
 return LM32_CPU(cpu_generic_init(TYPE_LM32_CPU, cpu_model));
-- 
1.9.3




[Qemu-devel] [PATCH 06/23] qom: Add cpu_exec_interrupt hook

2014-09-13 Thread Richard Henderson
Continuing the removal of ifdefs from cpu_exec.

Cc: Andreas Färber 
Signed-off-by: Richard Henderson 
---
 cpu-exec.c| 14 +-
 include/qom/cpu.h |  2 ++
 qom/cpu.c |  6 ++
 3 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index d930e7a..fe313b4 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -676,8 +676,15 @@ int cpu_exec(CPUArchState *env)
 next_tb = 0;
 }
 #endif
-   /* Don't use the cached interrupt_request value,
-  do_interrupt may have updated the EXITTB flag. */
+/* The target hook has 3 exit conditions:
+   False when the interrupt isn't processed,
+   True when it is, and we should restart on a new TB,
+   and via longjmp via cpu_loop_exit.  */
+if (cc->cpu_exec_interrupt(cpu, interrupt_request)) {
+next_tb = 0;
+}
+/* Don't use the cached interrupt_request value,
+   do_interrupt may have updated the EXITTB flag. */
 if (cpu->interrupt_request & CPU_INTERRUPT_EXITTB) {
 cpu->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
 /* ensure that no TB jump will be modified as
@@ -783,10 +790,7 @@ int cpu_exec(CPUArchState *env)
  * local variables as longjmp is marked 'noreturn'. */
 cpu = current_cpu;
 env = cpu->env_ptr;
-#if !(defined(CONFIG_USER_ONLY) && \
-  (defined(TARGET_M68K) || defined(TARGET_PPC) || defined(TARGET_S390X)))
 cc = CPU_GET_CLASS(cpu);
-#endif
 #ifdef TARGET_I386
 x86_cpu = X86_CPU(cpu);
 #endif
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 0340cf4..f576b47 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -101,6 +101,7 @@ struct TranslationBlock;
  * @gdb_core_xml_file: File name for core registers GDB XML description.
  * @cpu_exec_enter: Callback for cpu_exec preparation.
  * @cpu_exec_exit: Callback for cpu_exec cleanup.
+ * @cpu_exec_interrupt: Callback for processing interrupts in cpu_exec.
  *
  * Represents a CPU family or model.
  */
@@ -154,6 +155,7 @@ typedef struct CPUClass {
 
 void (*cpu_exec_enter)(CPUState *cpu);
 void (*cpu_exec_exit)(CPUState *cpu);
+bool (*cpu_exec_interrupt)(CPUState *cpu, int interrupt_request);
 } CPUClass;
 
 #ifdef HOST_WORDS_BIGENDIAN
diff --git a/qom/cpu.c b/qom/cpu.c
index 6a9d02e..0ec3337 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -206,6 +206,11 @@ static void cpu_common_noop(CPUState *cpu)
 {
 }
 
+static bool cpu_common_exec_interrupt(CPUState *cpu, int int_req)
+{
+return false;
+}
+
 void cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
 int flags)
 {
@@ -347,6 +352,7 @@ static void cpu_class_init(ObjectClass *klass, void *data)
 k->debug_excp_handler = cpu_common_noop;
 k->cpu_exec_enter = cpu_common_noop;
 k->cpu_exec_exit = cpu_common_noop;
+k->cpu_exec_interrupt = cpu_common_exec_interrupt;
 dc->realize = cpu_common_realizefn;
 /*
  * Reason: CPUs still need special care by board code: wiring up
-- 
1.9.3




[Qemu-devel] [PATCH 23/23] cpu-exec: Do CPU_INTERRUPT_HALT unconditionally

2014-09-13 Thread Richard Henderson
The signal is currently checked by 10 targets, but only actually
raised by Sparc and ARM.  For the sake of one test-and-branch,
we can handle this generic bit generically.

Signed-off-by: Richard Henderson 
---
 cpu-exec.c | 5 -
 1 file changed, 5 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index b977481..3913de0 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -404,17 +404,12 @@ int cpu_exec(CPUArchState *env)
 cpu->exception_index = EXCP_DEBUG;
 cpu_loop_exit(cpu);
 }
-#if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \
-defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || \
-defined(TARGET_MICROBLAZE) || defined(TARGET_LM32) ||   \
-defined(TARGET_UNICORE32) || defined(TARGET_TRICORE)
 if (interrupt_request & CPU_INTERRUPT_HALT) {
 cpu->interrupt_request &= ~CPU_INTERRUPT_HALT;
 cpu->halted = 1;
 cpu->exception_index = EXCP_HLT;
 cpu_loop_exit(cpu);
 }
-#endif
 #if defined(TARGET_I386)
 if (interrupt_request & CPU_INTERRUPT_INIT) {
 cpu_svm_check_intercept_param(env, SVM_EXIT_INIT, 0);
-- 
1.9.3




[Qemu-devel] [PATCH 11/23] target-alpha: Use cpu_exec_interrupt qom hook

2014-09-13 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 cpu-exec.c | 32 
 target-alpha/cpu-qom.h |  1 +
 target-alpha/cpu.c |  1 +
 target-alpha/helper.c  | 44 
 4 files changed, 46 insertions(+), 32 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 7efcf27..2f73be4 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -597,38 +597,6 @@ int cpu_exec(CPUArchState *env)
 cc->do_interrupt(cpu);
 next_tb = 0;
 }
-#elif defined(TARGET_ALPHA)
-{
-int idx = -1;
-/* ??? This hard-codes the OSF/1 interrupt levels.  */
-switch (env->pal_mode ? 7 : env->ps & PS_INT_MASK) {
-case 0 ... 3:
-if (interrupt_request & CPU_INTERRUPT_HARD) {
-idx = EXCP_DEV_INTERRUPT;
-}
-/* FALLTHRU */
-case 4:
-if (interrupt_request & CPU_INTERRUPT_TIMER) {
-idx = EXCP_CLK_INTERRUPT;
-}
-/* FALLTHRU */
-case 5:
-if (interrupt_request & CPU_INTERRUPT_SMP) {
-idx = EXCP_SMP_INTERRUPT;
-}
-/* FALLTHRU */
-case 6:
-if (interrupt_request & CPU_INTERRUPT_MCHK) {
-idx = EXCP_MCHK;
-}
-}
-if (idx >= 0) {
-cpu->exception_index = idx;
-env->error_code = 0;
-cc->do_interrupt(cpu);
-next_tb = 0;
-}
-}
 #endif
 /* The target hook has 3 exit conditions:
False when the interrupt isn't processed,
diff --git a/target-alpha/cpu-qom.h b/target-alpha/cpu-qom.h
index 0caa362..b01c6c8 100644
--- a/target-alpha/cpu-qom.h
+++ b/target-alpha/cpu-qom.h
@@ -79,6 +79,7 @@ extern const struct VMStateDescription vmstate_alpha_cpu;
 #endif
 
 void alpha_cpu_do_interrupt(CPUState *cpu);
+bool alpha_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void alpha_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
   int flags);
 hwaddr alpha_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c
index 2491f0a..a98b7d8 100644
--- a/target-alpha/cpu.c
+++ b/target-alpha/cpu.c
@@ -284,6 +284,7 @@ static void alpha_cpu_class_init(ObjectClass *oc, void 
*data)
 cc->class_by_name = alpha_cpu_class_by_name;
 cc->has_work = alpha_cpu_has_work;
 cc->do_interrupt = alpha_cpu_do_interrupt;
+cc->cpu_exec_interrupt = alpha_cpu_exec_interrupt;
 cc->dump_state = alpha_cpu_dump_state;
 cc->set_pc = alpha_cpu_set_pc;
 cc->gdb_read_register = alpha_cpu_gdb_read_register;
diff --git a/target-alpha/helper.c b/target-alpha/helper.c
index 7c053a3..a8aa782 100644
--- a/target-alpha/helper.c
+++ b/target-alpha/helper.c
@@ -470,6 +470,50 @@ void alpha_cpu_do_interrupt(CPUState *cs)
 #endif /* !USER_ONLY */
 }
 
+bool alpha_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+{
+AlphaCPU *cpu = ALPHA_CPU(cs);
+CPUAlphaState *env = &cpu->env;
+int idx = -1;
+
+/* We never take interrupts while in PALmode.  */
+if (env->pal_mode) {
+return false;
+}
+
+/* Fall through the switch, collecting the highest priority
+   interrupt that isn't masked by the processor status IPL.  */
+/* ??? This hard-codes the OSF/1 interrupt levels.  */
+switch (env->ps & PS_INT_MASK) {
+case 0 ... 3:
+if (interrupt_request & CPU_INTERRUPT_HARD) {
+idx = EXCP_DEV_INTERRUPT;
+}
+/* FALLTHRU */
+case 4:
+if (interrupt_request & CPU_INTERRUPT_TIMER) {
+idx = EXCP_CLK_INTERRUPT;
+}
+/* FALLTHRU */
+case 5:
+if (interrupt_request & CPU_INTERRUPT_SMP) {
+idx = EXCP_SMP_INTERRUPT;
+}
+/* FALLTHRU */
+case 6:
+if (interrupt_request & CPU_INTERRUPT_MCHK) {
+idx = EXCP_MCHK;
+}
+}
+if (idx >= 0) {
+cs->exception_index = idx;
+env->error_code = 0;
+alpha_cpu_do_interrupt(cs);
+return true;
+}
+return false;
+}
+
 void alpha_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
   int flags)
 {
-- 
1.9.3




[Qemu-devel] [PATCH 19/23] target-microblaze: Use cpu_exec_interrupt qom hook

2014-09-13 Thread Richard Henderson
Cc: Edgar E. Iglesias 
Signed-off-by: Richard Henderson 
---
 cpu-exec.c  |  9 -
 target-microblaze/cpu-qom.h |  1 +
 target-microblaze/cpu.c |  1 +
 target-microblaze/helper.c  | 16 
 4 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 60f7270..5c93a5f 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -505,15 +505,6 @@ int cpu_exec(CPUArchState *env)
 cc->do_interrupt(cpu);
 next_tb = 0;
 }
-#elif defined(TARGET_MICROBLAZE)
-if ((interrupt_request & CPU_INTERRUPT_HARD)
-&& (env->sregs[SR_MSR] & MSR_IE)
-&& !(env->sregs[SR_MSR] & (MSR_EIP | MSR_BIP))
-&& !(env->iflags & (D_FLAG | IMM_FLAG))) {
-cpu->exception_index = EXCP_IRQ;
-cc->do_interrupt(cpu);
-next_tb = 0;
-}
 #endif
 /* The target hook has 3 exit conditions:
False when the interrupt isn't processed,
diff --git a/target-microblaze/cpu-qom.h b/target-microblaze/cpu-qom.h
index 35a12b4..e3e0701 100644
--- a/target-microblaze/cpu-qom.h
+++ b/target-microblaze/cpu-qom.h
@@ -72,6 +72,7 @@ static inline MicroBlazeCPU *mb_env_get_cpu(CPUMBState *env)
 #define ENV_OFFSET offsetof(MicroBlazeCPU, env)
 
 void mb_cpu_do_interrupt(CPUState *cs);
+bool mb_cpu_exec_interrupt(CPUState *cs, int int_req);
 void mb_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
int flags);
 hwaddr mb_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c
index 0379f2b..67e3182 100644
--- a/target-microblaze/cpu.c
+++ b/target-microblaze/cpu.c
@@ -169,6 +169,7 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
 
 cc->has_work = mb_cpu_has_work;
 cc->do_interrupt = mb_cpu_do_interrupt;
+cc->cpu_exec_interrupt = mb_cpu_exec_interrupt;
 cc->dump_state = mb_cpu_dump_state;
 cc->set_pc = mb_cpu_set_pc;
 cc->gdb_read_register = mb_cpu_gdb_read_register;
diff --git a/target-microblaze/helper.c b/target-microblaze/helper.c
index 59c9ad5..59466c9 100644
--- a/target-microblaze/helper.c
+++ b/target-microblaze/helper.c
@@ -286,3 +286,19 @@ hwaddr mb_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
 return paddr;
 }
 #endif
+
+bool mb_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+{
+MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
+CPUMBState *env = &cpu->env;
+
+if ((interrupt_request & CPU_INTERRUPT_HARD)
+&& (env->sregs[SR_MSR] & MSR_IE)
+&& !(env->sregs[SR_MSR] & (MSR_EIP | MSR_BIP))
+&& !(env->iflags & (D_FLAG | IMM_FLAG))) {
+cs->exception_index = EXCP_IRQ;
+mb_cpu_do_interrupt(cs);
+return true;
+}
+return false;
+}
-- 
1.9.3




[Qemu-devel] [PATCH 05/23] target-ppc: Use cpu_exec_enter qom hook

2014-09-13 Thread Richard Henderson
Cc: qemu-...@nongnu.org
Signed-off-by: Richard Henderson 
---
 cpu-exec.c  | 3 ---
 target-ppc/translate_init.c | 9 +
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 9f84dda..d930e7a 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -352,9 +352,6 @@ int cpu_exec(CPUArchState *env)
 cpu->exit_request = 1;
 }
 
-#if defined(TARGET_PPC)
-env->reserve_addr = -1;
-#endif
 cc->cpu_exec_enter(cpu);
 cpu->exception_index = -1;
 
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 48177ed..e577e03 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -9456,6 +9456,14 @@ static bool ppc_cpu_has_work(CPUState *cs)
 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
 }
 
+static void ppc_cpu_exec_enter(CPUState *cs)
+{
+PowerPCCPU *cpu = POWERPC_CPU(cs);
+CPUPPCState *env = &cpu->env;
+
+env->reserve_addr = -1;
+}
+
 /* CPUClass::reset() */
 static void ppc_cpu_reset(CPUState *s)
 {
@@ -9638,6 +9646,7 @@ static void ppc_cpu_class_init(ObjectClass *oc, void 
*data)
 cc->write_elf64_qemunote = ppc64_cpu_write_elf64_qemunote;
 #endif
 #endif
+cc->cpu_exec_enter = ppc_cpu_exec_enter;
 
 cc->gdb_num_core_regs = 71;
 
-- 
1.9.3




[Qemu-devel] [PATCH 16/23] target-openrisc: Use cpu_exec_interrupt qom hook

2014-09-13 Thread Richard Henderson
Cc: Jia Liu 
Signed-off-by: Richard Henderson 
---
 cpu-exec.c  | 18 --
 target-openrisc/cpu.c   |  1 +
 target-openrisc/cpu.h   |  1 +
 target-openrisc/interrupt.c | 20 
 4 files changed, 22 insertions(+), 18 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 075abf9..81441e7 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -528,24 +528,6 @@ int cpu_exec(CPUArchState *env)
 cc->do_interrupt(cpu);
 next_tb = 0;
 }
-
-#elif defined(TARGET_OPENRISC)
-{
-int idx = -1;
-if ((interrupt_request & CPU_INTERRUPT_HARD)
-&& (env->sr & SR_IEE)) {
-idx = EXCP_INT;
-}
-if ((interrupt_request & CPU_INTERRUPT_TIMER)
-&& (env->sr & SR_TEE)) {
-idx = EXCP_TICK;
-}
-if (idx >= 0) {
-cpu->exception_index = idx;
-cc->do_interrupt(cpu);
-next_tb = 0;
-}
-}
 #endif
 /* The target hook has 3 exit conditions:
False when the interrupt isn't processed,
diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c
index 08e724c..39bedc1 100644
--- a/target-openrisc/cpu.c
+++ b/target-openrisc/cpu.c
@@ -165,6 +165,7 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void 
*data)
 cc->class_by_name = openrisc_cpu_class_by_name;
 cc->has_work = openrisc_cpu_has_work;
 cc->do_interrupt = openrisc_cpu_do_interrupt;
+cc->cpu_exec_interrupt = openrisc_cpu_exec_interrupt;
 cc->dump_state = openrisc_cpu_dump_state;
 cc->set_pc = openrisc_cpu_set_pc;
 cc->gdb_read_register = openrisc_cpu_gdb_read_register;
diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
index 4512f45..69b96c6 100644
--- a/target-openrisc/cpu.h
+++ b/target-openrisc/cpu.h
@@ -348,6 +348,7 @@ OpenRISCCPU *cpu_openrisc_init(const char *cpu_model);
 void cpu_openrisc_list(FILE *f, fprintf_function cpu_fprintf);
 int cpu_openrisc_exec(CPUOpenRISCState *s);
 void openrisc_cpu_do_interrupt(CPUState *cpu);
+bool openrisc_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void openrisc_cpu_dump_state(CPUState *cpu, FILE *f,
  fprintf_function cpu_fprintf, int flags);
 hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target-openrisc/interrupt.c b/target-openrisc/interrupt.c
index 3de567e..e480cfd 100644
--- a/target-openrisc/interrupt.c
+++ b/target-openrisc/interrupt.c
@@ -63,3 +63,23 @@ void openrisc_cpu_do_interrupt(CPUState *cs)
 
 cs->exception_index = -1;
 }
+
+bool openrisc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+{
+OpenRISCCPU *cpu = OPENRISC_CPU(cs);
+CPUOpenRISCState *env = &cpu->env;
+int idx = -1;
+
+if ((interrupt_request & CPU_INTERRUPT_HARD) && (env->sr & SR_IEE)) {
+idx = EXCP_INT;
+}
+if ((interrupt_request & CPU_INTERRUPT_TIMER) && (env->sr & SR_TEE)) {
+idx = EXCP_TICK;
+}
+if (idx >= 0) {
+cs->exception_index = idx;
+openrisc_cpu_do_interrupt(cs);
+return true;
+}
+return false;
+}
-- 
1.9.3




[Qemu-devel] [PATCH 07/23] target-xtensa: Use cpu_exec_interrupt qom hook

2014-09-13 Thread Richard Henderson
Cc: Max Filippov 
Signed-off-by: Richard Henderson 
---
 cpu-exec.c  |  6 --
 target-xtensa/cpu-qom.h |  1 +
 target-xtensa/cpu.c |  1 +
 target-xtensa/helper.c  | 10 ++
 4 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index fe313b4..304867d 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -669,12 +669,6 @@ int cpu_exec(CPUArchState *env)
 cc->do_interrupt(cpu);
 next_tb = 0;
 }
-#elif defined(TARGET_XTENSA)
-if (interrupt_request & CPU_INTERRUPT_HARD) {
-cpu->exception_index = EXC_IRQ;
-cc->do_interrupt(cpu);
-next_tb = 0;
-}
 #endif
 /* The target hook has 3 exit conditions:
False when the interrupt isn't processed,
diff --git a/target-xtensa/cpu-qom.h b/target-xtensa/cpu-qom.h
index f320486..9de5c6e 100644
--- a/target-xtensa/cpu-qom.h
+++ b/target-xtensa/cpu-qom.h
@@ -84,6 +84,7 @@ static inline XtensaCPU *xtensa_env_get_cpu(const 
CPUXtensaState *env)
 #define ENV_OFFSET offsetof(XtensaCPU, env)
 
 void xtensa_cpu_do_interrupt(CPUState *cpu);
+bool xtensa_cpu_exec_interrupt(CPUState *cpu, int interrupt_request);
 void xtensa_cpu_dump_state(CPUState *cpu, FILE *f,
fprintf_function cpu_fprintf, int flags);
 hwaddr xtensa_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c
index 936d526..51c41d5 100644
--- a/target-xtensa/cpu.c
+++ b/target-xtensa/cpu.c
@@ -142,6 +142,7 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void 
*data)
 cc->class_by_name = xtensa_cpu_class_by_name;
 cc->has_work = xtensa_cpu_has_work;
 cc->do_interrupt = xtensa_cpu_do_interrupt;
+cc->cpu_exec_interrupt = xtensa_cpu_exec_interrupt;
 cc->dump_state = xtensa_cpu_dump_state;
 cc->set_pc = xtensa_cpu_set_pc;
 cc->gdb_read_register = xtensa_cpu_gdb_read_register;
diff --git a/target-xtensa/helper.c b/target-xtensa/helper.c
index 6671e40..d84d259 100644
--- a/target-xtensa/helper.c
+++ b/target-xtensa/helper.c
@@ -256,6 +256,16 @@ void xtensa_cpu_do_interrupt(CPUState *cs)
 check_interrupts(env);
 }
 
+bool xtensa_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+{
+if (interrupt_request & CPU_INTERRUPT_HARD) {
+cs->exception_index = EXC_IRQ;
+xtensa_cpu_do_interrupt(cs);
+return true;
+}
+return false;
+}
+
 static void reset_tlb_mmu_all_ways(CPUXtensaState *env,
 const xtensa_tlb *tlb, xtensa_tlb_entry entry[][MAX_TLB_WAY_SIZE])
 {
-- 
1.9.3




[Qemu-devel] [PATCH 15/23] target-sparc: Use cpu_exec_interrupt qom hook

2014-09-13 Thread Richard Henderson
Cc: Blue Swirl 
Signed-off-by: Richard Henderson 
---
 cpu-exec.c | 16 
 target-sparc/cpu.c | 21 +
 2 files changed, 21 insertions(+), 16 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 0d5ce62..075abf9 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -546,22 +546,6 @@ int cpu_exec(CPUArchState *env)
 next_tb = 0;
 }
 }
-#elif defined(TARGET_SPARC)
-if (interrupt_request & CPU_INTERRUPT_HARD) {
-if (cpu_interrupts_enabled(env) &&
-env->interrupt_index > 0) {
-int pil = env->interrupt_index & 0xf;
-int type = env->interrupt_index & 0xf0;
-
-if (((type == TT_EXTINT) &&
-  cpu_pil_allowed(env, pil)) ||
-  type != TT_EXTINT) {
-cpu->exception_index = env->interrupt_index;
-cc->do_interrupt(cpu);
-next_tb = 0;
-}
-}
-}
 #endif
 /* The target hook has 3 exit conditions:
False when the interrupt isn't processed,
diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c
index 3a0ee50..aa7626c 100644
--- a/target-sparc/cpu.c
+++ b/target-sparc/cpu.c
@@ -70,6 +70,26 @@ static void sparc_cpu_reset(CPUState *s)
 env->cache_control = 0;
 }
 
+static bool sparc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+{
+if (interrupt_request & CPU_INTERRUPT_HARD) {
+SPARCCPU *cpu = SPARC_CPU(cs);
+CPUSPARCState *env = &cpu->env;
+
+if (cpu_interrupts_enabled(env) && env->interrupt_index > 0) {
+int pil = env->interrupt_index & 0xf;
+int type = env->interrupt_index & 0xf0;
+
+if (type != TT_EXTINT || cpu_pil_allowed(env, pil)) {
+cs->exception_index = env->interrupt_index;
+sparc_cpu_do_interrupt(cs);
+return true;
+}
+}
+}
+return false;
+}
+
 static int cpu_sparc_register(SPARCCPU *cpu, const char *cpu_model)
 {
 CPUClass *cc = CPU_GET_CLASS(cpu);
@@ -813,6 +833,7 @@ static void sparc_cpu_class_init(ObjectClass *oc, void 
*data)
 cc->parse_features = sparc_cpu_parse_features;
 cc->has_work = sparc_cpu_has_work;
 cc->do_interrupt = sparc_cpu_do_interrupt;
+cc->cpu_exec_interrupt = sparc_cpu_exec_interrupt;
 cc->dump_state = sparc_cpu_dump_state;
 #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
 cc->memory_rw_debug = sparc_cpu_memory_rw_debug;
-- 
1.9.3




[Qemu-devel] [PATCH 17/23] target-tricore: Remove the dummy interrupt boilerplate

2014-09-13 Thread Richard Henderson
It can go back in when it actually does something.

Cc: Bastian Koppelmann 
Signed-off-by: Richard Henderson 
---
 cpu-exec.c   | 5 -
 target-tricore/cpu-qom.h | 1 -
 target-tricore/cpu.c | 1 -
 target-tricore/cpu.h | 2 --
 target-tricore/helper.c  | 4 
 5 files changed, 13 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 81441e7..7e9f4cd 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -523,11 +523,6 @@ int cpu_exec(CPUArchState *env)
 cc->do_interrupt(cpu);
 next_tb = 0;
 }
-#elif defined(TARGET_TRICORE)
-if ((interrupt_request & CPU_INTERRUPT_HARD)) {
-cc->do_interrupt(cpu);
-next_tb = 0;
-}
 #endif
 /* The target hook has 3 exit conditions:
False when the interrupt isn't processed,
diff --git a/target-tricore/cpu-qom.h b/target-tricore/cpu-qom.h
index 470215a..66c9664 100644
--- a/target-tricore/cpu-qom.h
+++ b/target-tricore/cpu-qom.h
@@ -63,7 +63,6 @@ static inline TriCoreCPU *tricore_env_get_cpu(CPUTriCoreState 
*env)
 #define ENV_OFFSET offsetof(TriCoreCPU, env)
 
 hwaddr tricore_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
-void tricore_cpu_do_interrupt(CPUState *cpu);
 void tricore_cpu_dump_state(CPUState *cpu, FILE *f,
 fprintf_function cpu_fprintf, int flags);
 
diff --git a/target-tricore/cpu.c b/target-tricore/cpu.c
index db9f404..7bf041a 100644
--- a/target-tricore/cpu.c
+++ b/target-tricore/cpu.c
@@ -145,7 +145,6 @@ static void tricore_cpu_class_init(ObjectClass *c, void 
*data)
 cc->class_by_name = tricore_cpu_class_by_name;
 cc->has_work = tricore_cpu_has_work;
 
-cc->do_interrupt = tricore_cpu_do_interrupt;
 cc->dump_state = tricore_cpu_dump_state;
 cc->set_pc = tricore_cpu_set_pc;
 cc->synchronize_from_tb = tricore_cpu_synchronize_from_tb;
diff --git a/target-tricore/cpu.h b/target-tricore/cpu.h
index b036ff1..7555b70 100644
--- a/target-tricore/cpu.h
+++ b/target-tricore/cpu.h
@@ -400,6 +400,4 @@ static inline void cpu_pc_from_tb(CPUTriCoreState *env, 
TranslationBlock *tb)
 env->PC = tb->pc;
 }
 
-void do_interrupt(CPUTriCoreState *env);
-
 #endif /*__TRICORE_CPU_H__ */
diff --git a/target-tricore/helper.c b/target-tricore/helper.c
index e4af6f1..f52504c 100644
--- a/target-tricore/helper.c
+++ b/target-tricore/helper.c
@@ -82,10 +82,6 @@ int cpu_tricore_handle_mmu_fault(CPUState *cs, target_ulong 
address,
 return ret;
 }
 
-void tricore_cpu_do_interrupt(CPUState *cs)
-{
-}
-
 TriCoreCPU *cpu_tricore_init(const char *cpu_model)
 {
 return TRICORE_CPU(cpu_generic_init(TYPE_TRICORE_CPU, cpu_model));
-- 
1.9.3




[Qemu-devel] [PATCH 03/23] target-i386: Use cpu_exec_enter/exit qom hooks

2014-09-13 Thread Richard Henderson
Note that the code that was within the "exit" ifdef block
was identical to the cpu_compute_eflags inline, so make that
simplification at the same time.

Signed-off-by: Richard Henderson 
---
 cpu-exec.c| 14 ++
 target-i386/cpu-qom.h |  3 +++
 target-i386/cpu.c |  2 ++
 target-i386/helper.c  | 21 +
 4 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 808d34f..0c1f0d3 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -352,13 +352,7 @@ int cpu_exec(CPUArchState *env)
 cpu->exit_request = 1;
 }
 
-#if defined(TARGET_I386)
-/* put eflags in CPU temporary format */
-CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
-env->df = 1 - (2 * ((env->eflags >> 10) & 1));
-CC_OP = CC_OP_EFLAGS;
-env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
-#elif defined(TARGET_M68K)
+#if defined(TARGET_M68K)
 env->cc_op = CC_OP_FLAGS;
 env->cc_dest = env->sr & 0xf;
 env->cc_x = (env->sr >> 4) & 1;
@@ -811,11 +805,7 @@ int cpu_exec(CPUArchState *env)
 } /* for(;;) */
 
 
-#if defined(TARGET_I386)
-/* restore flags in standard format */
-env->eflags = env->eflags | cpu_cc_compute_all(env, CC_OP)
-| (env->df & DF_MASK);
-#elif defined(TARGET_M68K)
+#if defined(TARGET_M68K)
 cpu_m68k_flush_flags(env, env->cc_op);
 env->cc_op = CC_OP_FLAGS;
 env->sr = (env->sr & 0xffe0)
diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
index 7755466..b242cb0 100644
--- a/target-i386/cpu-qom.h
+++ b/target-i386/cpu-qom.h
@@ -151,4 +151,7 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cpu, vaddr 
addr);
 int x86_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
 int x86_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 
+void x86_cpu_exec_enter(CPUState *cpu);
+void x86_cpu_exec_exit(CPUState *cpu);
+
 #endif
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 90d0a05..223e43e 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2942,6 +2942,8 @@ static void x86_cpu_common_class_init(ObjectClass *oc, 
void *data)
 #ifndef CONFIG_USER_ONLY
 cc->debug_excp_handler = breakpoint_handler;
 #endif
+cc->cpu_exec_enter = x86_cpu_exec_enter;
+cc->cpu_exec_exit = x86_cpu_exec_exit;
 }
 
 static const TypeInfo x86_cpu_type_info = {
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 28fefe0..345bda1 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -1262,3 +1262,24 @@ void do_cpu_sipi(X86CPU *cpu)
 {
 }
 #endif
+
+/* Frob eflags into and out of the CPU temporary format.  */
+
+void x86_cpu_exec_enter(CPUState *cs)
+{
+X86CPU *cpu = X86_CPU(cs);
+CPUX86State *env = &cpu->env;
+
+CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
+env->df = 1 - (2 * ((env->eflags >> 10) & 1));
+CC_OP = CC_OP_EFLAGS;
+env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
+}
+
+void x86_cpu_exec_exit(CPUState *cs)
+{
+X86CPU *cpu = X86_CPU(cs);
+CPUX86State *env = &cpu->env;
+
+env->eflags = cpu_compute_eflags(env);
+}
-- 
1.9.3




[Qemu-devel] [PATCH 00/23] qom hooks to clean up cpu_exec

2014-09-13 Thread Richard Henderson
Prompted by trying to review Martin's ARM exception vs gdb
problems, let's clean up cpu_exec so that it's almost readable.

After the 23 patches, there's one (interesting) ifdef left.
That is, i386 redefining CPU_INTERRUPT_RESET as CPU_INTERRUPT_INIT
for its own purposes.  I'm not sure why all that couldn't be done
under whatever hooks cpu_reset allows.  Failing that, we might be
able to redefine C_I_I as a new CPU_INTERRUPT_TGT_INT_3 bit.

I've done some smoke tests on i386, arm, xtensa, because I had
images handy.  But I've not done anything but compile the rest.

Comments appreciated.


r~


Richard Henderson (23):
  qom: Add cpu_exec_enter and cpu_exec_exit hooks
  cpu-exec: Remove do-nothing ifdef chains
  target-i386: Use cpu_exec_enter/exit qom hooks
  target-m68k: Use cpu_exec_enter/exit qom hooks
  target-ppc: Use cpu_exec_enter qom hook
  qom: Add cpu_exec_interrupt hook
  target-xtensa: Use cpu_exec_interrupt qom hook
  target-s390x: Use cpu_exec_interrupt qom hook
  target-m68k: Use cpu_exec_interrupt qom hook
  target-cris: Use cpu_exec_interrupt qom hook
  target-alpha: Use cpu_exec_interrupt qom hook
  target-sh4: Use cpu_exec_interrupt qom hook
  target-unicore32: Use cpu_exec_interrupt qom hook
  target-arm: Use cpu_exec_interrupt qom hook
  target-sparc: Use cpu_exec_interrupt qom hook
  target-openrisc: Use cpu_exec_interrupt qom hook
  target-tricore: Remove the dummy interrupt boilerplate
  target-mips: Use cpu_exec_interrupt qom hook
  target-microblaze: Use cpu_exec_interrupt qom hook
  target-lm32: Use cpu_exec_interrupt qom hook
  target-ppc: Use cpu_exec_interrupt qom hook
  target-i386: Use cpu_exec_interrupt qom hook
  cpu-exec: Do CPU_INTERRUPT_HALT unconditionally

 cpu-exec.c  | 329 ++--
 include/qom/cpu.h   |   7 +
 qom/cpu.c   |  12 +-
 target-alpha/cpu-qom.h  |   1 +
 target-alpha/cpu.c  |   1 +
 target-alpha/helper.c   |  44 ++
 target-arm/cpu-qom.h|   1 +
 target-arm/cpu.c|  34 +
 target-arm/cpu64.c  |   1 +
 target-cris/cpu-qom.h   |   1 +
 target-cris/cpu.c   |   1 +
 target-cris/helper.c|  31 +
 target-i386/cpu-qom.h   |   4 +
 target-i386/cpu.c   |   3 +
 target-i386/helper.c|  21 +++
 target-i386/seg_helper.c|  69 ++
 target-lm32/cpu-qom.h   |   1 +
 target-lm32/cpu.c   |   1 +
 target-lm32/helper.c|  13 ++
 target-m68k/cpu-qom.h   |   4 +
 target-m68k/cpu.c   |   4 +
 target-m68k/cpu.h   |   1 -
 target-m68k/helper.c|  20 +++
 target-m68k/op_helper.c |  22 ++-
 target-microblaze/cpu-qom.h |   1 +
 target-microblaze/cpu.c |   1 +
 target-microblaze/helper.c  |  16 +++
 target-mips/cpu-qom.h   |   1 +
 target-mips/cpu.c   |   1 +
 target-mips/helper.c|  17 +++
 target-openrisc/cpu.c   |   1 +
 target-openrisc/cpu.h   |   1 +
 target-openrisc/interrupt.c |  20 +++
 target-ppc/cpu-qom.h|   1 +
 target-ppc/cpu.h|   1 -
 target-ppc/excp_helper.c|  19 ++-
 target-ppc/translate_init.c |  10 ++
 target-s390x/cpu-qom.h  |   1 +
 target-s390x/cpu.c  |   1 +
 target-s390x/helper.c   |  13 ++
 target-sh4/cpu-qom.h|   1 +
 target-sh4/cpu.c|   1 +
 target-sh4/helper.c |   9 ++
 target-sparc/cpu.c  |  21 +++
 target-tricore/cpu-qom.h|   1 -
 target-tricore/cpu.c|   1 -
 target-tricore/cpu.h|   2 -
 target-tricore/helper.c |   4 -
 target-unicore32/cpu-qom.h  |   1 +
 target-unicore32/cpu.c  |   1 +
 target-unicore32/helper.c   |  15 ++
 target-xtensa/cpu-qom.h |   1 +
 target-xtensa/cpu.c |   1 +
 target-xtensa/helper.c  |  10 ++
 54 files changed, 464 insertions(+), 336 deletions(-)

-- 
1.9.3




[Qemu-devel] [PATCH 09/23] target-m68k: Use cpu_exec_interrupt qom hook

2014-09-13 Thread Richard Henderson
Since do_interrupt_m68k_hardirq is no longer used outside
op_helper.c, make it static.

Signed-off-by: Richard Henderson 
---
 cpu-exec.c  | 13 -
 target-m68k/cpu-qom.h   |  1 +
 target-m68k/cpu.c   |  1 +
 target-m68k/cpu.h   |  1 -
 target-m68k/op_helper.c | 22 --
 5 files changed, 22 insertions(+), 16 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 08be521..8ff85ba 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -650,19 +650,6 @@ int cpu_exec(CPUArchState *env)
 next_tb = 0;
 }
 }
-#elif defined(TARGET_M68K)
-if (interrupt_request & CPU_INTERRUPT_HARD
-&& ((env->sr & SR_I) >> SR_I_SHIFT)
-< env->pending_level) {
-/* Real hardware gets the interrupt vector via an
-   IACK cycle at this point.  Current emulated
-   hardware doesn't rely on this, so we
-   provide/save the vector when the interrupt is
-   first signalled.  */
-cpu->exception_index = env->pending_vector;
-do_interrupt_m68k_hardirq(env);
-next_tb = 0;
-}
 #endif
 /* The target hook has 3 exit conditions:
False when the interrupt isn't processed,
diff --git a/target-m68k/cpu-qom.h b/target-m68k/cpu-qom.h
index 41b14ae..c28e55d 100644
--- a/target-m68k/cpu-qom.h
+++ b/target-m68k/cpu-qom.h
@@ -71,6 +71,7 @@ static inline M68kCPU *m68k_env_get_cpu(CPUM68KState *env)
 #define ENV_OFFSET offsetof(M68kCPU, env)
 
 void m68k_cpu_do_interrupt(CPUState *cpu);
+bool m68k_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void m68k_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
  int flags);
 hwaddr m68k_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c
index 5a58d51..4cfb725 100644
--- a/target-m68k/cpu.c
+++ b/target-m68k/cpu.c
@@ -196,6 +196,7 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
 cc->class_by_name = m68k_cpu_class_by_name;
 cc->has_work = m68k_cpu_has_work;
 cc->do_interrupt = m68k_cpu_do_interrupt;
+cc->cpu_exec_interrupt = m68k_cpu_exec_interrupt;
 cc->dump_state = m68k_cpu_dump_state;
 cc->set_pc = m68k_cpu_set_pc;
 cc->gdb_read_register = m68k_cpu_gdb_read_register;
diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h
index 6e4001d..f67bbcc 100644
--- a/target-m68k/cpu.h
+++ b/target-m68k/cpu.h
@@ -120,7 +120,6 @@ void m68k_tcg_init(void);
 void m68k_cpu_init_gdb(M68kCPU *cpu);
 M68kCPU *cpu_m68k_init(const char *cpu_model);
 int cpu_m68k_exec(CPUM68KState *s);
-void do_interrupt_m68k_hardirq(CPUM68KState *env1);
 /* you can call this signal handler from your SIGBUS and SIGSEGV
signal handlers to inform the virtual CPU of exceptions. non zero
is returned if the signal was handled by the virtual CPU.  */
diff --git a/target-m68k/op_helper.c b/target-m68k/op_helper.c
index 9dd3e74..06661f5 100644
--- a/target-m68k/op_helper.c
+++ b/target-m68k/op_helper.c
@@ -27,7 +27,7 @@ void m68k_cpu_do_interrupt(CPUState *cs)
 cs->exception_index = -1;
 }
 
-void do_interrupt_m68k_hardirq(CPUM68KState *env)
+static inline void do_interrupt_m68k_hardirq(CPUM68KState *env)
 {
 }
 
@@ -141,12 +141,30 @@ void m68k_cpu_do_interrupt(CPUState *cs)
 do_interrupt_all(env, 0);
 }
 
-void do_interrupt_m68k_hardirq(CPUM68KState *env)
+static inline void do_interrupt_m68k_hardirq(CPUM68KState *env)
 {
 do_interrupt_all(env, 1);
 }
 #endif
 
+bool m68k_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+{
+M68kCPU *cpu = M68K_CPU(cs);
+CPUM68KState *env = &cpu->env;
+
+if (interrupt_request & CPU_INTERRUPT_HARD
+&& ((env->sr & SR_I) >> SR_I_SHIFT) < env->pending_level) {
+/* Real hardware gets the interrupt vector via an IACK cycle
+   at this point.  Current emulated hardware doesn't rely on
+   this, so we provide/save the vector when the interrupt is
+   first signalled.  */
+cs->exception_index = env->pending_vector;
+do_interrupt_m68k_hardirq(env);
+return true;
+}
+return false;
+}
+
 static void raise_exception(CPUM68KState *env, int tt)
 {
 CPUState *cs = CPU(m68k_env_get_cpu(env));
-- 
1.9.3




[Qemu-devel] [PATCH 14/23] target-arm: Use cpu_exec_interrupt qom hook

2014-09-13 Thread Richard Henderson
Cc: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 cpu-exec.c   | 23 ---
 target-arm/cpu-qom.h |  1 +
 target-arm/cpu.c | 34 ++
 target-arm/cpu64.c   |  1 +
 4 files changed, 36 insertions(+), 23 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index b7b012b..0d5ce62 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -562,29 +562,6 @@ int cpu_exec(CPUArchState *env)
 }
 }
 }
-#elif defined(TARGET_ARM)
-if (interrupt_request & CPU_INTERRUPT_FIQ
-&& !(env->daif & PSTATE_F)) {
-cpu->exception_index = EXCP_FIQ;
-cc->do_interrupt(cpu);
-next_tb = 0;
-}
-/* ARMv7-M interrupt return works by loading a magic value
-   into the PC.  On real hardware the load causes the
-   return to occur.  The qemu implementation performs the
-   jump normally, then does the exception return when the
-   CPU tries to execute code at the magic address.
-   This will cause the magic PC value to be pushed to
-   the stack if an interrupt occurred at the wrong time.
-   We avoid this by disabling interrupts when
-   pc contains a magic address.  */
-if (interrupt_request & CPU_INTERRUPT_HARD
-&& !(env->daif & PSTATE_I)
-&& (!IS_M(env) || env->regs[15] < 0xfff0)) {
-cpu->exception_index = EXCP_IRQ;
-cc->do_interrupt(cpu);
-next_tb = 0;
-}
 #endif
 /* The target hook has 3 exit conditions:
False when the interrupt isn't processed,
diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
index 07f3c9e..96a3da9 100644
--- a/target-arm/cpu-qom.h
+++ b/target-arm/cpu-qom.h
@@ -192,6 +192,7 @@ void init_cpreg_list(ARMCPU *cpu);
 
 void arm_cpu_do_interrupt(CPUState *cpu);
 void arm_v7m_cpu_do_interrupt(CPUState *cpu);
+bool arm_cpu_exec_interrupt(CPUState *cpu, int int_req);
 
 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
 int flags);
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 7ea12bd..407f977 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -188,6 +188,39 @@ static void arm_cpu_reset(CPUState *s)
 hw_watchpoint_update_all(cpu);
 }
 
+bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+{
+CPUClass *cc = CPU_GET_CLASS(cs);
+ARMCPU *cpu = ARM_CPU(cs);
+CPUARMState *env = &cpu->env;
+bool ret = false;
+
+if (interrupt_request & CPU_INTERRUPT_FIQ
+&& !(env->daif & PSTATE_F)) {
+cs->exception_index = EXCP_FIQ;
+cc->do_interrupt(cs);
+ret = true;
+}
+/* ARMv7-M interrupt return works by loading a magic value
+   into the PC.  On real hardware the load causes the
+   return to occur.  The qemu implementation performs the
+   jump normally, then does the exception return when the
+   CPU tries to execute code at the magic address.
+   This will cause the magic PC value to be pushed to
+   the stack if an interrupt occurred at the wrong time.
+   We avoid this by disabling interrupts when
+   pc contains a magic address.  */
+if (interrupt_request & CPU_INTERRUPT_HARD
+&& !(env->daif & PSTATE_I)
+&& (!IS_M(env) || env->regs[15] < 0xfff0)) {
+cs->exception_index = EXCP_IRQ;
+cc->do_interrupt(cs);
+ret = true;
+}
+
+return ret;
+}
+
 #ifndef CONFIG_USER_ONLY
 static void arm_cpu_set_irq(void *opaque, int irq, int level)
 {
@@ -1053,6 +1086,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void 
*data)
 cc->class_by_name = arm_cpu_class_by_name;
 cc->has_work = arm_cpu_has_work;
 cc->do_interrupt = arm_cpu_do_interrupt;
+cc->cpu_exec_interrupt = arm_cpu_exec_interrupt;
 cc->dump_state = arm_cpu_dump_state;
 cc->set_pc = arm_cpu_set_pc;
 cc->gdb_read_register = arm_cpu_gdb_read_register;
diff --git a/target-arm/cpu64.c b/target-arm/cpu64.c
index aa42803..c30f47e 100644
--- a/target-arm/cpu64.c
+++ b/target-arm/cpu64.c
@@ -197,6 +197,7 @@ static void aarch64_cpu_class_init(ObjectClass *oc, void 
*data)
 CPUClass *cc = CPU_CLASS(oc);
 
 cc->do_interrupt = aarch64_cpu_do_interrupt;
+cc->cpu_exec_interrupt = arm_cpu_exec_interrupt;
 cc->set_pc = aarch64_cpu_set_pc;
 cc->gdb_read_register = aarch64_cpu_gdb_read_register;
 cc->gdb_write_register = aarch64_cpu_gdb_write_register;
-- 
1.9.3




[Qemu-devel] [PATCH 00/23] qom hooks to clean up cpu_exec

2014-09-13 Thread Richard Henderson
Prompted by trying to review Martin's ARM exception vs gdb
problems, let's clean up cpu_exec so that it's almost readable.

After the 23 patches, there's one (interesting) ifdef left.
That is, i386 redefining CPU_INTERRUPT_RESET as CPU_INTERRUPT_INIT
for its own purposes.  I'm not sure why all that couldn't be done
under whatever hooks cpu_reset allows.  Failing that, we might be
able to redefine C_I_I as a new CPU_INTERRUPT_TGT_INT_3 bit.

I've done some smoke tests on i386, arm, xtensa, because I had
images handy.  But I've not done anything but compile the rest.

Comments appreciated.


r~


Richard Henderson (23):
  qom: Add cpu_exec_enter and cpu_exec_exit hooks
  cpu-exec: Remove do-nothing ifdef chains
  target-i386: Use cpu_exec_enter/exit qom hooks
  target-m68k: Use cpu_exec_enter/exit qom hooks
  target-ppc: Use cpu_exec_enter qom hook
  qom: Add cpu_exec_interrupt hook
  target-xtensa: Use cpu_exec_interrupt qom hook
  target-s390x: Use cpu_exec_interrupt qom hook
  target-m68k: Use cpu_exec_interrupt qom hook
  target-cris: Use cpu_exec_interrupt qom hook
  target-alpha: Use cpu_exec_interrupt qom hook
  target-sh4: Use cpu_exec_interrupt qom hook
  target-unicore32: Use cpu_exec_interrupt qom hook
  target-arm: Use cpu_exec_interrupt qom hook
  target-sparc: Use cpu_exec_interrupt qom hook
  target-openrisc: Use cpu_exec_interrupt qom hook
  target-tricore: Remove the dummy interrupt boilerplate
  target-mips: Use cpu_exec_interrupt qom hook
  target-microblaze: Use cpu_exec_interrupt qom hook
  target-lm32: Use cpu_exec_interrupt qom hook
  target-ppc: Use cpu_exec_interrupt qom hook
  target-i386: Use cpu_exec_interrupt qom hook
  cpu-exec: Do CPU_INTERRUPT_HALT unconditionally

 cpu-exec.c  | 329 ++--
 include/qom/cpu.h   |   7 +
 qom/cpu.c   |  12 +-
 target-alpha/cpu-qom.h  |   1 +
 target-alpha/cpu.c  |   1 +
 target-alpha/helper.c   |  44 ++
 target-arm/cpu-qom.h|   1 +
 target-arm/cpu.c|  34 +
 target-arm/cpu64.c  |   1 +
 target-cris/cpu-qom.h   |   1 +
 target-cris/cpu.c   |   1 +
 target-cris/helper.c|  31 +
 target-i386/cpu-qom.h   |   4 +
 target-i386/cpu.c   |   3 +
 target-i386/helper.c|  21 +++
 target-i386/seg_helper.c|  69 ++
 target-lm32/cpu-qom.h   |   1 +
 target-lm32/cpu.c   |   1 +
 target-lm32/helper.c|  13 ++
 target-m68k/cpu-qom.h   |   4 +
 target-m68k/cpu.c   |   4 +
 target-m68k/cpu.h   |   1 -
 target-m68k/helper.c|  20 +++
 target-m68k/op_helper.c |  22 ++-
 target-microblaze/cpu-qom.h |   1 +
 target-microblaze/cpu.c |   1 +
 target-microblaze/helper.c  |  16 +++
 target-mips/cpu-qom.h   |   1 +
 target-mips/cpu.c   |   1 +
 target-mips/helper.c|  17 +++
 target-openrisc/cpu.c   |   1 +
 target-openrisc/cpu.h   |   1 +
 target-openrisc/interrupt.c |  20 +++
 target-ppc/cpu-qom.h|   1 +
 target-ppc/cpu.h|   1 -
 target-ppc/excp_helper.c|  19 ++-
 target-ppc/translate_init.c |  10 ++
 target-s390x/cpu-qom.h  |   1 +
 target-s390x/cpu.c  |   1 +
 target-s390x/helper.c   |  13 ++
 target-sh4/cpu-qom.h|   1 +
 target-sh4/cpu.c|   1 +
 target-sh4/helper.c |   9 ++
 target-sparc/cpu.c  |  21 +++
 target-tricore/cpu-qom.h|   1 -
 target-tricore/cpu.c|   1 -
 target-tricore/cpu.h|   2 -
 target-tricore/helper.c |   4 -
 target-unicore32/cpu-qom.h  |   1 +
 target-unicore32/cpu.c  |   1 +
 target-unicore32/helper.c   |  15 ++
 target-xtensa/cpu-qom.h |   1 +
 target-xtensa/cpu.c |   1 +
 target-xtensa/helper.c  |  10 ++
 54 files changed, 464 insertions(+), 336 deletions(-)

-- 
1.9.3




[Qemu-devel] [PATCH 02/23] cpu-exec: Remove do-nothing ifdef chains

2014-09-13 Thread Richard Henderson
Around the cpu_exec_enter/exit hooks contain many empty
ifdef blocks.  Delete all of these to highlight those
targets for which we actually need to do work.

Signed-off-by: Richard Henderson 
---
 cpu-exec.c | 32 
 1 file changed, 32 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index d5b86d0..808d34f 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -358,27 +358,12 @@ int cpu_exec(CPUArchState *env)
 env->df = 1 - (2 * ((env->eflags >> 10) & 1));
 CC_OP = CC_OP_EFLAGS;
 env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
-#elif defined(TARGET_SPARC)
 #elif defined(TARGET_M68K)
 env->cc_op = CC_OP_FLAGS;
 env->cc_dest = env->sr & 0xf;
 env->cc_x = (env->sr >> 4) & 1;
-#elif defined(TARGET_ALPHA)
-#elif defined(TARGET_ARM)
-#elif defined(TARGET_UNICORE32)
 #elif defined(TARGET_PPC)
 env->reserve_addr = -1;
-#elif defined(TARGET_LM32)
-#elif defined(TARGET_MICROBLAZE)
-#elif defined(TARGET_MIPS)
-#elif defined(TARGET_MOXIE)
-#elif defined(TARGET_OPENRISC)
-#elif defined(TARGET_SH4)
-#elif defined(TARGET_CRIS)
-#elif defined(TARGET_S390X)
-#elif defined(TARGET_XTENSA)
-#elif defined(TARGET_TRICORE)
-/* X */
 #endif
 cc->cpu_exec_enter(cpu);
 cpu->exception_index = -1;
@@ -830,28 +815,11 @@ int cpu_exec(CPUArchState *env)
 /* restore flags in standard format */
 env->eflags = env->eflags | cpu_cc_compute_all(env, CC_OP)
 | (env->df & DF_MASK);
-#elif defined(TARGET_ARM)
-/* XXX: Save/restore host fpu exception state?.  */
-#elif defined(TARGET_UNICORE32)
-#elif defined(TARGET_SPARC)
-#elif defined(TARGET_PPC)
-#elif defined(TARGET_LM32)
 #elif defined(TARGET_M68K)
 cpu_m68k_flush_flags(env, env->cc_op);
 env->cc_op = CC_OP_FLAGS;
 env->sr = (env->sr & 0xffe0)
   | env->cc_dest | (env->cc_x << 4);
-#elif defined(TARGET_MICROBLAZE)
-#elif defined(TARGET_MIPS)
-#elif defined(TARGET_TRICORE)
-#elif defined(TARGET_MOXIE)
-#elif defined(TARGET_OPENRISC)
-#elif defined(TARGET_SH4)
-#elif defined(TARGET_ALPHA)
-#elif defined(TARGET_CRIS)
-#elif defined(TARGET_S390X)
-#elif defined(TARGET_XTENSA)
-/* X */
 #endif
 cc->cpu_exec_exit(cpu);
 
-- 
1.9.3




[Qemu-devel] [PATCH 01/23] qom: Add cpu_exec_enter and cpu_exec_exit hooks

2014-09-13 Thread Richard Henderson
In preparation for removing a bunch of ifdefs from cpu_exec.

Cc: Andreas Färber 
Signed-off-by: Richard Henderson 
---
 cpu-exec.c| 9 ++---
 include/qom/cpu.h | 5 +
 qom/cpu.c | 6 --
 3 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index bd93165..d5b86d0 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -317,10 +317,7 @@ volatile sig_atomic_t exit_request;
 int cpu_exec(CPUArchState *env)
 {
 CPUState *cpu = ENV_GET_CPU(env);
-#if !(defined(CONFIG_USER_ONLY) && \
-  (defined(TARGET_M68K) || defined(TARGET_PPC) || defined(TARGET_S390X)))
 CPUClass *cc = CPU_GET_CLASS(cpu);
-#endif
 #ifdef TARGET_I386
 X86CPU *x86_cpu = X86_CPU(cpu);
 #endif
@@ -382,9 +379,8 @@ int cpu_exec(CPUArchState *env)
 #elif defined(TARGET_XTENSA)
 #elif defined(TARGET_TRICORE)
 /* X */
-#else
-#error unsupported target CPU
 #endif
+cc->cpu_exec_enter(cpu);
 cpu->exception_index = -1;
 
 /* Calculate difference between guest clock and host clock.
@@ -856,9 +852,8 @@ int cpu_exec(CPUArchState *env)
 #elif defined(TARGET_S390X)
 #elif defined(TARGET_XTENSA)
 /* X */
-#else
-#error unsupported target CPU
 #endif
+cc->cpu_exec_exit(cpu);
 
 /* fail safe : never use current_cpu outside cpu_exec() */
 current_cpu = NULL;
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 370b3eb..0340cf4 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -99,6 +99,8 @@ struct TranslationBlock;
  * @vmsd: State description for migration.
  * @gdb_num_core_regs: Number of core registers accessible to GDB.
  * @gdb_core_xml_file: File name for core registers GDB XML description.
+ * @cpu_exec_enter: Callback for cpu_exec preparation.
+ * @cpu_exec_exit: Callback for cpu_exec cleanup.
  *
  * Represents a CPU family or model.
  */
@@ -149,6 +151,9 @@ typedef struct CPUClass {
 const struct VMStateDescription *vmsd;
 int gdb_num_core_regs;
 const char *gdb_core_xml_file;
+
+void (*cpu_exec_enter)(CPUState *cpu);
+void (*cpu_exec_exit)(CPUState *cpu);
 } CPUClass;
 
 #ifdef HOST_WORDS_BIGENDIAN
diff --git a/qom/cpu.c b/qom/cpu.c
index ba8b402..6a9d02e 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -202,7 +202,7 @@ static bool cpu_common_virtio_is_big_endian(CPUState *cpu)
 return target_words_bigendian();
 }
 
-static void cpu_common_debug_excp_handler(CPUState *cpu)
+static void cpu_common_noop(CPUState *cpu)
 {
 }
 
@@ -344,7 +344,9 @@ static void cpu_class_init(ObjectClass *klass, void *data)
 k->gdb_read_register = cpu_common_gdb_read_register;
 k->gdb_write_register = cpu_common_gdb_write_register;
 k->virtio_is_big_endian = cpu_common_virtio_is_big_endian;
-k->debug_excp_handler = cpu_common_debug_excp_handler;
+k->debug_excp_handler = cpu_common_noop;
+k->cpu_exec_enter = cpu_common_noop;
+k->cpu_exec_exit = cpu_common_noop;
 dc->realize = cpu_common_realizefn;
 /*
  * Reason: CPUs still need special care by board code: wiring up
-- 
1.9.3




[Qemu-devel] [PATCH 08/23] target-s390x: Use cpu_exec_interrupt qom hook

2014-09-13 Thread Richard Henderson
Cc: Alexander Graf 
Signed-off-by: Richard Henderson 
---
 cpu-exec.c |  6 --
 target-s390x/cpu-qom.h |  1 +
 target-s390x/cpu.c |  1 +
 target-s390x/helper.c  | 13 +
 4 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 304867d..08be521 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -663,12 +663,6 @@ int cpu_exec(CPUArchState *env)
 do_interrupt_m68k_hardirq(env);
 next_tb = 0;
 }
-#elif defined(TARGET_S390X) && !defined(CONFIG_USER_ONLY)
-if ((interrupt_request & CPU_INTERRUPT_HARD) &&
-(env->psw.mask & PSW_MASK_EXT)) {
-cc->do_interrupt(cpu);
-next_tb = 0;
-}
 #endif
 /* The target hook has 3 exit conditions:
False when the interrupt isn't processed,
diff --git a/target-s390x/cpu-qom.h b/target-s390x/cpu-qom.h
index 80dd741..4f7d4cb 100644
--- a/target-s390x/cpu-qom.h
+++ b/target-s390x/cpu-qom.h
@@ -78,6 +78,7 @@ static inline S390CPU *s390_env_get_cpu(CPUS390XState *env)
 #define ENV_OFFSET offsetof(S390CPU, env)
 
 void s390_cpu_do_interrupt(CPUState *cpu);
+bool s390_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void s390_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
  int flags);
 int s390_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index 97a9216..2cfeb82 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -262,6 +262,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
 cc->get_phys_page_debug = s390_cpu_get_phys_page_debug;
 cc->write_elf64_note = s390_cpu_write_elf64_note;
 cc->write_elf64_qemunote = s390_cpu_write_elf64_qemunote;
+cc->cpu_exec_interrupt = s390_cpu_exec_interrupt;
 #endif
 dc->vmsd = &vmstate_s390_cpu;
 cc->gdb_num_core_regs = S390_NUM_CORE_REGS;
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index 67ab106..e21afe6 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -876,4 +876,17 @@ void s390_cpu_do_interrupt(CPUState *cs)
 }
 }
 
+bool s390_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+{
+if (interrupt_request & CPU_INTERRUPT_HARD) {
+S390CPU *cpu = S390_CPU(cs);
+CPUS390XState *env = &cpu->env;
+
+if (env->psw.mask & PSW_MASK_EXT) {
+s390_cpu_do_interrupt(cs);
+return true;
+}
+}
+return false;
+}
 #endif /* CONFIG_USER_ONLY */
-- 
1.9.3




[Qemu-devel] [PATCH 04/23] target-m68k: Use cpu_exec_enter/exit qom hooks

2014-09-13 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 cpu-exec.c| 13 +
 target-m68k/cpu-qom.h |  3 +++
 target-m68k/cpu.c |  3 +++
 target-m68k/helper.c  | 20 
 4 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 0c1f0d3..9f84dda 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -352,11 +352,7 @@ int cpu_exec(CPUArchState *env)
 cpu->exit_request = 1;
 }
 
-#if defined(TARGET_M68K)
-env->cc_op = CC_OP_FLAGS;
-env->cc_dest = env->sr & 0xf;
-env->cc_x = (env->sr >> 4) & 1;
-#elif defined(TARGET_PPC)
+#if defined(TARGET_PPC)
 env->reserve_addr = -1;
 #endif
 cc->cpu_exec_enter(cpu);
@@ -804,13 +800,6 @@ int cpu_exec(CPUArchState *env)
 }
 } /* for(;;) */
 
-
-#if defined(TARGET_M68K)
-cpu_m68k_flush_flags(env, env->cc_op);
-env->cc_op = CC_OP_FLAGS;
-env->sr = (env->sr & 0xffe0)
-  | env->cc_dest | (env->cc_x << 4);
-#endif
 cc->cpu_exec_exit(cpu);
 
 /* fail safe : never use current_cpu outside cpu_exec() */
diff --git a/target-m68k/cpu-qom.h b/target-m68k/cpu-qom.h
index 7f388ed..41b14ae 100644
--- a/target-m68k/cpu-qom.h
+++ b/target-m68k/cpu-qom.h
@@ -77,4 +77,7 @@ hwaddr m68k_cpu_get_phys_page_debug(CPUState *cpu, vaddr 
addr);
 int m68k_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
 int m68k_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 
+void m68k_cpu_exec_enter(CPUState *cs);
+void m68k_cpu_exec_exit(CPUState *cs);
+
 #endif
diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c
index c9cff19..5a58d51 100644
--- a/target-m68k/cpu.c
+++ b/target-m68k/cpu.c
@@ -205,6 +205,9 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
 #else
 cc->get_phys_page_debug = m68k_cpu_get_phys_page_debug;
 #endif
+cc->cpu_exec_enter = m68k_cpu_exec_enter;
+cc->cpu_exec_exit = m68k_cpu_exec_exit;
+
 dc->vmsd = &vmstate_m68k_cpu;
 cc->gdb_num_core_regs = 18;
 cc->gdb_core_xml_file = "cf-core.xml";
diff --git a/target-m68k/helper.c b/target-m68k/helper.c
index 8be9745..77225a2 100644
--- a/target-m68k/helper.c
+++ b/target-m68k/helper.c
@@ -864,3 +864,23 @@ void HELPER(set_mac_extu)(CPUM68KState *env, uint32_t val, 
uint32_t acc)
 res |= (uint64_t)(val & 0x) << 16;
 env->macc[acc + 1] = res;
 }
+
+void m68k_cpu_exec_enter(CPUState *cs)
+{
+M68kCPU *cpu = M68K_CPU(cs);
+CPUM68KState *env = &cpu->env;
+
+env->cc_op = CC_OP_FLAGS;
+env->cc_dest = env->sr & 0xf;
+env->cc_x = (env->sr >> 4) & 1;
+}
+
+void m68k_cpu_exec_exit(CPUState *cs)
+{
+M68kCPU *cpu = M68K_CPU(cs);
+CPUM68KState *env = &cpu->env;
+
+cpu_m68k_flush_flags(env, env->cc_op);
+env->cc_op = CC_OP_FLAGS;
+env->sr = (env->sr & 0xffe0) | env->cc_dest | (env->cc_x << 4);
+}
-- 
1.9.3




Re: [Qemu-devel] [synnefo-devel] Re: [PATCH resend 1/2] monitor: Reset HMP mon->rs on CHR_EVENT_CLOSED

2014-09-13 Thread Stratos Psomadakis
On 12/09/2014 08:19 μμ, Luiz Capitulino wrote:
> On Fri, 12 Sep 2014 20:01:04 +0300
> Stratos Psomadakis  wrote:
>
>> On 12/09/2014 06:21 μμ, Luiz Capitulino wrote:
>>> On Fri, 12 Sep 2014 17:07:32 +0300
>>> Stratos Psomadakis  wrote:
>>>
 Commit cdaa86a54 ("Add G_IO_HUP handler for socket chardev") exposed a bug 
 in
 the way the HMP monitor handles its command buffer. When a client closes 
 the
 connection to the monitor, tcp_chr_read() will detect the G_IO_HUP 
 condition
 and call tcp_chr_disconnect() to close the server-side connection too. Due 
 to
 the fact that monitor reads 1 byte at a time (for each tcp_chr_read()), the
 monitor readline state / buffers might contain junk (i.e. a half-finished
 command).  Thus, without calling readline_restart() on mon->rs upon
 CHR_EVENT_CLOSED, future HMP commands will fail.
>>> What's your reproducer?
>> We have a script that opens a connection to the HMP socket and starts
>> sending 'info version' commands to the monitor in a loop. If we kill the
>> script (in the middle of the loop) and re-run it, we get "unknown
>> command" errors from the HMP ("unknown command: 'infinfo'" for example).
>>
>>> Are you using the mux feature?
>> Nope (on the cli we use '-monitor unix:.mon,server,nowait' for the
>> HMP).
>>
>>> We also reset it
>>> in CHR_EVENT_OPENED if the mux feature is not used, why isn't that
>>> good enough?
>> I checked the code and on CHR_EVENT_OPENED the monitor calls
>> readline_show_prompt (when not using mux). This resets the
>> last_cmd_index/size readline variables, but the cmd_buf_index/size
>> remains intact. I think that readline_restart() is necessary in order to
>> cleanup the readline cmd buf (either in CHR_EVENT_OPENED or in
>> CHR_EVENT_CLOSED).
> I'm wondering if calling readline_restart() in the CHR_EVENT_CLOSED
> can break mux support. But I won't have time to check it today. Maybe
> moving the readline_restart() call to right before the
> readline_show_prompt() call in the OPENED event is the best thing to do?

I did some quick tests with a mux chardev (I tried two mux'ed HMP
monitors and a serial and an HMP). Calling readline_restart() in
CHR_EVENT_CLOSED didn't seem to affect mux support (as far as I could
tell). However, calling readline_restart() in CHR_EVENT_OPENED, just
before readline_show_prompt(), resolves the issue too, and I think it
makes more sense to be called at that point. If you agree, I can resend
the modified patch.

>
>> Thanks,
>> Stratos
>>
 Signed-off-by: Stratos Psomadakis 
 Signed-off-by: Dimitris Aragiorgis 
 ---
  monitor.c |1 +
  1 file changed, 1 insertion(+)

 diff --git a/monitor.c b/monitor.c
 index 34cee74..7857300 100644
 --- a/monitor.c
 +++ b/monitor.c
 @@ -5252,6 +5252,7 @@ static void monitor_event(void *opaque, int event)
  break;
  
  case CHR_EVENT_CLOSED:
 +readline_restart(mon->rs);
  mon_refcount--;
  monitor_fdsets_cleanup();
  break;
>>


-- 
Stratos Psomadakis





signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH v2] qcow2: add update refcount table realization for update_refcount

2014-09-13 Thread Jun Li
On Fri, 09/05 16:33, Stefan Hajnoczi wrote:
> On Mon, Sep 01, 2014 at 06:52:48PM +0800, Jun Li wrote:
> 
> How does this patch handle self-describing refcount blocks?  I think
> they will keep the refcount block alive forever because your code will
> not decide to free them.
> 

Sorry, I have ignored self-describing refcount blocks. :)

> This patch should also discard the refcount block if we decide to free
> it (in the same way that we discard at cluster_offset).
> 
> > diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
> > index 43665b8..63f36e6 100644
> > --- a/block/qcow2-refcount.c
> > +++ b/block/qcow2-refcount.c
> > @@ -586,6 +586,37 @@ static int QEMU_WARN_UNUSED_RESULT 
> > update_refcount(BlockDriverState *bs,
> >  if (refcount == 0 && s->discard_passthrough[type]) {
> >  update_refcount_discard(bs, cluster_offset, s->cluster_size);
> >  }
> > +
> > +/* When refcount block is NULL, update refcount table */
> > +if (block_index == 0) {
> 
> What is the purpose of block_index == 0?

Here is want to reduce the probability of running the following code. Only
when block_index == 0, we will run the following code to free refcount block.

> 
> > +int k = block_index;
> > +int refcount_block_entries = s->cluster_size / 
> > sizeof(uint16_t);
> > +for (k = 0; k < refcount_block_entries; k++) {
> > +if (refcount_block[k] != cpu_to_be16(0)) {
> > +break;
> > +}
> > +}
> > +
> > +if (k == refcount_block_entries) {
> > +qemu_vfree(refcount_block);
> 
> You can't do this, the buffer belongs to the refcount block cache.
> Please look at the cache get/put as well as qcow2_cache_create/destroy.

ok, thx. Should add 
qcow2_cache_put(bs, s->refcount_block_cache, (void**) refcount_block);

> 
> > +/* update refcount table */
> > +unsigned int refcount_table_index;
> > +uint64_t data64 = cpu_to_be64(0);
> > +refcount_table_index = cluster_index >> (s->cluster_bits -
> > +   REFCOUNT_SHIFT);
> > +ret = bdrv_pwrite_sync(bs->file,
> > +   s->refcount_table_offset +
> > +   refcount_table_index *
> > +   sizeof(uint64_t),
> > +   &data64, sizeof(data64));
> > +if (ret < 0) {
> > +goto fail;
> > +}
> 
> Plase use write_reftable_entry().

ok, got it. I will submit a new version when I submit v3 of qcow2 shrinking.


Best Regards,
Jun Li



Re: [Qemu-devel] [PATCH 4/4] block: Improve message for device name clashing with node name

2014-09-13 Thread Eric Blake
On 09/12/2014 01:26 PM, Markus Armbruster wrote:
> Suggested-by: Benoit Canet 
> Signed-off-by: Markus Armbruster 
> ---
>  block.c| 3 ++-
>  tests/qemu-iotests/087.out | 2 +-
>  2 files changed, 3 insertions(+), 2 deletions(-)

Reviewed-by: Eric Blake 

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



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PATCH v2 22/23] block: Lift device model API into BlockBackend

2014-09-13 Thread Markus Armbruster
Move device model attachment / detachment and the BlockDevOps device
model callbacks and their wrappers from BlockDriverState to
BlockBackend.

Signed-off-by: Markus Armbruster 
---
 block.c| 126 --
 block/block-backend.c  | 151 ++---
 block/qapi.c   |   8 +--
 blockdev.c |   8 +--
 include/block/block.h  |  45 
 include/block/block_int.h  |  12 ++--
 include/sysemu/block-backend.h |  35 ++
 7 files changed, 203 insertions(+), 182 deletions(-)

diff --git a/block.c b/block.c
index 9c6d467..0ef5182 100644
--- a/block.c
+++ b/block.c
@@ -58,9 +58,6 @@ struct BdrvDirtyBitmap {
 
 #define NOT_DONE 0x7fff /* used while emulated sync operation in progress 
*/
 
-#define COROUTINE_POOL_RESERVATION 64 /* number of coroutines to reserve */
-
-static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load);
 static BlockAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
 int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
 BlockCompletionFunc *cb, void *opaque);
@@ -1527,7 +1524,9 @@ int bdrv_open(BlockDriverState **pbs, const char 
*filename,
 }
 
 if (!bdrv_key_required(bs)) {
-bdrv_dev_change_media_cb(bs, true);
+if (bs->blk) {
+blk_dev_change_media_cb(bs->blk, true);
+}
 } else if (!runstate_check(RUN_STATE_PRELAUNCH)
&& !runstate_check(RUN_STATE_INMIGRATE)
&& !runstate_check(RUN_STATE_PAUSED)) { /* HACK */
@@ -1852,7 +1851,9 @@ void bdrv_close(BlockDriverState *bs)
 }
 }
 
-bdrv_dev_change_media_cb(bs, false);
+if (bs->blk) {
+blk_dev_change_media_cb(bs->blk, false);
+}
 
 /*throttling disk I/O limits*/
 if (bs->io_limits_enabled) {
@@ -1964,9 +1965,6 @@ static void bdrv_move_feature_fields(BlockDriverState 
*bs_dest,
 /* move some fields that need to stay attached to the device */
 
 /* dev info */
-bs_dest->dev_ops= bs_src->dev_ops;
-bs_dest->dev_opaque = bs_src->dev_opaque;
-bs_dest->dev= bs_src->dev;
 bs_dest->guest_block_size   = bs_src->guest_block_size;
 bs_dest->copy_on_read   = bs_src->copy_on_read;
 
@@ -2034,7 +2032,6 @@ void bdrv_swap(BlockDriverState *bs_new, BlockDriverState 
*bs_old)
 assert(!bs_new->blk);
 assert(QLIST_EMPTY(&bs_new->dirty_bitmaps));
 assert(bs_new->job == NULL);
-assert(bs_new->dev == NULL);
 assert(bs_new->io_limits_enabled == false);
 assert(!throttle_have_timer(&bs_new->throttle_state));
 
@@ -2051,7 +2048,6 @@ void bdrv_swap(BlockDriverState *bs_new, BlockDriverState 
*bs_old)
 assert(!bs_new->blk);
 
 /* Check a few fields that should remain attached to the device */
-assert(bs_new->dev == NULL);
 assert(bs_new->job == NULL);
 assert(bs_new->io_limits_enabled == false);
 assert(!throttle_have_timer(&bs_new->throttle_state));
@@ -2090,7 +2086,6 @@ void bdrv_append(BlockDriverState *bs_new, 
BlockDriverState *bs_top)
 
 static void bdrv_delete(BlockDriverState *bs)
 {
-assert(!bs->dev);
 assert(!bs->job);
 assert(bdrv_op_blocker_is_empty(bs));
 assert(!bs->refcnt);
@@ -2104,105 +2099,6 @@ static void bdrv_delete(BlockDriverState *bs)
 g_free(bs);
 }
 
-int bdrv_attach_dev(BlockDriverState *bs, void *dev)
-/* TODO change to DeviceState *dev when all users are qdevified */
-{
-if (bs->dev) {
-return -EBUSY;
-}
-bs->dev = dev;
-bdrv_iostatus_reset(bs);
-
-/* We're expecting I/O from the device so bump up coroutine pool size */
-qemu_coroutine_adjust_pool_size(COROUTINE_POOL_RESERVATION);
-return 0;
-}
-
-/* TODO qdevified devices don't use this, remove when devices are qdevified */
-void bdrv_attach_dev_nofail(BlockDriverState *bs, void *dev)
-{
-if (bdrv_attach_dev(bs, dev) < 0) {
-abort();
-}
-}
-
-void bdrv_detach_dev(BlockDriverState *bs, void *dev)
-/* TODO change to DeviceState *dev when all users are qdevified */
-{
-assert(bs->dev == dev);
-bs->dev = NULL;
-bs->dev_ops = NULL;
-bs->dev_opaque = NULL;
-bs->guest_block_size = 512;
-qemu_coroutine_adjust_pool_size(-COROUTINE_POOL_RESERVATION);
-}
-
-/* TODO change to return DeviceState * when all users are qdevified */
-void *bdrv_get_attached_dev(BlockDriverState *bs)
-{
-return bs->dev;
-}
-
-void bdrv_set_dev_ops(BlockDriverState *bs, const BlockDevOps *ops,
-  void *opaque)
-{
-bs->dev_ops = ops;
-bs->dev_opaque = opaque;
-}
-
-static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load)
-{
-if (bs->dev_ops && bs->dev_ops->change_media_cb) {
-bool tray_was_closed = !bdrv_dev_is_tray_open(bs);
-bs->dev_ops->change_media_cb(bs->dev_opaque, load);
-if (tray_was_closed) {
-/* tray open */
-qapi_event_send_device_tra

[Qemu-devel] [PATCH v2 18/23] blockdev: Fix blockdev-add not to create IDE drive (0, 0)

2014-09-13 Thread Markus Armbruster
blockdev_init() always creates a DriveInfo, but only drive_new() fills
it in.  qmp_blockdev_add() leaves it blank.  This results in a drive
with type = IF_IDE, bus = 0, unit = 0.  Screwed up in commit ee13ed1c.

Board initialization code looking for IDE drive (0,0) can pick up one
of these bogus drives.  Not sure whether getting the QMP command
executed early enough is likely in practice, though.

Fix by creating DriveInfo in drive_new().  Block backends created by
blockdev-add don't get one.

A few places assume a block backend always has a DriveInfo.  Fix them
up.

Signed-off-by: Markus Armbruster 
---
 block/block-backend.c |  4 +---
 blockdev.c| 10 ++
 hw/block/block.c  | 16 ++--
 hw/ide/qdev.c |  2 +-
 hw/scsi/scsi-disk.c   |  2 +-
 5 files changed, 15 insertions(+), 19 deletions(-)

diff --git a/block/block-backend.c b/block/block-backend.c
index 9b146c8..ac3d774 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -100,9 +100,7 @@ static void drive_info_del(DriveInfo *dinfo)
 if (!dinfo) {
 return;
 }
-if (dinfo->opts) {
-qemu_opts_del(dinfo->opts);
-}
+qemu_opts_del(dinfo->opts);
 g_free(dinfo->serial);
 g_free(dinfo);
 }
diff --git a/blockdev.c b/blockdev.c
index 2def256..0d99be0 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -285,7 +285,6 @@ static BlockBackend *blockdev_init(const char *file, QDict 
*bs_opts,
 int on_read_error, on_write_error;
 BlockBackend *blk;
 BlockDriverState *bs;
-DriveInfo *dinfo;
 ThrottleConfig cfg;
 int snapshot = 0;
 bool copy_on_read;
@@ -457,9 +456,6 @@ static BlockBackend *blockdev_init(const char *file, QDict 
*bs_opts,
 bdrv_set_io_limits(bs, &cfg);
 }
 
-dinfo = g_malloc0(sizeof(*dinfo));
-blk_set_legacy_dinfo(blk, dinfo);
-
 if (!file || !*file) {
 if (has_driver_specific_opts) {
 file = NULL;
@@ -903,21 +899,19 @@ DriveInfo *drive_new(QemuOpts *all_opts, 
BlockInterfaceType block_default_type)
 }
 
 /* Set legacy DriveInfo fields */
-dinfo = blk_legacy_dinfo(blk);
+dinfo = g_malloc0(sizeof(*dinfo));
 dinfo->enable_auto_del = true;
 dinfo->opts = all_opts;
-
 dinfo->cyls = cyls;
 dinfo->heads = heads;
 dinfo->secs = secs;
 dinfo->trans = translation;
-
 dinfo->type = type;
 dinfo->bus = bus_id;
 dinfo->unit = unit_id;
 dinfo->devaddr = devaddr;
-
 dinfo->serial = g_strdup(serial);
+blk_set_legacy_dinfo(blk, dinfo);
 
 switch(type) {
 case IF_IDE:
diff --git a/hw/block/block.c b/hw/block/block.c
index 0666dd3..a625773 100644
--- a/hw/block/block.c
+++ b/hw/block/block.c
@@ -19,7 +19,9 @@ void blkconf_serial(BlockConf *conf, char **serial)
 if (!*serial) {
 /* try to fall back to value set with legacy -drive serial=... */
 dinfo = blk_legacy_dinfo(conf->blk);
-*serial = g_strdup(dinfo->serial);
+if (dinfo) {
+*serial = g_strdup(dinfo->serial);
+}
 }
 }
 
@@ -32,11 +34,13 @@ void blkconf_geometry(BlockConf *conf, int *ptrans,
 if (!conf->cyls && !conf->heads && !conf->secs) {
 /* try to fall back to value set with legacy -drive cyls=... */
 dinfo = blk_legacy_dinfo(conf->blk);
-conf->cyls  = dinfo->cyls;
-conf->heads = dinfo->heads;
-conf->secs  = dinfo->secs;
-if (ptrans) {
-*ptrans = dinfo->trans;
+if (dinfo) {
+conf->cyls  = dinfo->cyls;
+conf->heads = dinfo->heads;
+conf->secs  = dinfo->secs;
+if (ptrans) {
+*ptrans = dinfo->trans;
+}
 }
 }
 if (!conf->cyls && !conf->heads && !conf->secs) {
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 4818334..a74c81e 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -206,7 +206,7 @@ static int ide_drive_initfn(IDEDevice *dev)
 {
 DriveInfo *dinfo = blk_legacy_dinfo(dev->conf.blk);
 
-return ide_dev_initfn(dev, dinfo->media_cd ? IDE_CD : IDE_HD);
+return ide_dev_initfn(dev, dinfo && dinfo->media_cd ? IDE_CD : IDE_HD);
 }
 
 #define DEFINE_IDE_DEV_PROPERTIES() \
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 768c1ad..e0c5ed3 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -2331,7 +2331,7 @@ static void scsi_disk_realize(SCSIDevice *dev, Error 
**errp)
 }
 
 dinfo = blk_legacy_dinfo(dev->conf.blk);
-if (dinfo->media_cd) {
+if (dinfo && dinfo->media_cd) {
 scsi_cd_realize(dev, errp);
 } else {
 scsi_hd_realize(dev, errp);
-- 
1.9.3




[Qemu-devel] [PATCH v2 11/23] block: Rename BlockDriverAIOCB* to BlockAIOCB*

2014-09-13 Thread Markus Armbruster
I'll use BlockDriverAIOCB with block backends shortly, and the name is
going to fit badly there.  It's a block layer thing anyway, not just a
block driver thing.

Signed-off-by: Markus Armbruster 
---
 block-migration.c   |   2 +-
 block.c | 151 ++--
 block/archipelago.c |  30 -
 block/backup.c  |   2 +-
 block/blkdebug.c|  22 +++
 block/blkverify.c   |  20 +++---
 block/commit.c  |   2 +-
 block/curl.c|   8 +--
 block/iscsi.c   |   8 +--
 block/linux-aio.c   |   8 +--
 block/mirror.c  |   6 +-
 block/qed-gencb.c   |   4 +-
 block/qed-table.c   |  10 +--
 block/qed.c |  46 +++---
 block/qed.h |  12 ++--
 block/quorum.c  |  38 +--
 block/raw-aio.h |   8 +--
 block/raw-posix.c   |  32 +-
 block/raw-win32.c   |  16 ++---
 block/raw_bsd.c |   8 +--
 block/rbd.c |  58 -
 block/sheepdog.c|   4 +-
 block/stream.c  |   2 +-
 block/win32-aio.c   |   8 +--
 blockjob.c  |   4 +-
 dma-helpers.c   |  24 +++
 hw/block/nvme.h |   2 +-
 hw/ide/ahci.c   |   2 +-
 hw/ide/ahci.h   |   2 +-
 hw/ide/core.c   |  12 ++--
 hw/ide/internal.h   |  12 ++--
 hw/ide/macio.c  |   2 +-
 hw/ide/pci.c|   2 +-
 hw/ide/pci.h|   2 +-
 hw/ppc/mac.h|   2 +-
 hw/scsi/scsi-generic.c  |   2 +-
 include/block/aio.h |  12 ++--
 include/block/block.h   |  36 +--
 include/block/block_int.h   |  30 -
 include/block/blockjob.h|   4 +-
 include/block/thread-pool.h |   4 +-
 include/hw/scsi/scsi.h  |   2 +-
 include/monitor/monitor.h   |   4 +-
 include/sysemu/dma.h|  26 
 monitor.c   |   6 +-
 tests/test-thread-pool.c|   2 +-
 thread-pool.c   |   8 +--
 47 files changed, 353 insertions(+), 354 deletions(-)

diff --git a/block-migration.c b/block-migration.c
index da30e93..08db01a 100644
--- a/block-migration.c
+++ b/block-migration.c
@@ -72,7 +72,7 @@ typedef struct BlkMigBlock {
 int nr_sectors;
 struct iovec iov;
 QEMUIOVector qiov;
-BlockDriverAIOCB *aiocb;
+BlockAIOCB *aiocb;
 
 /* Protected by block migration lock.  */
 int ret;
diff --git a/block.c b/block.c
index f59dade..9c6d467 100644
--- a/block.c
+++ b/block.c
@@ -61,12 +61,12 @@ struct BdrvDirtyBitmap {
 #define COROUTINE_POOL_RESERVATION 64 /* number of coroutines to reserve */
 
 static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load);
-static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
+static BlockAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
 int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-BlockDriverCompletionFunc *cb, void *opaque);
-static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs,
+BlockCompletionFunc *cb, void *opaque);
+static BlockAIOCB *bdrv_aio_writev_em(BlockDriverState *bs,
 int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-BlockDriverCompletionFunc *cb, void *opaque);
+BlockCompletionFunc *cb, void *opaque);
 static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs,
  int64_t sector_num, int nb_sectors,
  QEMUIOVector *iov);
@@ -79,14 +79,14 @@ static int coroutine_fn bdrv_co_do_preadv(BlockDriverState 
*bs,
 static int coroutine_fn bdrv_co_do_pwritev(BlockDriverState *bs,
 int64_t offset, unsigned int bytes, QEMUIOVector *qiov,
 BdrvRequestFlags flags);
-static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
-   int64_t sector_num,
-   QEMUIOVector *qiov,
-   int nb_sectors,
-   BdrvRequestFlags flags,
-   BlockDriverCompletionFunc *cb,
-   void *opaque,
-   bool is_write);
+static BlockAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
+ int64_t sector_num,
+ QEMUIOVector *qiov,
+ int nb_sectors,
+ BdrvRequestFlags flags,
+ BlockCompletionFunc *cb,
+ void *opaque,
+ bool is_write);
 static void coroutine_fn bdrv_co_do_rw(void *opaque);
 static int coroutine_fn bdrv

[Qemu-devel] [PATCH v2 20/23] block/qapi: Convert qmp_query_block() to BlockBackend

2014-09-13 Thread Markus Armbruster
Much more command code needs conversion.  I start with this one
because it's using bdrv_dev_* functions, which I'm about to lift into
BlockBackend.

While there, give bdrv_query_info() internal linkage.

Signed-off-by: Markus Armbruster 
---
 block/qapi.c | 15 ---
 include/block/qapi.h |  3 ---
 2 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/block/qapi.c b/block/qapi.c
index cc8f711..02121b2 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -28,6 +28,7 @@
 #include "qapi-visit.h"
 #include "qapi/qmp-output-visitor.h"
 #include "qapi/qmp/types.h"
+#include "sysemu/block-backend.h"
 #ifdef __linux__
 #include 
 #include 
@@ -264,15 +265,15 @@ void bdrv_query_image_info(BlockDriverState *bs,
 }
 
 /* @p_info will be set only on success. */
-void bdrv_query_info(BlockDriverState *bs,
- BlockInfo **p_info,
- Error **errp)
+static void bdrv_query_info(BlockBackend *blk, BlockInfo **p_info,
+Error **errp)
 {
 BlockInfo *info = g_malloc0(sizeof(*info));
+BlockDriverState *bs = blk_bs(blk);
 BlockDriverState *bs0;
 ImageInfo **p_image_info;
 Error *local_err = NULL;
-info->device = g_strdup(bdrv_get_device_name(bs));
+info->device = g_strdup(blk_name(blk));
 info->type = g_strdup("unknown");
 info->locked = bdrv_dev_is_medium_locked(bs);
 info->removable = bdrv_dev_has_removable_media(bs);
@@ -359,12 +360,12 @@ static BlockStats *bdrv_query_stats(const 
BlockDriverState *bs)
 BlockInfoList *qmp_query_block(Error **errp)
 {
 BlockInfoList *head = NULL, **p_next = &head;
-BlockDriverState *bs = NULL;
+BlockBackend *blk;
 Error *local_err = NULL;
 
- while ((bs = bdrv_next(bs))) {
+for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
 BlockInfoList *info = g_malloc0(sizeof(*info));
-bdrv_query_info(bs, &info->value, &local_err);
+bdrv_query_info(blk, &info->value, &local_err);
 if (local_err) {
 error_propagate(errp, local_err);
 goto err;
diff --git a/include/block/qapi.h b/include/block/qapi.h
index 0374546..168d788 100644
--- a/include/block/qapi.h
+++ b/include/block/qapi.h
@@ -36,9 +36,6 @@ int bdrv_query_snapshot_info_list(BlockDriverState *bs,
 void bdrv_query_image_info(BlockDriverState *bs,
ImageInfo **p_info,
Error **errp);
-void bdrv_query_info(BlockDriverState *bs,
- BlockInfo **p_info,
- Error **errp);
 
 void bdrv_snapshot_dump(fprintf_function func_fprintf, void *f,
 QEMUSnapshotInfo *sn);
-- 
1.9.3




[Qemu-devel] [PATCH v2 23/23] block: Make device model's references to BlockBackend strong

2014-09-13 Thread Markus Armbruster
Doesn't make a difference just yet, but it's the right thing to do.

Signed-off-by: Markus Armbruster 
---
 block/block-backend.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/block/block-backend.c b/block/block-backend.c
index 9c504f3..17285ba 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -251,6 +251,7 @@ int blk_attach_dev(BlockBackend *blk, void *dev)
 if (blk->dev) {
 return -EBUSY;
 }
+blk_ref(blk);
 blk->dev = dev;
 bdrv_iostatus_reset(blk->bs);
 
@@ -279,9 +280,10 @@ void blk_detach_dev(BlockBackend *blk, void *dev)
 /* TODO change to DeviceState *dev when all users are qdevified */
 {
 assert(blk->dev == dev);
-blk->dev = NULL;
 blk->dev_ops = NULL;
 blk->dev_opaque = NULL;
+blk->dev = NULL;
+blk_unref(blk);
 bdrv_set_guest_block_size(blk->bs, 512);
 qemu_coroutine_adjust_pool_size(-COROUTINE_POOL_RESERVATION);
 }
-- 
1.9.3




[Qemu-devel] [PATCH v2 21/23] blockdev: Convert qmp_eject(), qmp_change_blockdev() to BlockBackend

2014-09-13 Thread Markus Armbruster
Much more command code needs conversion.  I'm converting these now
because they's using bdrv_dev_* functions, which I'm about to lift
into BlockBackend.

Signed-off-by: Markus Armbruster 
---
 blockdev.c | 20 
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index e218c59..e115bde 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1502,8 +1502,10 @@ exit:
 }
 
 
-static void eject_device(BlockDriverState *bs, int force, Error **errp)
+static void eject_device(BlockBackend *blk, int force, Error **errp)
 {
+BlockDriverState *bs = blk_bs(blk);
+
 if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_EJECT, errp)) {
 return;
 }
@@ -1527,15 +1529,15 @@ static void eject_device(BlockDriverState *bs, int 
force, Error **errp)
 
 void qmp_eject(const char *device, bool has_force, bool force, Error **errp)
 {
-BlockDriverState *bs;
+BlockBackend *blk;
 
-bs = bdrv_find(device);
-if (!bs) {
+blk = blk_by_name(device);
+if (!blk) {
 error_set(errp, QERR_DEVICE_NOT_FOUND, device);
 return;
 }
 
-eject_device(bs, force, errp);
+eject_device(blk, force, errp);
 }
 
 void qmp_block_passwd(bool has_device, const char *device,
@@ -1594,16 +1596,18 @@ static void qmp_bdrv_open_encrypted(BlockDriverState 
*bs, const char *filename,
 void qmp_change_blockdev(const char *device, const char *filename,
  const char *format, Error **errp)
 {
+BlockBackend *blk;
 BlockDriverState *bs;
 BlockDriver *drv = NULL;
 int bdrv_flags;
 Error *err = NULL;
 
-bs = bdrv_find(device);
-if (!bs) {
+blk = blk_by_name(device);
+if (!blk) {
 error_set(errp, QERR_DEVICE_NOT_FOUND, device);
 return;
 }
+bs = blk_bs(blk);
 
 if (format) {
 drv = bdrv_find_whitelisted_format(format, bs->read_only);
@@ -1613,7 +1617,7 @@ void qmp_change_blockdev(const char *device, const char 
*filename,
 }
 }
 
-eject_device(bs, 0, &err);
+eject_device(blk, 0, &err);
 if (err) {
 error_propagate(errp, err);
 return;
-- 
1.9.3




[Qemu-devel] [PATCH v2 17/23] blockdev: Drop superfluous DriveInfo member id

2014-09-13 Thread Markus Armbruster
Signed-off-by: Markus Armbruster 
---
 block/block-backend.c | 1 -
 blockdev.c| 3 +--
 include/sysemu/blockdev.h | 1 -
 3 files changed, 1 insertion(+), 4 deletions(-)

diff --git a/block/block-backend.c b/block/block-backend.c
index 472b545..9b146c8 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -103,7 +103,6 @@ static void drive_info_del(DriveInfo *dinfo)
 if (dinfo->opts) {
 qemu_opts_del(dinfo->opts);
 }
-g_free(dinfo->id);
 g_free(dinfo->serial);
 g_free(dinfo);
 }
diff --git a/blockdev.c b/blockdev.c
index e87bf4b..2def256 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -458,7 +458,6 @@ static BlockBackend *blockdev_init(const char *file, QDict 
*bs_opts,
 }
 
 dinfo = g_malloc0(sizeof(*dinfo));
-dinfo->id = g_strdup(qemu_opts_id(opts));
 blk_set_legacy_dinfo(blk, dinfo);
 
 if (!file || !*file) {
@@ -492,7 +491,7 @@ static BlockBackend *blockdev_init(const char *file, QDict 
*bs_opts,
 
 if (ret < 0) {
 error_setg(errp, "could not open disk image %s: %s",
-   file ?: dinfo->id, error_get_pretty(error));
+   file ?: blk_name(blk), error_get_pretty(error));
 error_free(error);
 goto err;
 }
diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
index f66b89a..27a40d5 100644
--- a/include/sysemu/blockdev.h
+++ b/include/sysemu/blockdev.h
@@ -30,7 +30,6 @@ typedef enum {
 } BlockInterfaceType;
 
 struct DriveInfo {
-char *id;
 const char *devaddr;
 BlockInterfaceType type;
 int bus;
-- 
1.9.3




[Qemu-devel] [PATCH v2 15/23] ide: Complete conversion from BlockDriverState to BlockBackend

2014-09-13 Thread Markus Armbruster
Add a BlockBackend member to TrimAIOCB, so ide_issue_trim_cb() can use
blk_aio_discard() instead of bdrv_aio_discard().

Signed-off-by: Markus Armbruster 
---
 hw/ide/core.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/hw/ide/core.c b/hw/ide/core.c
index fe12145..c043dbe 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -362,6 +362,7 @@ static void ide_set_signature(IDEState *s)
 
 typedef struct TrimAIOCB {
 BlockAIOCB common;
+BlockBackend *blk;
 QEMUBH *bh;
 int ret;
 QEMUIOVector *qiov;
@@ -423,8 +424,8 @@ static void ide_issue_trim_cb(void *opaque, int ret)
 }
 
 /* Got an entry! Submit and exit.  */
-iocb->aiocb = bdrv_aio_discard(iocb->common.bs, sector, count,
-   ide_issue_trim_cb, opaque);
+iocb->aiocb = blk_aio_discard(iocb->blk, sector, count,
+  ide_issue_trim_cb, opaque);
 return;
 }
 
@@ -448,6 +449,7 @@ BlockAIOCB *ide_issue_trim(BlockBackend *blk,
 TrimAIOCB *iocb;
 
 iocb = blk_aio_get(&trim_aiocb_info, blk, cb, opaque);
+iocb->blk = blk;
 iocb->bh = qemu_bh_new(ide_trim_bh_cb, iocb);
 iocb->ret = 0;
 iocb->qiov = qiov;
-- 
1.9.3




[Qemu-devel] [PATCH v2 19/23] blockdev: Drop DriveInfo member enable_auto_del

2014-09-13 Thread Markus Armbruster
Commit 2d246f0 introduced DriveInfo member enable_auto_del to
distinguish DriveInfo created via drive_new() from DriveInfo created
via qmp_blockdev_add().  The latter no longer exist.  Drop
enable_auto_del.

Signed-off-by: Markus Armbruster 
---
 blockdev.c| 11 +++
 include/sysemu/blockdev.h |  1 -
 2 files changed, 3 insertions(+), 9 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 0d99be0..e218c59 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -90,16 +90,14 @@ void blockdev_mark_auto_del(BlockBackend *blk)
 DriveInfo *dinfo = blk_legacy_dinfo(blk);
 BlockDriverState *bs = blk_bs(blk);
 
-if (dinfo && !dinfo->enable_auto_del) {
+if (!dinfo) {
 return;
 }
 
 if (bs->job) {
 block_job_cancel(bs->job);
 }
-if (dinfo) {
-dinfo->auto_del = 1;
-}
+dinfo->auto_del = 1;
 }
 
 void blockdev_auto_del(BlockBackend *blk)
@@ -900,7 +898,6 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType 
block_default_type)
 
 /* Set legacy DriveInfo fields */
 dinfo = g_malloc0(sizeof(*dinfo));
-dinfo->enable_auto_del = true;
 dinfo->opts = all_opts;
 dinfo->cyls = cyls;
 dinfo->heads = heads;
@@ -1716,7 +1713,6 @@ int do_drive_del(Monitor *mon, const QDict *qdict, 
QObject **ret_data)
 const char *id = qdict_get_str(qdict, "id");
 BlockBackend *blk;
 BlockDriverState *bs;
-DriveInfo *dinfo;
 AioContext *aio_context;
 Error *local_err = NULL;
 
@@ -1727,8 +1723,7 @@ int do_drive_del(Monitor *mon, const QDict *qdict, 
QObject **ret_data)
 }
 bs = blk_bs(blk);
 
-dinfo = blk_legacy_dinfo(blk);
-if (dinfo && !dinfo->enable_auto_del) {
+if (!blk_legacy_dinfo(blk)) {
 error_report("Deleting device added with blockdev-add"
  " is not supported");
 return -1;
diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
index 27a40d5..2129d81 100644
--- a/include/sysemu/blockdev.h
+++ b/include/sysemu/blockdev.h
@@ -35,7 +35,6 @@ struct DriveInfo {
 int bus;
 int unit;
 int auto_del;   /* see blockdev_mark_auto_del() */
-bool enable_auto_del;   /* Only for legacy drive_new() */
 int media_cd;
 int cyls, heads, secs, trans;
 QemuOpts *opts;
-- 
1.9.3




[Qemu-devel] [PATCH v2 16/23] pc87312: Drop unused members of PC87312State

2014-09-13 Thread Markus Armbruster
Signed-off-by: Markus Armbruster 
---
 include/hw/isa/pc87312.h | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/include/hw/isa/pc87312.h b/include/hw/isa/pc87312.h
index befc8bd..bf74470 100644
--- a/include/hw/isa/pc87312.h
+++ b/include/hw/isa/pc87312.h
@@ -47,13 +47,10 @@ typedef struct PC87312State {
 
 struct {
 ISADevice *dev;
-BlockDriverState *drive[2];
-uint32_t base;
 } fdc;
 
 struct {
 ISADevice *dev;
-uint32_t base;
 } ide;
 
 MemoryRegion io;
-- 
1.9.3




[Qemu-devel] [PATCH v2 05/23] block: Code motion to get rid of stubs/blockdev.c

2014-09-13 Thread Markus Armbruster
Signed-off-by: Markus Armbruster 
---
 block/block-backend.c | 15 +++
 blockdev.c| 13 -
 include/sysemu/blockdev.h |  1 -
 stubs/Makefile.objs   |  1 -
 stubs/blockdev.c  | 12 
 5 files changed, 15 insertions(+), 27 deletions(-)
 delete mode 100644 stubs/blockdev.c

diff --git a/block/block-backend.c b/block/block-backend.c
index 7b8c062..0842abe 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -22,6 +22,8 @@ struct BlockBackend {
 QTAILQ_ENTRY(BlockBackend) link; /* for blk_backends */
 };
 
+static void drive_info_del(DriveInfo *dinfo);
+
 /* All the BlockBackends (except for hidden ones) */
 static QTAILQ_HEAD(, BlockBackend) blk_backends =
 QTAILQ_HEAD_INITIALIZER(blk_backends);
@@ -92,6 +94,19 @@ static void blk_delete(BlockBackend *blk)
 g_free(blk);
 }
 
+static void drive_info_del(DriveInfo *dinfo)
+{
+if (!dinfo) {
+return;
+}
+if (dinfo->opts) {
+qemu_opts_del(dinfo->opts);
+}
+g_free(dinfo->id);
+g_free(dinfo->serial);
+g_free(dinfo);
+}
+
 /*
  * Increment @blk's reference count.
  * @blk must not be null.
diff --git a/blockdev.c b/blockdev.c
index aec9f0e..0ed108d 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -223,19 +223,6 @@ void drive_del(DriveInfo *dinfo)
 blk_unref(blk_by_legacy_dinfo(dinfo));
 }
 
-void drive_info_del(DriveInfo *dinfo)
-{
-if (!dinfo) {
-return;
-}
-if (dinfo->opts) {
-qemu_opts_del(dinfo->opts);
-}
-g_free(dinfo->id);
-g_free(dinfo->serial);
-g_free(dinfo);
-}
-
 typedef struct {
 QEMUBH *bh;
 BlockDriverState *bs;
diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
index 1dc5906..2ed297b 100644
--- a/include/sysemu/blockdev.h
+++ b/include/sysemu/blockdev.h
@@ -60,7 +60,6 @@ QemuOpts *drive_add(BlockInterfaceType type, int index, const 
char *file,
 const char *optstr);
 DriveInfo *drive_new(QemuOpts *arg, BlockInterfaceType block_default_type);
 void drive_del(DriveInfo *dinfo);
-void drive_info_del(DriveInfo *dinfo);
 
 /* device-hotplug */
 
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index c0b1f6a..5e347d0 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -1,6 +1,5 @@
 stub-obj-y += arch-query-cpu-def.o
 stub-obj-y += bdrv-commit-all.o
-stub-obj-y += blockdev.o
 stub-obj-y += chr-baum-init.o
 stub-obj-y += chr-msmouse.o
 stub-obj-y += chr-testdev.o
diff --git a/stubs/blockdev.c b/stubs/blockdev.c
deleted file mode 100644
index 5d0a79c..000
--- a/stubs/blockdev.c
+++ /dev/null
@@ -1,12 +0,0 @@
-#include 
-#include "sysemu/blockdev.h"
-
-DriveInfo *drive_get_by_blockdev(BlockDriverState *bs)
-{
-return NULL;
-}
-
-void drive_info_del(DriveInfo *dinfo)
-{
-assert(!dinfo);
-}
-- 
1.9.3




[Qemu-devel] [PATCH v2 10/23] block: Eliminate DriveInfo member bdrv, use blk_by_legacy_dinfo()

2014-09-13 Thread Markus Armbruster
The patch is big, but all it really does is replacing

dinfo->bdrv

by

blk_bs(blk_legacy_dinfo(dinfo))

The replacement is repetitive, but the conversion of device models to
BlockBackend is imminent, and will shorten it to just
blk_legacy_dinfo(dinfo).

Line wrapping muddies the waters a bit.  I also omit tests whether
dinfo->bdrv is null, because it never is.

Signed-off-by: Markus Armbruster 
---
 blockdev.c   |  3 +--
 hw/arm/collie.c  |  9 +
 hw/arm/gumstix.c |  5 +++--
 hw/arm/mainstone.c   |  8 
 hw/arm/musicpal.c| 11 ++-
 hw/arm/nseries.c |  6 --
 hw/arm/omap1.c   |  4 +++-
 hw/arm/omap2.c   |  4 +++-
 hw/arm/omap_sx1.c|  9 +
 hw/arm/pxa2xx.c  |  7 +--
 hw/arm/spitz.c   |  4 +++-
 hw/arm/versatilepb.c |  4 +++-
 hw/arm/vexpress.c|  4 +++-
 hw/arm/xilinx_zynq.c |  4 +++-
 hw/arm/z2.c  |  7 ---
 hw/block/fdc.c   | 16 +++-
 hw/block/m25p80.c|  5 +++--
 hw/block/xen_disk.c  |  2 +-
 hw/cris/axis_dev88.c |  3 ++-
 hw/display/tc6393xb.c|  4 +++-
 hw/i386/pc_sysfw.c   |  3 ++-
 hw/ide/piix.c|  6 --
 hw/ide/qdev.c|  4 +++-
 hw/isa/pc87312.c |  7 +--
 hw/lm32/lm32_boards.c| 13 +++--
 hw/lm32/milkymist.c  |  7 ---
 hw/microblaze/petalogix_ml605_mmu.c  |  5 +++--
 hw/microblaze/petalogix_s3adsp1800_mmu.c |  5 +++--
 hw/mips/mips_malta.c |  4 +++-
 hw/mips/mips_r4k.c   |  5 +++--
 hw/pci/pci-hotplug-old.c |  9 ++---
 hw/ppc/ppc405_boards.c   | 25 -
 hw/ppc/spapr.c   |  4 +++-
 hw/ppc/virtex_ml507.c|  5 +++--
 hw/scsi/scsi-bus.c   |  5 +++--
 hw/sd/milkymist-memcard.c|  7 +--
 hw/sd/pl181.c|  3 ++-
 hw/sd/sdhci.c|  3 ++-
 hw/sd/ssi-sd.c   |  3 ++-
 hw/sh4/r2d.c |  5 +++--
 hw/usb/dev-storage.c |  4 +++-
 hw/xtensa/xtfpga.c   |  4 +++-
 include/sysemu/blockdev.h|  1 -
 43 files changed, 163 insertions(+), 93 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 85f574b..49496b6 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -472,7 +472,6 @@ static BlockBackend *blockdev_init(const char *file, QDict 
*bs_opts,
 
 dinfo = g_malloc0(sizeof(*dinfo));
 dinfo->id = g_strdup(qemu_opts_id(opts));
-dinfo->bdrv = bs;
 blk_set_legacy_dinfo(blk, dinfo);
 
 if (!file || !*file) {
@@ -502,7 +501,7 @@ static BlockBackend *blockdev_init(const char *file, QDict 
*bs_opts,
 
 QINCREF(bs_opts);
 ret = bdrv_open(&bs, file, NULL, bs_opts, bdrv_flags, drv, &error);
-assert(bs == dinfo->bdrv);
+assert(bs == blk_bs(blk));
 
 if (ret < 0) {
 error_setg(errp, "could not open disk image %s: %s",
diff --git a/hw/arm/collie.c b/hw/arm/collie.c
index ed7851f..0247290 100644
--- a/hw/arm/collie.c
+++ b/hw/arm/collie.c
@@ -15,6 +15,7 @@
 #include "strongarm.h"
 #include "hw/arm/arm.h"
 #include "hw/block/flash.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "exec/address-spaces.h"
 
@@ -41,13 +42,13 @@ static void collie_init(MachineState *machine)
 
 dinfo = drive_get(IF_PFLASH, 0, 0);
 pflash_cfi01_register(SA_CS0, NULL, "collie.fl1", 0x0200,
-dinfo ? dinfo->bdrv : NULL, (64 * 1024),
-512, 4, 0x00, 0x00, 0x00, 0x00, 0);
+dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
+(64 * 1024), 512, 4, 0x00, 0x00, 0x00, 0x00, 0);
 
 dinfo = drive_get(IF_PFLASH, 0, 1);
 pflash_cfi01_register(SA_CS1, NULL, "collie.fl2", 0x0200,
-dinfo ? dinfo->bdrv : NULL, (64 * 1024),
-512, 4, 0x00, 0x00, 0x00, 0x00, 0);
+dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,
+(64 * 1024), 512, 4, 0x00, 0x00, 0x00, 0x00, 0);
 
 sysbus_create_simple("scoop", 0x4080, NULL);
 
diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
index 3f8465e..49f9339 100644
--- a/hw/arm/gumstix.c
+++ b/hw/arm/gumstix.c
@@ -40,6 +40,7 @@
 #include "hw/block/flash.h"
 #include "hw/devices.h"
 #include "hw/boards.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "exec/address-spaces.h"

[Qemu-devel] [PATCH v2 00/23] Split BlockBackend off BDS with an axe

2014-09-13 Thread Markus Armbruster
My last attempt got bogged down because I tried to do a reasonably
complete job, and the complexity proved more than I could handle with
the limited amount of uninterrupted time available.  This time, I'm
cutting BlockBackend off with an axe, leaving most of the work for
later.

Done in this series already:

* Introduce a BlockBackend type, and lift up BlockDriverState's
  device_name, device_list, dev, dev_ops, dev_opaque.  Much more
  remains to be lifted.

* Make BlockBackend own the DriveInfo.

* Wean hw/ off BlockDriverState, with two small exceptions.

* Fix blockdev-add not to create a bogus IDE drive (0,0).

* Take a few baby steps towards use of BlockBackend in monitor command
  code where appropriate.

Coming soon, hopefully:

* QMP command blockdev-del

* blockdev-add accepts node-name without id at top level

* Lift up more stuff

* More BlockBackend use in monitor command code

Depends on my
[PATCH 0/4] Block-related miscellaneous cleanups.
[PATCH] blockdev: Refuse to drive_del something added with blockdev-add
[PATCH 0/4] Miscellaneous block fixes

I know the diffstat looks intimidating.  I tried very hard to split
the patches so that the bigger ones do just one simple thing, and
mostly mechanically.

v2:
* General
  - Improved function comments [Kevin, Benoît]
  - Avoiding temporary badness around drive_del affects several
patches up to PATCH 14/23, but by then the solution is basically
v1's again, plus a simple bug fix.
* [PATCH 01/23] block: Split bdrv_new_root() off bdrv_new()
  - Call it bdrv_new_root() instead of bdrv_new_named(), because it'll
lose its name parameter in PATCH 08.  In v1, it gets removed there.
  - Drop a condition that cannot be false due to prior assertion
* [PATCH 02/23] block: New BlockBackend
  - Commit message amended to explain when BlockBackends get created
and destroyed [Kevin]
  - License reluctantly changed to LGPL2.1+ [Kevin]
  - Plug leak on error in blk_new() [Kevin]
  - g_assert() is silly, stick to plain assert() [Kevin]
  - Fix double-free when do_drive_del() leaves BDS destruction to
blockdev_auto_del(), and user adds a BB with the same name in
between [Kevin]
Note: bug goes away later in v1
  - Plug a bunch of leaks on error in qemu-img.c [Kevin, Benoît]
Note: bugs goes away later in v1
  - Update for "[PATCH 3/4] qemu-nbd: Destroy the BlockDriverState
properly"
* [PATCH 03/23] block: Connect BlockBackend to BlockDriverState
  - Keep the double-free just mentioned fixed; commit message amended
to explain the drive_del complications
Basically move v1's solution from "[PATCH 14/23] hw: Convert from
BlockDriverState to BlockBackend, mostly" here, plus a fix for
invalid queue removal in blk_delete()
  - Cleanup extracted and posted separately as "[PATCH 1/4] blockdev:
Disentangle BlockDriverState and DriveInfo creation" [Kevin]
  - Inline blk_attach_bs(), blk_detach_bs() into only callers
  - Rebase on PATCH 02's qemu-img.c leak fixes, basically reverting
its error path complications
  - Update for "[PATCH 3/4] qemu-nbd: Destroy the BlockDriverState
properly"
* [PATCH 04/23] block: Connect BlockBackend and DriveInfo
  - Bug fix extracted and posted separately as "[PATCH 2/4] block:
Keep DriveInfo alive until BlockDriverState dies" [Kevin]
Unlike v1, it takes care to preserve the guard against
qemu_opts_del(NULL)
Could only happen when drive_del'ing something created with
blockdev-add, which is impossible since "[PATCH] blockdev: Refuse
to drive_del something added with blockdev-add", but not obviously
so
Becomes obvious in PATCH 18, which duly drops the guard
  - Plug leak on error in drive_new() [Kevin]
* [PATCH 05/23] block: Code motion to get rid of stubs/blockdev.c
  - New; to separate some of the cleanup of the mess made in said
extracted bug fix from the previous patch, to keep it more readable
* [PATCH 06/23] block: Make BlockBackend own its BlockDriverState
  - Update for "[PATCH 3/4] qemu-nbd: Destroy the BlockDriverState
properly"
* [PATCH 07/23] block: Eliminate bdrv_states, use block_next() instead
  - Drop; it can break things when a root BDS outlives its BB, because
something else is holding a reference to the BDS when the BB dies
* [PATCH 07/23] block: Eliminate bdrv_iterate(), use bdrv_next()
  - Fix accidental removal of a line [Benoît]
* [PATCH 08/23] block: Eliminate BlockDriverState member device_name[]
  - Commit message: typo fixed [Eric], clarified
  - Update for [PATCH 4/4] block: Improve message for device name
clashing with node name
  - Ripple effects from drop of PATCH 07
  - Neater implementation of bdrv_get_device_name() [Benoît]
* [PATCH 09/23] block: Merge BlockBackend and BlockDriverState name
  spaces
  - Update for [PATCH 4/4] block: Improve message for device name
clashing with node name
* [PATCH 10/23] block: Eliminate DriveInfo member bdrv, use
  - Commit message amended to explain the repetitive changes

[Qemu-devel] [PATCH v2 06/23] block: Make BlockBackend own its BlockDriverState

2014-09-13 Thread Markus Armbruster
On BlockBackend destruction, unref its BlockDriverState.  Replaces the
callers' unrefs.

Signed-off-by: Markus Armbruster 
---
 block/block-backend.c |  6 ++
 blockdev.c|  7 ++-
 hw/block/xen_disk.c   |  6 +++---
 qemu-img.c| 35 +--
 qemu-io.c |  5 -
 qemu-nbd.c|  1 -
 6 files changed, 8 insertions(+), 52 deletions(-)

diff --git a/block/block-backend.c b/block/block-backend.c
index 0842abe..dfe2654 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -54,8 +54,6 @@ BlockBackend *blk_new(const char *name, Error **errp)
 
 /*
  * Create a new BlockBackend with a new BlockDriverState attached.
- * Both have a reference count of one.  Caller owns *both* references.
- * TODO Let caller own only the BlockBackend reference
  * Otherwise just like blk_new(), which see.
  */
 BlockBackend *blk_new_with_bs(const char *name, Error **errp)
@@ -83,7 +81,9 @@ static void blk_delete(BlockBackend *blk)
 {
 assert(!blk->refcnt);
 if (blk->bs) {
+assert(blk->bs->blk == blk);
 blk->bs->blk = NULL;
+bdrv_unref(blk->bs);
 blk->bs = NULL;
 }
 if (blk->name[0]) {
@@ -120,8 +120,6 @@ void blk_ref(BlockBackend *blk)
  * Decrement @blk's reference count.
  * If this drops it to zero, destroy @blk.
  * For convenience, do nothing if @blk is null.
- * Does *not* touch the attached BlockDriverState's reference count.
- * TODO Decrement it!
  */
 void blk_unref(BlockBackend *blk)
 {
diff --git a/blockdev.c b/blockdev.c
index 0ed108d..3a6fd46 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -108,7 +108,7 @@ void blockdev_auto_del(BlockDriverState *bs)
 DriveInfo *dinfo = blk_legacy_dinfo(blk);
 
 if (dinfo && dinfo->auto_del) {
-drive_del(dinfo);
+blk_unref(blk);
 }
 }
 
@@ -219,7 +219,6 @@ static void bdrv_format_print(void *opaque, const char 
*name)
 
 void drive_del(DriveInfo *dinfo)
 {
-bdrv_unref(dinfo->bdrv);
 blk_unref(blk_by_legacy_dinfo(dinfo));
 }
 
@@ -522,7 +521,6 @@ static BlockBackend *blockdev_init(const char *file, QDict 
*bs_opts,
 return blk;
 
 err:
-bdrv_unref(bs);
 blk_unref(blk);
 early_err:
 qemu_opts_del(opts);
@@ -1783,7 +1781,7 @@ int do_drive_del(Monitor *mon, const QDict *qdict, 
QObject **ret_data)
 bdrv_set_on_error(bs, BLOCKDEV_ON_ERROR_REPORT,
   BLOCKDEV_ON_ERROR_REPORT);
 } else {
-drive_del(dinfo);
+blk_unref(blk);
 }
 
 aio_context_release(aio_context);
@@ -2520,7 +2518,6 @@ void qmp_blockdev_add(BlockdevOptions *options, Error 
**errp)
 }
 
 if (bdrv_key_required(blk_bs(blk))) {
-bdrv_unref(blk_bs(blk));
 blk_unref(blk);
 error_setg(errp, "blockdev-add doesn't support encrypted devices");
 goto fail;
diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
index 51f4f3a..6d474b9 100644
--- a/hw/block/xen_disk.c
+++ b/hw/block/xen_disk.c
@@ -870,7 +870,6 @@ static int blk_connect(struct XenDevice *xendev)
 xen_be_printf(&blkdev->xendev, 0, "error: %s\n",
   error_get_pretty(local_err));
 error_free(local_err);
-bdrv_unref(blkdev->bs);
 blk_unref(blk);
 blkdev->bs = NULL;
 return -1;
@@ -886,7 +885,9 @@ static int blk_connect(struct XenDevice *xendev)
 }
 /* blkdev->bs is not create by us, we get a reference
  * so we can bdrv_unref() unconditionally */
-bdrv_ref(blkdev->bs);
+/* Except we don't bdrv_unref() anymore, we blk_unref().
+ * Conditionally, because we can't easily blk_ref() here.
+ * TODO Clean this up! */
 }
 bdrv_attach_dev_nofail(blkdev->bs, blkdev);
 blkdev->file_size = bdrv_getlength(blkdev->bs);
@@ -986,7 +987,6 @@ static void blk_disconnect(struct XenDevice *xendev)
 
 if (blkdev->bs) {
 bdrv_detach_dev(blkdev->bs, blkdev);
-bdrv_unref(blkdev->bs);
 if (!blkdev->dinfo) {
 blk_unref(blk_by_name(blkdev->dev));
 }
diff --git a/qemu-img.c b/qemu-img.c
index 206a513..40bd129 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -329,7 +329,6 @@ static BlockBackend *img_open(const char *id, const char 
*filename,
 }
 return blk;
 fail:
-bdrv_unref(bs);
 blk_unref(blk);
 return NULL;
 }
@@ -712,9 +711,7 @@ static int img_check(int argc, char **argv)
 
 fail:
 qapi_free_ImageCheck(check);
-bdrv_unref(bs);
 blk_unref(blk);
-
 return ret;
 }
 
@@ -786,7 +783,6 @@ static int img_commit(int argc, char **argv)
 break;
 }
 
-bdrv_unref(bs);
 blk_unref(blk);
 if (ret) {
 return 1;
@@ -1196,10 +1192,8 @@ static int img_compare(int argc, char **argv)
 out:
 qemu_vfree(buf1);
 qemu_vfree(buf2);
-bdrv_unref(bs2);
 blk_unref(blk2);
 out2:
-bdrv_unref(bs1);
 blk_unref(blk1);
 out3:
 qemu_progress_end();
@@ -1756,18 +17

[Qemu-devel] [PATCH v2 07/23] block: Eliminate bdrv_iterate(), use bdrv_next()

2014-09-13 Thread Markus Armbruster
Signed-off-by: Markus Armbruster 
---
 block-migration.c | 30 +++---
 block.c   |  9 -
 blockdev.c| 31 +--
 include/block/block.h |  2 --
 monitor.c | 32 +---
 5 files changed, 37 insertions(+), 67 deletions(-)

diff --git a/block-migration.c b/block-migration.c
index 3ad31a2..cb3e16c 100644
--- a/block-migration.c
+++ b/block-migration.c
@@ -343,12 +343,25 @@ static void unset_dirty_tracking(void)
 }
 }
 
-static void init_blk_migration_it(void *opaque, BlockDriverState *bs)
+static void init_blk_migration(QEMUFile *f)
 {
+BlockDriverState *bs;
 BlkMigDevState *bmds;
 int64_t sectors;
 
-if (!bdrv_is_read_only(bs)) {
+block_mig_state.submitted = 0;
+block_mig_state.read_done = 0;
+block_mig_state.transferred = 0;
+block_mig_state.total_sector_sum = 0;
+block_mig_state.prev_progress = -1;
+block_mig_state.bulk_completed = 0;
+block_mig_state.zero_blocks = migrate_zero_blocks();
+
+for (bs = bdrv_next(NULL); bs; bs = bdrv_next(bs)) {
+if (bdrv_is_read_only(bs)) {
+continue;
+}
+
 sectors = bdrv_nb_sectors(bs);
 if (sectors <= 0) {
 return;
@@ -378,19 +391,6 @@ static void init_blk_migration_it(void *opaque, 
BlockDriverState *bs)
 }
 }
 
-static void init_blk_migration(QEMUFile *f)
-{
-block_mig_state.submitted = 0;
-block_mig_state.read_done = 0;
-block_mig_state.transferred = 0;
-block_mig_state.total_sector_sum = 0;
-block_mig_state.prev_progress = -1;
-block_mig_state.bulk_completed = 0;
-block_mig_state.zero_blocks = migrate_zero_blocks();
-
-bdrv_iterate(init_blk_migration_it, NULL);
-}
-
 /* Called with no lock taken.  */
 
 static int blk_mig_save_bulked_block(QEMUFile *f)
diff --git a/block.c b/block.c
index 5708c7c..2fd689a 100644
--- a/block.c
+++ b/block.c
@@ -3893,15 +3893,6 @@ BlockDriverState *bdrv_next(BlockDriverState *bs)
 return QTAILQ_NEXT(bs, device_list);
 }
 
-void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs), void *opaque)
-{
-BlockDriverState *bs;
-
-QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
-it(opaque, bs);
-}
-}
-
 const char *bdrv_get_device_name(BlockDriverState *bs)
 {
 return bs->device_name;
diff --git a/blockdev.c b/blockdev.c
index 3a6fd46..85f574b 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2527,26 +2527,21 @@ fail:
 qmp_output_visitor_cleanup(ov);
 }
 
-static void do_qmp_query_block_jobs_one(void *opaque, BlockDriverState *bs)
-{
-BlockJobInfoList **prev = opaque;
-BlockJob *job = bs->job;
-
-if (job) {
-BlockJobInfoList *elem = g_new0(BlockJobInfoList, 1);
-elem->value = block_job_query(bs->job);
-(*prev)->next = elem;
-*prev = elem;
-}
-}
-
 BlockJobInfoList *qmp_query_block_jobs(Error **errp)
 {
-/* Dummy is a fake list element for holding the head pointer */
-BlockJobInfoList dummy = {};
-BlockJobInfoList *prev = &dummy;
-bdrv_iterate(do_qmp_query_block_jobs_one, &prev);
-return dummy.next;
+BlockJobInfoList *head = NULL, **p_next = &head;
+BlockDriverState *bs;
+
+for (bs = bdrv_next(NULL); bs; bs = bdrv_next(bs)) {
+if (bs->job) {
+BlockJobInfoList *elem = g_new0(BlockJobInfoList, 1);
+elem->value = block_job_query(bs->job);
+*p_next = elem;
+p_next = &elem->next;
+}
+}
+
+return head;
 }
 
 QemuOptsList qemu_common_drive_opts = {
diff --git a/include/block/block.h b/include/block/block.h
index 6cabc98..c092eab 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -409,8 +409,6 @@ BlockDriverState *bdrv_lookup_bs(const char *device,
  Error **errp);
 bool bdrv_chain_contains(BlockDriverState *top, BlockDriverState *base);
 BlockDriverState *bdrv_next(BlockDriverState *bs);
-void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs),
-  void *opaque);
 int bdrv_is_encrypted(BlockDriverState *bs);
 int bdrv_key_required(BlockDriverState *bs);
 int bdrv_set_key(BlockDriverState *bs, const char *key);
diff --git a/monitor.c b/monitor.c
index 34cee74..565d60e 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4208,24 +4208,6 @@ static void file_completion(Monitor *mon, const char 
*input)
 closedir(ffs);
 }
 
-typedef struct MonitorBlockComplete {
-Monitor *mon;
-const char *input;
-} MonitorBlockComplete;
-
-static void block_completion_it(void *opaque, BlockDriverState *bs)
-{
-const char *name = bdrv_get_device_name(bs);
-MonitorBlockComplete *mbc = opaque;
-Monitor *mon = mbc->mon;
-const char *input = mbc->input;
-
-if (input[0] == '\0' ||
-!strncmp(name, (char *)input, strlen(input))) {
-readline_add_completion(mon->rs, name);
-}
-}
-
 static const char *next_arg_type(const char *typestr

[Qemu-devel] [PATCH v2 01/23] block: Split bdrv_new_root() off bdrv_new()

2014-09-13 Thread Markus Armbruster
Creating an anonymous BDS can't fail.  Make that obvious.

Signed-off-by: Markus Armbruster 
---
 block.c   | 28 +++-
 block/iscsi.c |  2 +-
 block/vvfat.c |  2 +-
 blockdev.c|  2 +-
 hw/block/xen_disk.c   |  2 +-
 include/block/block.h |  3 ++-
 qemu-img.c|  6 +++---
 qemu-io.c |  2 +-
 qemu-nbd.c|  2 +-
 9 files changed, 30 insertions(+), 19 deletions(-)

diff --git a/block.c b/block.c
index 02ea90f..4fe3b62 100644
--- a/block.c
+++ b/block.c
@@ -336,10 +336,11 @@ void bdrv_register(BlockDriver *bdrv)
 }
 
 /* create a new block device (by default it is empty) */
-BlockDriverState *bdrv_new(const char *device_name, Error **errp)
+BlockDriverState *bdrv_new_root(const char *device_name, Error **errp)
 {
 BlockDriverState *bs;
-int i;
+
+assert(*device_name);
 
 if (bdrv_find(device_name)) {
 error_setg(errp, "Device with id '%s' already exists",
@@ -353,12 +354,21 @@ BlockDriverState *bdrv_new(const char *device_name, Error 
**errp)
 return NULL;
 }
 
+bs = bdrv_new();
+
+pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
+QTAILQ_INSERT_TAIL(&bdrv_states, bs, device_list);
+
+return bs;
+}
+
+BlockDriverState *bdrv_new(void)
+{
+BlockDriverState *bs;
+int i;
+
 bs = g_new0(BlockDriverState, 1);
 QLIST_INIT(&bs->dirty_bitmaps);
-pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
-if (device_name[0] != '\0') {
-QTAILQ_INSERT_TAIL(&bdrv_states, bs, device_list);
-}
 for (i = 0; i < BLOCK_OP_TYPE_MAX; i++) {
 QLIST_INIT(&bs->op_blockers[i]);
 }
@@ -1219,7 +1229,7 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict 
*options, Error **errp)
 goto free_exit;
 }
 
-backing_hd = bdrv_new("", errp);
+backing_hd = bdrv_new();
 
 if (bs->backing_format[0] != '\0') {
 back_drv = bdrv_find_format(bs->backing_format);
@@ -1348,7 +1358,7 @@ int bdrv_append_temp_snapshot(BlockDriverState *bs, int 
flags, Error **errp)
 qdict_put(snapshot_options, "file.filename",
   qstring_from_str(tmp_filename));
 
-bs_snapshot = bdrv_new("", &error_abort);
+bs_snapshot = bdrv_new();
 
 ret = bdrv_open(&bs_snapshot, NULL, NULL, snapshot_options,
 flags, bdrv_qcow2, &local_err);
@@ -1419,7 +1429,7 @@ int bdrv_open(BlockDriverState **pbs, const char 
*filename,
 if (*pbs) {
 bs = *pbs;
 } else {
-bs = bdrv_new("", &error_abort);
+bs = bdrv_new();
 }
 
 /* NULL means an empty set of options */
diff --git a/block/iscsi.c b/block/iscsi.c
index 3e19202..af3d0f6 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -1528,7 +1528,7 @@ static int iscsi_create(const char *filename, QemuOpts 
*opts, Error **errp)
 IscsiLun *iscsilun = NULL;
 QDict *bs_options;
 
-bs = bdrv_new("", &error_abort);
+bs = bdrv_new();
 
 /* Read out options */
 total_size =
diff --git a/block/vvfat.c b/block/vvfat.c
index 731e591..6c9fde0 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -2939,7 +2939,7 @@ static int enable_write_target(BDRVVVFATState *s, Error 
**errp)
 unlink(s->qcow_filename);
 #endif
 
-bdrv_set_backing_hd(s->bs, bdrv_new("", &error_abort));
+bdrv_set_backing_hd(s->bs, bdrv_new());
 s->bs->backing_hd->drv = &vvfat_write_target;
 s->bs->backing_hd->opaque = g_new(void *, 1);
 *(void**)s->bs->backing_hd->opaque = s;
diff --git a/blockdev.c b/blockdev.c
index 450f95c..c9463e3 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -463,7 +463,7 @@ static DriveInfo *blockdev_init(const char *file, QDict 
*bs_opts,
 }
 
 /* init */
-bs = bdrv_new(qemu_opts_id(opts), errp);
+bs = bdrv_new_root(qemu_opts_id(opts), errp);
 if (!bs) {
 goto early_err;
 }
diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
index 2dcef07..71f0953 100644
--- a/hw/block/xen_disk.c
+++ b/hw/block/xen_disk.c
@@ -856,7 +856,7 @@ static int blk_connect(struct XenDevice *xendev)
 
 /* setup via xenbus -> create new block driver instance */
 xen_be_printf(&blkdev->xendev, 2, "create new bdrv (xenbus setup)\n");
-blkdev->bs = bdrv_new(blkdev->dev, NULL);
+blkdev->bs = bdrv_new_root(blkdev->dev, NULL);
 if (!blkdev->bs) {
 return -1;
 }
diff --git a/include/block/block.h b/include/block/block.h
index 8f4ad16..6cabc98 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -203,7 +203,8 @@ BlockDriver *bdrv_find_whitelisted_format(const char 
*format_name,
 int bdrv_create(BlockDriver *drv, const char* filename,
 QemuOpts *opts, Error **errp);
 int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp);
-BlockDriverState *bdrv_new(const char *device_name, Error **errp);
+BlockDriverState *bdrv_new_root(const char *device_name, Error **errp);
+BlockDriverState *bdrv_new(void

[Qemu-devel] [PATCH v2 12/23] virtio-blk: Drop redundant VirtIOBlock member conf

2014-09-13 Thread Markus Armbruster
Commit 12c5674 turned it into a pointer to member blk.conf.

Signed-off-by: Markus Armbruster 
---
 hw/block/virtio-blk.c  | 28 ++--
 include/hw/virtio/virtio-blk.h |  1 -
 2 files changed, 14 insertions(+), 15 deletions(-)

diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index a7f2827..0be7203 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -297,7 +297,7 @@ static bool virtio_blk_sect_range_ok(VirtIOBlock *dev,
 if (sector & dev->sector_mask) {
 return false;
 }
-if (size % dev->conf->logical_block_size) {
+if (size % dev->blk.conf.logical_block_size) {
 return false;
 }
 bdrv_get_geometry(dev->bs, &total_sectors);
@@ -516,19 +516,20 @@ static void virtio_blk_reset(VirtIODevice *vdev)
 static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
 {
 VirtIOBlock *s = VIRTIO_BLK(vdev);
+BlockConf *conf = &s->blk.conf;
 struct virtio_blk_config blkcfg;
 uint64_t capacity;
-int blk_size = s->conf->logical_block_size;
+int blk_size = conf->logical_block_size;
 
 bdrv_get_geometry(s->bs, &capacity);
 memset(&blkcfg, 0, sizeof(blkcfg));
 virtio_stq_p(vdev, &blkcfg.capacity, capacity);
 virtio_stl_p(vdev, &blkcfg.seg_max, 128 - 2);
-virtio_stw_p(vdev, &blkcfg.cylinders, s->conf->cyls);
+virtio_stw_p(vdev, &blkcfg.cylinders, conf->cyls);
 virtio_stl_p(vdev, &blkcfg.blk_size, blk_size);
-virtio_stw_p(vdev, &blkcfg.min_io_size, s->conf->min_io_size / blk_size);
-virtio_stw_p(vdev, &blkcfg.opt_io_size, s->conf->opt_io_size / blk_size);
-blkcfg.heads = s->conf->heads;
+virtio_stw_p(vdev, &blkcfg.min_io_size, conf->min_io_size / blk_size);
+virtio_stw_p(vdev, &blkcfg.opt_io_size, conf->opt_io_size / blk_size);
+blkcfg.heads = conf->heads;
 /*
  * We must ensure that the block device capacity is a multiple of
  * the logical block size. If that is not the case, let's use
@@ -540,13 +541,13 @@ static void virtio_blk_update_config(VirtIODevice *vdev, 
uint8_t *config)
  * divided by 512 - instead it is the amount of blk_size blocks
  * per track (cylinder).
  */
-if (bdrv_getlength(s->bs) /  s->conf->heads / s->conf->secs % blk_size) {
-blkcfg.sectors = s->conf->secs & ~s->sector_mask;
+if (bdrv_getlength(s->bs) /  conf->heads / conf->secs % blk_size) {
+blkcfg.sectors = conf->secs & ~s->sector_mask;
 } else {
-blkcfg.sectors = s->conf->secs;
+blkcfg.sectors = conf->secs;
 }
 blkcfg.size_max = 0;
-blkcfg.physical_block_exp = get_physical_block_exp(s->conf);
+blkcfg.physical_block_exp = get_physical_block_exp(&s->blk.conf);
 blkcfg.alignment_offset = 0;
 blkcfg.wce = bdrv_enable_write_cache(s->bs);
 memcpy(config, &blkcfg, sizeof(struct virtio_blk_config));
@@ -753,9 +754,8 @@ static void virtio_blk_device_realize(DeviceState *dev, 
Error **errp)
 sizeof(struct virtio_blk_config));
 
 s->bs = blk->conf.bs;
-s->conf = &blk->conf;
 s->rq = NULL;
-s->sector_mask = (s->conf->logical_block_size / BDRV_SECTOR_SIZE) - 1;
+s->sector_mask = (s->blk.conf.logical_block_size / BDRV_SECTOR_SIZE) - 1;
 
 s->vq = virtio_add_queue(vdev, 128, virtio_blk_handle_output);
 s->complete_request = virtio_blk_complete_request;
@@ -774,11 +774,11 @@ static void virtio_blk_device_realize(DeviceState *dev, 
Error **errp)
 register_savevm(dev, "virtio-blk", virtio_blk_id++, 2,
 virtio_blk_save, virtio_blk_load, s);
 bdrv_set_dev_ops(s->bs, &virtio_block_ops, s);
-bdrv_set_guest_block_size(s->bs, s->conf->logical_block_size);
+bdrv_set_guest_block_size(s->bs, s->blk.conf.logical_block_size);
 
 bdrv_iostatus_enable(s->bs);
 
-add_boot_device_path(s->conf->bootindex, dev, "/disk@0,0");
+add_boot_device_path(s->blk.conf.bootindex, dev, "/disk@0,0");
 }
 
 static void virtio_blk_device_unrealize(DeviceState *dev, Error **errp)
diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h
index afb7b8d..1329482 100644
--- a/include/hw/virtio/virtio-blk.h
+++ b/include/hw/virtio/virtio-blk.h
@@ -124,7 +124,6 @@ typedef struct VirtIOBlock {
 VirtQueue *vq;
 void *rq;
 QEMUBH *bh;
-BlockConf *conf;
 VirtIOBlkConf blk;
 unsigned short sector_mask;
 bool original_wce;
-- 
1.9.3




[Qemu-devel] [PATCH v2 08/23] block: Eliminate BlockDriverState member device_name[]

2014-09-13 Thread Markus Armbruster
device_name[] can become non-empty only in bdrv_new_root() and
bdrv_move_feature_fields().  The latter is used only to undo damage
done by bdrv_swap().  The former is called only by blk_new_with_bs().
Therefore, when a BlockDriverState's device_name[] is non-empty, then
it's been created with a BlockBackend, and vice versa.  Furthermore,
blk_new_with_bs() keeps the two names equal.

Therefore, device_name[] is redundant.  Eliminate it.

Signed-off-by: Markus Armbruster 
---
 block-migration.c | 12 +
 block.c   | 63 +--
 block/block-backend.c | 14 ++-
 block/cow.c   |  2 +-
 block/mirror.c|  3 ++-
 block/qapi.c  |  6 ++---
 block/qcow.c  |  4 +--
 block/qcow2.c |  4 +--
 block/qed.c   |  2 +-
 block/quorum.c|  4 +--
 block/vdi.c   |  2 +-
 block/vhdx.c  |  2 +-
 block/vmdk.c  |  4 +--
 block/vpc.c   |  2 +-
 block/vvfat.c |  2 +-
 blockjob.c|  3 ++-
 include/block/block.h |  4 +--
 include/block/block_int.h |  2 --
 18 files changed, 60 insertions(+), 75 deletions(-)

diff --git a/block-migration.c b/block-migration.c
index cb3e16c..da30e93 100644
--- a/block-migration.c
+++ b/block-migration.c
@@ -14,7 +14,9 @@
  */
 
 #include "qemu-common.h"
-#include "block/block_int.h"
+#include "block/block.h"
+#include "qemu/error-report.h"
+#include "qemu/main-loop.h"
 #include "hw/hw.h"
 #include "qemu/queue.h"
 #include "qemu/timer.h"
@@ -130,9 +132,9 @@ static void blk_send(QEMUFile *f, BlkMigBlock * blk)
  | flags);
 
 /* device name */
-len = strlen(blk->bmds->bs->device_name);
+len = strlen(bdrv_get_device_name(blk->bmds->bs));
 qemu_put_byte(f, len);
-qemu_put_buffer(f, (uint8_t *)blk->bmds->bs->device_name, len);
+qemu_put_buffer(f, (uint8_t *)bdrv_get_device_name(blk->bmds->bs), len);
 
 /* if a block is zero we need to flush here since the network
  * bandwidth is now a lot higher than the storage device bandwidth.
@@ -382,9 +384,9 @@ static void init_blk_migration(QEMUFile *f)
 
 if (bmds->shared_base) {
 DPRINTF("Start migration for %s with shared base image\n",
-bs->device_name);
+bdrv_get_device_name(bs));
 } else {
-DPRINTF("Start full migration for %s\n", bs->device_name);
+DPRINTF("Start full migration for %s\n", bdrv_get_device_name(bs));
 }
 
 QSIMPLEQ_INSERT_TAIL(&block_mig_state.bmds_list, bmds, entry);
diff --git a/block.c b/block.c
index 2fd689a..b39e368 100644
--- a/block.c
+++ b/block.c
@@ -28,6 +28,7 @@
 #include "block/blockjob.h"
 #include "qemu/module.h"
 #include "qapi/qmp/qjson.h"
+#include "sysemu/block-backend.h"
 #include "sysemu/sysemu.h"
 #include "qemu/notify.h"
 #include "block/coroutine.h"
@@ -334,30 +335,11 @@ void bdrv_register(BlockDriver *bdrv)
 QLIST_INSERT_HEAD(&bdrv_drivers, bdrv, list);
 }
 
-/* create a new block device (by default it is empty) */
-BlockDriverState *bdrv_new_root(const char *device_name, Error **errp)
+BlockDriverState *bdrv_new_root(void)
 {
-BlockDriverState *bs;
+BlockDriverState *bs = bdrv_new();
 
-assert(*device_name);
-
-if (bdrv_find(device_name)) {
-error_setg(errp, "Device with id '%s' already exists",
-   device_name);
-return NULL;
-}
-if (bdrv_find_node(device_name)) {
-error_setg(errp,
-   "Device name '%s' conflicts with an existing node name",
-   device_name);
-return NULL;
-}
-
-bs = bdrv_new();
-
-pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
 QTAILQ_INSERT_TAIL(&bdrv_states, bs, device_list);
-
 return bs;
 }
 
@@ -1163,7 +1145,7 @@ void bdrv_set_backing_hd(BlockDriverState *bs, 
BlockDriverState *backing_hd)
 } else if (backing_hd) {
 error_setg(&bs->backing_blocker,
"device is used as backing hd of '%s'",
-   bs->device_name);
+   bdrv_get_device_name(bs));
 }
 
 bs->backing_hd = backing_hd;
@@ -1537,7 +1519,7 @@ int bdrv_open(BlockDriverState **pbs, const char 
*filename,
 } else {
 error_setg(errp, "Block format '%s' used by device '%s' doesn't "
"support the option '%s'", drv->format_name,
-   bs->device_name, entry->key);
+   bdrv_get_device_name(bs), entry->key);
 }
 
 ret = -EINVAL;
@@ -1744,7 +1726,7 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, 
BlockReopenQueue *queue,
 if (!(reopen_state->bs->open_flags & BDRV_O_ALLOW_RDWR) &&
 reopen_state->flags & BDRV_O_RDWR) {
 error_set(errp, QERR_DEVICE_IS_READ_ONLY,
-  reopen_state->bs->device_name);
+

[Qemu-devel] [PATCH v2 13/23] virtio-blk: Rename VirtIOBlkConf variables to conf

2014-09-13 Thread Markus Armbruster
This is consistent with how VirtIOFOOConf variables are named
elsewhere, and makes blk available for BlockBackend variables.

Signed-off-by: Markus Armbruster 
---
 hw/block/dataplane/virtio-blk.c | 33 +-
 hw/block/dataplane/virtio-blk.h |  2 +-
 hw/block/virtio-blk.c   | 52 -
 include/hw/virtio/virtio-blk.h  |  2 +-
 4 files changed, 45 insertions(+), 44 deletions(-)

diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
index b55188c..af67dc3 100644
--- a/hw/block/dataplane/virtio-blk.c
+++ b/hw/block/dataplane/virtio-blk.c
@@ -30,7 +30,7 @@ struct VirtIOBlockDataPlane {
 bool stopping;
 bool disabled;
 
-VirtIOBlkConf *blk;
+VirtIOBlkConf *conf;
 
 VirtIODevice *vdev;
 Vring vring;/* virtqueue vring */
@@ -94,7 +94,7 @@ static void handle_notify(EventNotifier *e)
 VirtIOBlock *vblk = VIRTIO_BLK(s->vdev);
 
 event_notifier_test_and_clear(&s->host_notifier);
-bdrv_io_plug(s->blk->conf.bs);
+bdrv_io_plug(s->conf->conf.bs);
 for (;;) {
 MultiReqBuffer mrb = {
 .num_writes = 0,
@@ -120,7 +120,7 @@ static void handle_notify(EventNotifier *e)
 virtio_blk_handle_request(req, &mrb);
 }
 
-virtio_submit_multiwrite(s->blk->conf.bs, &mrb);
+virtio_submit_multiwrite(s->conf->conf.bs, &mrb);
 
 if (likely(ret == -EAGAIN)) { /* vring emptied */
 /* Re-enable guest->host notifies and stop processing the vring.
@@ -133,11 +133,11 @@ static void handle_notify(EventNotifier *e)
 break;
 }
 }
-bdrv_io_unplug(s->blk->conf.bs);
+bdrv_io_unplug(s->conf->conf.bs);
 }
 
 /* Context: QEMU global mutex held */
-void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *blk,
+void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf,
   VirtIOBlockDataPlane **dataplane,
   Error **errp)
 {
@@ -148,7 +148,7 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, 
VirtIOBlkConf *blk,
 
 *dataplane = NULL;
 
-if (!blk->data_plane && !blk->iothread) {
+if (!conf->data_plane && !conf->iothread) {
 return;
 }
 
@@ -163,7 +163,8 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, 
VirtIOBlkConf *blk,
 /* If dataplane is (re-)enabled while the guest is running there could be
  * block jobs that can conflict.
  */
-if (bdrv_op_is_blocked(blk->conf.bs, BLOCK_OP_TYPE_DATAPLANE, &local_err)) 
{
+if (bdrv_op_is_blocked(conf->conf.bs, BLOCK_OP_TYPE_DATAPLANE,
+   &local_err)) {
 error_report("cannot start dataplane thread: %s",
   error_get_pretty(local_err));
 error_free(local_err);
@@ -172,10 +173,10 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, 
VirtIOBlkConf *blk,
 
 s = g_new0(VirtIOBlockDataPlane, 1);
 s->vdev = vdev;
-s->blk = blk;
+s->conf = conf;
 
-if (blk->iothread) {
-s->iothread = blk->iothread;
+if (conf->iothread) {
+s->iothread = conf->iothread;
 object_ref(OBJECT(s->iothread));
 } else {
 /* Create per-device IOThread if none specified.  This is for
@@ -192,9 +193,9 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, 
VirtIOBlkConf *blk,
 s->bh = aio_bh_new(s->ctx, notify_guest_bh, s);
 
 error_setg(&s->blocker, "block device is in use by data plane");
-bdrv_op_block_all(blk->conf.bs, s->blocker);
-bdrv_op_unblock(blk->conf.bs, BLOCK_OP_TYPE_RESIZE, s->blocker);
-bdrv_op_unblock(blk->conf.bs, BLOCK_OP_TYPE_DRIVE_DEL, s->blocker);
+bdrv_op_block_all(conf->conf.bs, s->blocker);
+bdrv_op_unblock(conf->conf.bs, BLOCK_OP_TYPE_RESIZE, s->blocker);
+bdrv_op_unblock(conf->conf.bs, BLOCK_OP_TYPE_DRIVE_DEL, s->blocker);
 
 *dataplane = s;
 }
@@ -207,7 +208,7 @@ void virtio_blk_data_plane_destroy(VirtIOBlockDataPlane *s)
 }
 
 virtio_blk_data_plane_stop(s);
-bdrv_op_unblock_all(s->blk->conf.bs, s->blocker);
+bdrv_op_unblock_all(s->conf->conf.bs, s->blocker);
 error_free(s->blocker);
 object_unref(OBJECT(s->iothread));
 qemu_bh_delete(s->bh);
@@ -262,7 +263,7 @@ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
 s->started = true;
 trace_virtio_blk_data_plane_start(s);
 
-bdrv_set_aio_context(s->blk->conf.bs, s->ctx);
+bdrv_set_aio_context(s->conf->conf.bs, s->ctx);
 
 /* Kick right away to begin processing requests already in vring */
 event_notifier_set(virtio_queue_get_host_notifier(vq));
@@ -308,7 +309,7 @@ void virtio_blk_data_plane_stop(VirtIOBlockDataPlane *s)
 aio_set_event_notifier(s->ctx, &s->host_notifier, NULL);
 
 /* Drain and switch bs back to the QEMU main loop */
-bdrv_set_aio_context(s->blk->conf.bs, qemu_get_aio_context());
+bdrv_set_aio_context(s->conf->conf.bs, qemu_get_aio_c

[Qemu-devel] [PATCH v2 03/23] block: Connect BlockBackend to BlockDriverState

2014-09-13 Thread Markus Armbruster
The pointer from BlockBackend to BlockDriverState is a strong
reference, managed with bdrv_ref() / bdrv_unref(), the back-pointer is
a weak one.

Convenience function blk_new_with_bs() creates a BlockBackend with its
BlockDriverState.  Callers have to unref both.  The commit after next
will relieve them of the need to unref the BlockDriverState.

Complication: due to the silly way drive_del works, we need a way to
hide a BlockBackend, just like bdrv_make_anon().  To emphasize its
"special" status, give the function a suitably off-putting name:
blk_hide_on_behalf_of_do_drive_del().  Unfortunately, hiding turns the
BlockBackend's name into the empty string.  Can't avoid that without
breaking the blk->bs->device_name equals blk->name invariant.

Signed-off-by: Markus Armbruster 
---
 block.c|  10 ++--
 block/block-backend.c  |  70 ++-
 blockdev.c |  26 +++--
 hw/block/xen_disk.c|   8 +--
 include/block/block_int.h  |   2 +
 include/sysemu/block-backend.h |   5 ++
 qemu-img.c | 125 +++--
 qemu-io.c  |   4 +-
 qemu-nbd.c |   2 +-
 9 files changed, 152 insertions(+), 100 deletions(-)

diff --git a/block.c b/block.c
index a05d0e3..92f84d2 100644
--- a/block.c
+++ b/block.c
@@ -2032,7 +2032,7 @@ static void bdrv_move_feature_fields(BlockDriverState 
*bs_dest,
  * This will modify the BlockDriverState fields, and swap contents
  * between bs_new and bs_old. Both bs_new and bs_old are modified.
  *
- * bs_new is required to be anonymous.
+ * bs_new must be nameless and not attached to a BlockBackend.
  *
  * This function does not create any image files.
  */
@@ -2051,8 +2051,9 @@ void bdrv_swap(BlockDriverState *bs_new, BlockDriverState 
*bs_old)
 QTAILQ_REMOVE(&graph_bdrv_states, bs_old, node_list);
 }
 
-/* bs_new must be anonymous and shouldn't have anything fancy enabled */
+/* bs_new must be nameless and shouldn't have anything fancy enabled */
 assert(bs_new->device_name[0] == '\0');
+assert(!bs_new->blk);
 assert(QLIST_EMPTY(&bs_new->dirty_bitmaps));
 assert(bs_new->job == NULL);
 assert(bs_new->dev == NULL);
@@ -2068,8 +2069,9 @@ void bdrv_swap(BlockDriverState *bs_new, BlockDriverState 
*bs_old)
 bdrv_move_feature_fields(bs_old, bs_new);
 bdrv_move_feature_fields(bs_new, &tmp);
 
-/* bs_new shouldn't be in bdrv_states even after the swap!  */
+/* bs_new must remain nameless and unattached */
 assert(bs_new->device_name[0] == '\0');
+assert(!bs_new->blk);
 
 /* Check a few fields that should remain attached to the device */
 assert(bs_new->dev == NULL);
@@ -2096,7 +2098,7 @@ void bdrv_swap(BlockDriverState *bs_new, BlockDriverState 
*bs_old)
  * This will modify the BlockDriverState fields, and swap contents
  * between bs_new and bs_top. Both bs_new and bs_top are modified.
  *
- * bs_new is required to be anonymous.
+ * bs_new must be nameless and not attached to a BlockBackend.
  *
  * This function does not create any image files.
  */
diff --git a/block/block-backend.c b/block/block-backend.c
index 919dd4c..b118b38 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -16,10 +16,11 @@
 struct BlockBackend {
 char *name;
 int refcnt;
+BlockDriverState *bs;
 QTAILQ_ENTRY(BlockBackend) link; /* for blk_backends */
 };
 
-/* All the BlockBackends */
+/* All the BlockBackends (except for hidden ones) */
 static QTAILQ_HEAD(, BlockBackend) blk_backends =
 QTAILQ_HEAD_INITIALIZER(blk_backends);
 
@@ -47,10 +48,43 @@ BlockBackend *blk_new(const char *name, Error **errp)
 return blk;
 }
 
+/*
+ * Create a new BlockBackend with a new BlockDriverState attached.
+ * Both have a reference count of one.  Caller owns *both* references.
+ * TODO Let caller own only the BlockBackend reference
+ * Otherwise just like blk_new(), which see.
+ */
+BlockBackend *blk_new_with_bs(const char *name, Error **errp)
+{
+BlockBackend *blk;
+BlockDriverState *bs;
+
+blk = blk_new(name, errp);
+if (!blk) {
+return NULL;
+}
+
+bs = bdrv_new_root(name, errp);
+if (!bs) {
+blk_unref(blk);
+return NULL;
+}
+
+blk->bs = bs;
+bs->blk = blk;
+return blk;
+}
+
 static void blk_delete(BlockBackend *blk)
 {
 assert(!blk->refcnt);
-QTAILQ_REMOVE(&blk_backends, blk, link);
+if (blk->bs) {
+blk->bs->blk = NULL;
+blk->bs = NULL;
+}
+if (blk->name[0]) {
+QTAILQ_REMOVE(&blk_backends, blk, link);
+}
 g_free(blk->name);
 g_free(blk);
 }
@@ -68,6 +102,8 @@ void blk_ref(BlockBackend *blk)
  * Decrement @blk's reference count.
  * If this drops it to zero, destroy @blk.
  * For convenience, do nothing if @blk is null.
+ * Does *not* touch the attached BlockDriverState's reference count.
+ * TODO Decrement it!
  */
 void blk_unref(BlockBackend

[Qemu-devel] [PATCH v2 04/23] block: Connect BlockBackend and DriveInfo

2014-09-13 Thread Markus Armbruster
Make the BlockBackend own the DriveInfo.  Change blockdev_init() to
return the BlockBackend instead of the DriveInfo.

Signed-off-by: Markus Armbruster 
---
 block.c   |  3 --
 block/block-backend.c | 38 
 blockdev.c| 73 ---
 include/sysemu/blockdev.h |  4 +++
 4 files changed, 79 insertions(+), 39 deletions(-)

diff --git a/block.c b/block.c
index 92f84d2..5708c7c 100644
--- a/block.c
+++ b/block.c
@@ -29,7 +29,6 @@
 #include "qemu/module.h"
 #include "qapi/qmp/qjson.h"
 #include "sysemu/sysemu.h"
-#include "sysemu/blockdev.h"/* FIXME layering violation */
 #include "qemu/notify.h"
 #include "block/coroutine.h"
 #include "block/qapi.h"
@@ -2121,8 +2120,6 @@ static void bdrv_delete(BlockDriverState *bs)
 
 bdrv_close(bs);
 
-drive_info_del(drive_get_by_blockdev(bs));
-
 /* remove from list, if necessary */
 bdrv_make_anon(bs);
 
diff --git a/block/block-backend.c b/block/block-backend.c
index b118b38..7b8c062 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -12,11 +12,13 @@
 
 #include "sysemu/block-backend.h"
 #include "block/block_int.h"
+#include "sysemu/blockdev.h"
 
 struct BlockBackend {
 char *name;
 int refcnt;
 BlockDriverState *bs;
+DriveInfo *legacy_dinfo;
 QTAILQ_ENTRY(BlockBackend) link; /* for blk_backends */
 };
 
@@ -86,6 +88,7 @@ static void blk_delete(BlockBackend *blk)
 QTAILQ_REMOVE(&blk_backends, blk, link);
 }
 g_free(blk->name);
+drive_info_del(blk->legacy_dinfo);
 g_free(blk);
 }
 
@@ -165,6 +168,41 @@ BlockDriverState *blk_bs(BlockBackend *blk)
 }
 
 /*
+ * Return @blk's DriveInfo if any, else null.
+ */
+DriveInfo *blk_legacy_dinfo(BlockBackend *blk)
+{
+return blk->legacy_dinfo;
+}
+
+/*
+ * Set @blk's DriveInfo to @dinfo, and return it.
+ * @blk must not have a DriveInfo set already.
+ * No other BlockBackend may have the same DriveInfo set.
+ */
+DriveInfo *blk_set_legacy_dinfo(BlockBackend *blk, DriveInfo *dinfo)
+{
+assert(!blk->legacy_dinfo);
+return blk->legacy_dinfo = dinfo;
+}
+
+/*
+ * Return the BlockBackend with DriveInfo @dinfo.
+ * It must exist.
+ */
+BlockBackend *blk_by_legacy_dinfo(DriveInfo *dinfo)
+{
+BlockBackend *blk;
+
+QTAILQ_FOREACH(blk, &blk_backends, link) {
+if (blk->legacy_dinfo == dinfo) {
+return blk;
+}
+}
+assert(0);
+}
+
+/*
  * Hide @blk.
  * @blk must not have been hidden already.
  * Make attached BlockDriverState, if any, anonymous.
diff --git a/blockdev.c b/blockdev.c
index 21f4c67..aec9f0e 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -47,8 +47,6 @@
 #include "trace.h"
 #include "sysemu/arch_init.h"
 
-static QTAILQ_HEAD(drivelist, DriveInfo) drives = 
QTAILQ_HEAD_INITIALIZER(drives);
-
 static const char *const if_name[IF_COUNT] = {
 [IF_NONE] = "none",
 [IF_IDE] = "ide",
@@ -89,7 +87,8 @@ static const int if_max_devs[IF_COUNT] = {
  */
 void blockdev_mark_auto_del(BlockDriverState *bs)
 {
-DriveInfo *dinfo = drive_get_by_blockdev(bs);
+BlockBackend *blk = bs->blk;
+DriveInfo *dinfo = blk_legacy_dinfo(blk);
 
 if (dinfo && !dinfo->enable_auto_del) {
 return;
@@ -105,7 +104,8 @@ void blockdev_mark_auto_del(BlockDriverState *bs)
 
 void blockdev_auto_del(BlockDriverState *bs)
 {
-DriveInfo *dinfo = drive_get_by_blockdev(bs);
+BlockBackend *blk = bs->blk;
+DriveInfo *dinfo = blk_legacy_dinfo(blk);
 
 if (dinfo && dinfo->auto_del) {
 drive_del(dinfo);
@@ -153,15 +153,15 @@ QemuOpts *drive_add(BlockInterfaceType type, int index, 
const char *file,
 
 DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit)
 {
+BlockBackend *blk;
 DriveInfo *dinfo;
 
-/* seek interface, bus and unit */
-
-QTAILQ_FOREACH(dinfo, &drives, next) {
-if (dinfo->type == type &&
-   dinfo->bus == bus &&
-   dinfo->unit == unit)
+for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
+dinfo = blk_legacy_dinfo(blk);
+if (dinfo && dinfo->type == type
+&& dinfo->bus == bus && dinfo->unit == unit) {
 return dinfo;
+}
 }
 
 return NULL;
@@ -177,13 +177,15 @@ DriveInfo *drive_get_by_index(BlockInterfaceType type, 
int index)
 int drive_get_max_bus(BlockInterfaceType type)
 {
 int max_bus;
+BlockBackend *blk;
 DriveInfo *dinfo;
 
 max_bus = -1;
-QTAILQ_FOREACH(dinfo, &drives, next) {
-if(dinfo->type == type &&
-   dinfo->bus > max_bus)
+for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
+dinfo = blk_legacy_dinfo(blk);
+if (dinfo && dinfo->type == type && dinfo->bus > max_bus) {
 max_bus = dinfo->bus;
+}
 }
 return max_bus;
 }
@@ -200,11 +202,11 @@ DriveInfo *drive_get_next(BlockInterfaceType type)
 
 DriveInfo *drive_get_by_blockdev(BlockDriverState *bs)
 {
-DriveInfo *dinfo;
+BlockBackend

[Qemu-devel] [PATCH v2 02/23] block: New BlockBackend

2014-09-13 Thread Markus Armbruster
A block device consists of a frontend device model and a backend.

A block backend has a tree of block drivers doing the actual work.
The tree is managed by the block layer.

We currently use a single abstraction BlockDriverState both for tree
nodes and the backend as a whole.  Drawbacks:

* Its API includes both stuff that makes sense only at the block
  backend level (root of the tree) and stuff that's only for use
  within the block layer.  This makes the API bigger and more complex
  than necessary.  Moreover, it's not obvious which interfaces are
  meant for device models, and which really aren't.

* Since device models keep a reference to their backend, the backend
  object can't just be destroyed.  But for media change, we need to
  replace the tree.  Our solution is to make the BlockDriverState
  generic, with actual driver state in a separate object, pointed to
  by member opaque.  That lets us replace the tree by deinitializing
  and reinitializing its root.  This special need of the root makes
  the data structure awkward everywhere in the tree.

The general plan is to separate the APIs into "block backend", for use
by device models, monitor and whatever other code dealing with block
backends, and "block driver", for use by the block layer and whatever
other code (if any) dealing with trees and tree nodes.

Code dealing with block backends, device models in particular, should
become completely oblivious of BlockDriverState.  This should let us
clean up both APIs, and the tree data structures.

This commit is a first step.  It creates a minimal "block backend"
API: type BlockBackend and functions to create, destroy and find them.

BlockBackend objects are created and destroyed exactly when root
BlockDriverState objects are created and destroyed.  "Root" in the
sense of "in bdrv_states".  They're not yet used for anything; that'll
come shortly.

BlockBackend is reference-counted.  Its reference count never exceeds
one so far, but that's going to change.

Signed-off-by: Markus Armbruster 
---
 block.c|   3 +-
 block/Makefile.objs|   2 +-
 block/block-backend.c  | 119 +
 blockdev.c |  21 +++-
 hw/block/xen_disk.c|  11 
 include/qemu/typedefs.h|   1 +
 include/sysemu/block-backend.h |  26 +
 qemu-img.c |  70 +---
 qemu-io.c  |   8 +++
 qemu-nbd.c |   5 +-
 10 files changed, 253 insertions(+), 13 deletions(-)
 create mode 100644 block/block-backend.c
 create mode 100644 include/sysemu/block-backend.h

diff --git a/block.c b/block.c
index 4fe3b62..a05d0e3 100644
--- a/block.c
+++ b/block.c
@@ -2119,10 +2119,11 @@ static void bdrv_delete(BlockDriverState *bs)
 
 bdrv_close(bs);
 
+drive_info_del(drive_get_by_blockdev(bs));
+
 /* remove from list, if necessary */
 bdrv_make_anon(bs);
 
-drive_info_del(drive_get_by_blockdev(bs));
 g_free(bs);
 }
 
diff --git a/block/Makefile.objs b/block/Makefile.objs
index f45f939..a70140b 100644
--- a/block/Makefile.objs
+++ b/block/Makefile.objs
@@ -5,7 +5,7 @@ block-obj-y += qed-check.o
 block-obj-$(CONFIG_VHDX) += vhdx.o vhdx-endian.o vhdx-log.o
 block-obj-$(CONFIG_QUORUM) += quorum.o
 block-obj-y += parallels.o blkdebug.o blkverify.o
-block-obj-y += snapshot.o qapi.o
+block-obj-y += block-backend.o snapshot.o qapi.o
 block-obj-$(CONFIG_WIN32) += raw-win32.o win32-aio.o
 block-obj-$(CONFIG_POSIX) += raw-posix.o
 block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
diff --git a/block/block-backend.c b/block/block-backend.c
new file mode 100644
index 000..919dd4c
--- /dev/null
+++ b/block/block-backend.c
@@ -0,0 +1,119 @@
+/*
+ * QEMU Block backends
+ *
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * Authors:
+ *  Markus Armbruster ,
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1
+ * or later.  See the COPYING.LIB file in the top-level directory.
+ */
+
+#include "sysemu/block-backend.h"
+#include "block/block_int.h"
+
+struct BlockBackend {
+char *name;
+int refcnt;
+QTAILQ_ENTRY(BlockBackend) link; /* for blk_backends */
+};
+
+/* All the BlockBackends */
+static QTAILQ_HEAD(, BlockBackend) blk_backends =
+QTAILQ_HEAD_INITIALIZER(blk_backends);
+
+/*
+ * Create a new BlockBackend with @name, with a reference count of one.
+ * @name must not be null or empty.
+ * Fail if a BlockBackend with this name already exists.
+ * Store an error through @errp on failure, unless it's null.
+ * Return the new BlockBackend on success, null on failure.
+ */
+BlockBackend *blk_new(const char *name, Error **errp)
+{
+BlockBackend *blk;
+
+assert(name && name[0]);
+if (blk_by_name(name)) {
+error_setg(errp, "Device with id '%s' already exists", name);
+return NULL;
+}
+
+blk = g_new0(BlockBackend, 1);
+blk->name = g_strdup(name);
+blk->refcnt = 1;
+QTAILQ_INSERT_

[Qemu-devel] [PATCH v2 09/23] block: Merge BlockBackend and BlockDriverState name spaces

2014-09-13 Thread Markus Armbruster
BlockBackend's name space is separate only to keep the initial patches
simple.  Time to merge the two.

Signed-off-by: Markus Armbruster 
---
 block.c   | 11 +++
 block/block-backend.c | 13 ++---
 2 files changed, 9 insertions(+), 15 deletions(-)

diff --git a/block.c b/block.c
index b39e368..f59dade 100644
--- a/block.c
+++ b/block.c
@@ -861,7 +861,7 @@ static void bdrv_assign_node_name(BlockDriverState *bs,
 }
 
 /* takes care of avoiding namespaces collisions */
-if (bdrv_find(node_name)) {
+if (blk_by_name(node_name)) {
 error_setg(errp, "node-name=%s is conflicting with a device id",
node_name);
 return;
@@ -3782,14 +3782,9 @@ void bdrv_iterate_format(void (*it)(void *opaque, const 
char *name),
 /* This function is to find block backend bs */
 BlockDriverState *bdrv_find(const char *name)
 {
-BlockDriverState *bs;
+BlockBackend *blk = blk_by_name(name);
 
-QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
-if (!strcmp(name, bdrv_get_device_name(bs))) {
-return bs;
-}
-}
-return NULL;
+return blk ? blk_bs(blk) : NULL;
 }
 
 /* This function is to find a node in the bs graph */
diff --git a/block/block-backend.c b/block/block-backend.c
index af23d71..17f05a3 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -44,6 +44,12 @@ BlockBackend *blk_new(const char *name, Error **errp)
 error_setg(errp, "Device with id '%s' already exists", name);
 return NULL;
 }
+if (bdrv_find_node(name)) {
+error_setg(errp,
+   "Device name '%s' conflicts with an existing node name",
+   name);
+return NULL;
+}
 
 blk = g_new0(BlockBackend, 1);
 blk->name = g_strdup(name);
@@ -61,13 +67,6 @@ BlockBackend *blk_new_with_bs(const char *name, Error **errp)
 BlockBackend *blk;
 BlockDriverState *bs;
 
-if (bdrv_find_node(name)) {
-error_setg(errp,
-   "Device name '%s' conflicts with an existing node name",
-   name);
-return NULL;
-}
-
 blk = blk_new(name, errp);
 if (!blk) {
 return NULL;
-- 
1.9.3




[Qemu-devel] [PATCH v6 1/6] generic function between migration and bitmap dump

2014-09-13 Thread Sanidhya Kashyap
Now, the counter variable is available to all the functions that will call
qemu_bitmap_sync_range. I have tried to make the function along with the
variables as generic as possible.

Signed-off-by: Sanidhya Kashyap 
---
 arch_init.c | 19 +++
 include/exec/ram_addr.h |  4 
 2 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/arch_init.c b/arch_init.c
index c974f3f..269c669 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -436,20 +436,22 @@ ram_addr_t 
migration_bitmap_find_and_reset_dirty(MemoryRegion *mr,
 return (next - base) << TARGET_PAGE_BITS;
 }
 
-static inline bool migration_bitmap_set_dirty(ram_addr_t addr)
+static inline bool qemu_bitmap_set_dirty(ram_addr_t addr, unsigned long 
*bitmap,
+ uint64_t *counter)
 {
 bool ret;
 int nr = addr >> TARGET_PAGE_BITS;
 
-ret = test_and_set_bit(nr, migration_bitmap);
+ret = test_and_set_bit(nr, bitmap);
 
 if (!ret) {
-migration_dirty_pages++;
+(*counter)++;
 }
 return ret;
 }
 
-static void migration_bitmap_sync_range(ram_addr_t start, ram_addr_t length)
+void qemu_bitmap_sync_range(ram_addr_t start, ram_addr_t length,
+unsigned long *bitmap, uint64_t *counter)
 {
 ram_addr_t addr;
 unsigned long page = BIT_WORD(start >> TARGET_PAGE_BITS);
@@ -463,8 +465,8 @@ static void migration_bitmap_sync_range(ram_addr_t start, 
ram_addr_t length)
 for (k = page; k < page + nr; k++) {
 if (src[k]) {
 unsigned long new_dirty;
-new_dirty = ~migration_bitmap[k];
-migration_bitmap[k] |= src[k];
+new_dirty = ~bitmap[k];
+bitmap[k] |= src[k];
 new_dirty &= src[k];
 migration_dirty_pages += ctpopl(new_dirty);
 src[k] = 0;
@@ -478,7 +480,7 @@ static void migration_bitmap_sync_range(ram_addr_t start, 
ram_addr_t length)
 cpu_physical_memory_reset_dirty(start + addr,
 TARGET_PAGE_SIZE,
 DIRTY_MEMORY_MIGRATION);
-migration_bitmap_set_dirty(start + addr);
+qemu_bitmap_set_dirty(start + addr, bitmap, counter);
 }
 }
 }
@@ -514,7 +516,8 @@ static void migration_bitmap_sync(void)
 address_space_sync_dirty_bitmap(&address_space_memory);
 
 QTAILQ_FOREACH(block, &ram_list.blocks, next) {
-migration_bitmap_sync_range(block->mr->ram_addr, block->length);
+qemu_bitmap_sync_range(block->mr->ram_addr, block->length,
+   migration_bitmap, &migration_dirty_pages);
 }
 trace_migration_bitmap_sync_end(migration_dirty_pages
 - num_dirty_pages_init);
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index 6593be1..fcc3501 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -162,5 +162,9 @@ static inline void 
cpu_physical_memory_clear_dirty_range(ram_addr_t start,
 void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t length,
  unsigned client);
 
+
+void qemu_bitmap_sync_range(ram_addr_t start, ram_addr_t length,
+unsigned long *bitmap, uint64_t *counter);
+
 #endif
 #endif
-- 
1.9.1




[Qemu-devel] [PATCH v6 6/6] BitmapLog: python script for extracting bitmap from a binary file

2014-09-13 Thread Sanidhya Kashyap
I have modified the script to support the dump of the images to the file. 
Earlier,
everything was saved to the memory and later the processing was taking place. 
Now,
I have tried to solve that issue with only using the required memory.

After discussion with David, I have tried to select a base 2 matrix dimension 
like
512 X 512 or 1024 X 512 etc for the dumping of the bitmap. But, I am still 
supporting
the default square root based method of dimension selection.


Signed-off-by: Sanidhya Kashyap 
---

 scripts/extract-bitmap.py | 213 ++
 1 file changed, 213 insertions(+)
 create mode 100755 scripts/extract-bitmap.py

diff --git a/scripts/extract-bitmap.py b/scripts/extract-bitmap.py
new file mode 100755
index 000..9a5a481
--- /dev/null
+++ b/scripts/extract-bitmap.py
@@ -0,0 +1,213 @@
+#!/usr/bin/python
+# This python script helps in extracting the dirty bitmap present
+# in the file after executing the log-dirty-bitmap command either
+# from the qmp or hmp interface. This file only processes binary
+# file obtained via command.
+#
+# Copyright (C) 2014 Sanidhya Kashyap 
+#
+# Authors:
+#   Sanidhya Kashyap
+#
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or later.
+
+import struct
+import argparse
+from functools import partial
+from math import sqrt
+from numpy import array
+from pylab import figure, imshow, savefig, gray, xlim, ylim
+from os import path, makedirs
+
+long_bytes = 8
+byte_size = 8
+int_bytes = 4
+block_list = []
+total_blocks = 0
+
+def get_unsigned_long_integer(value):
+   return struct.unpack('

[Qemu-devel] [PATCH v6 3/6] BitmapLog: get the information about the parameters

2014-09-13 Thread Sanidhya Kashyap
Signed-off-by: Sanidhya Kashyap 
---

Removed acronyms, no functional change.

 hmp-commands.hx  |  2 ++
 hmp.c| 21 +
 hmp.h|  1 +
 monitor.c|  7 +++
 qapi-schema.json | 28 
 qmp-commands.hx  | 25 +
 savevm.c | 17 +
 7 files changed, 101 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index d104232..d336f20 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1778,6 +1778,8 @@ show qdev device model list
 show roms
 @item info tpm
 show the TPM device
+@item info log_dirty_bitmap
+show the current parameters values
 @end table
 ETEXI
 
diff --git a/hmp.c b/hmp.c
index d067420..4533dcd 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1732,3 +1732,24 @@ void hmp_info_memdev(Monitor *mon, const QDict *qdict)
 
 monitor_printf(mon, "\n");
 }
+
+void hmp_info_log_dirty_bitmap(Monitor *mon, const QDict *qdict)
+{
+Error *err = NULL;
+BitmapLogStateInfo *info = qmp_query_log_dirty_bitmap(&err);
+
+if (info) {
+monitor_printf(mon, "current iteration: %" PRId64 "\n",
+   info->current_iteration);
+monitor_printf(mon, "total iterations: %" PRId64 "\n",
+   info->iterations);
+monitor_printf(mon, "current period value: %" PRId64 "\n",
+   info->period);
+}
+
+if (err) {
+hmp_handle_error(mon, &err);
+}
+
+qapi_free_BitmapLogStateInfo(info);
+}
diff --git a/hmp.h b/hmp.h
index 0895182..02e8ee4 100644
--- a/hmp.h
+++ b/hmp.h
@@ -38,6 +38,7 @@ void hmp_info_balloon(Monitor *mon, const QDict *qdict);
 void hmp_info_pci(Monitor *mon, const QDict *qdict);
 void hmp_info_block_jobs(Monitor *mon, const QDict *qdict);
 void hmp_info_tpm(Monitor *mon, const QDict *qdict);
+void hmp_info_log_dirty_bitmap(Monitor *mon, const QDict *qdict);
 void hmp_quit(Monitor *mon, const QDict *qdict);
 void hmp_stop(Monitor *mon, const QDict *qdict);
 void hmp_system_reset(Monitor *mon, const QDict *qdict);
diff --git a/monitor.c b/monitor.c
index 34cee74..ba79375 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2921,6 +2921,13 @@ static mon_cmd_t info_cmds[] = {
 .mhandler.cmd = hmp_info_memdev,
 },
 {
+.name   = "log_dirty_bitmap",
+.args_type  = "",
+.params = "",
+.help   = "show the current parameters values",
+.mhandler.cmd = hmp_info_log_dirty_bitmap,
+},
+{
 .name   = NULL,
 },
 };
diff --git a/qapi-schema.json b/qapi-schema.json
index f96e959..d1b44f4 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3518,3 +3518,31 @@
   'data': { 'filename'  : 'str',
 '*iterations'   : 'int',
 '*period'   : 'int' } }
+##
+# @BitmapLogStateInfo
+#
+# Provides information for the bitmap logging process
+#
+# @current-iteration: stores current iteration value
+#
+# @iterations: total iterations value
+#
+# @period: the time difference in milliseconds between each iteration
+#
+# Since 2.2
+##
+{ 'type': 'BitmapLogStateInfo',
+  'data': { 'current-iteration' : 'int',
+'iterations': 'int',
+'period': 'int' } }
+
+##
+# @query-log-dirty-bitmap
+#
+# Get the current values of the parameters involved in bitmap logging process
+#
+# This command returns the BitmapLogStateInfo
+#
+# Since 2.2
+##
+{ 'command': 'query-log-dirty-bitmap', 'returns': 'BitmapLogStateInfo' }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index db0a8ed..9582bc7 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -3786,3 +3786,28 @@ Examples:
 
 <- { "return": {} }
 EQMP
+
+{
+.name   = "query-log-dirty-bitmap",
+.args_type  = "",
+.mhandler.cmd_new = qmp_marshal_input_query_log_dirty_bitmap,
+},
+
+SQMP
+query-log-dirty-bitmap
+--
+
+Get the parameters information
+
+- "current-iteration": stores current iteration value
+- "iterations": total iterations value
+- "period": the time difference in milliseconds between each iteration
+
+Example:
+
+-> { "execute": "query-log-dirty-bitmap" }
+<- { "return": {
+"current-iteration": 3,
+"iterations": 10,
+"period": 100 } }
+EQMP
diff --git a/savevm.c b/savevm.c
index 19f7b0c..75fdd04 100644
--- a/savevm.c
+++ b/savevm.c
@@ -1515,6 +1515,23 @@ void qmp_log_dirty_bitmap(const char *filename, bool 
has_iterations,
 return;
 }
 
+BitmapLogStateInfo *qmp_query_log_dirty_bitmap(Error **errp)
+{
+BitmapLogState *b = log_bitmap_get_current_state();
+BitmapLogStateInfo *info = NULL;
+
+if (b->state != LOG_BITMAP_STATE_ACTIVE) {
+return info;
+}
+
+info = g_malloc0(sizeof(BitmapLogStateInfo));
+info->current_iteration = b->current_iteration;
+info->iterations = b->iterations;
+info->period = b->current_period;
+
+return info;
+}
+
 void qmp_xen_save_devices_state(const char *fi

[Qemu-devel] [PATCH v6 5/6] BitmapLog: set the period of the dump bitmap process

2014-09-13 Thread Sanidhya Kashyap
Signed-off-by: Sanidhya Kashyap 
---

Removed acronyms, no functional change.

 hmp-commands.hx  | 15 +++
 hmp.c| 12 
 hmp.h|  1 +
 qapi-schema.json | 12 
 qmp-commands.hx  | 24 
 savevm.c | 14 ++
 6 files changed, 78 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index b253239..c480309 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1818,6 +1818,21 @@ STEXI
 Cancel the current bitmap dump process
 ETEXI
 
+{
+.name   = "log_dirty_bitmap_set_period",
+.args_type  = "period:i",
+.params = "period",
+.help   = "set the period for bitmap dump process\n\t\t\t"
+  "period: the new period value to replace the existing",
+.mhandler.cmd = hmp_log_dirty_bitmap_set_period,
+},
+
+STEXI
+@item log_dirty_bitmap_set_period @var{period}
+@findex log_dirty_bitmap_set_period
+Set the period to @var{period} (int) for bitmap dump process.
+ETEXI
+
 STEXI
 @end table
 ETEXI
diff --git a/hmp.c b/hmp.c
index 80b4e5d..4f9b807 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1341,6 +1341,18 @@ void hmp_log_dirty_bitmap_cancel(Monitor *mon, const 
QDict *qdict)
 qmp_log_dirty_bitmap_cancel(NULL);
 }
 
+void hmp_log_dirty_bitmap_set_period(Monitor *mon, const QDict *qdict)
+{
+int64_t period = qdict_get_int(qdict, "period");
+Error *err = NULL;
+qmp_log_dirty_bitmap_set_period(period, &err);
+if (err) {
+monitor_printf(mon, "log_dirty_bitmap_set_period: %s\n",
+   error_get_pretty(err));
+error_free(err);
+}
+}
+
 void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
 {
 Error *err = NULL;
diff --git a/hmp.h b/hmp.h
index fcfb10f..a5a0571 100644
--- a/hmp.h
+++ b/hmp.h
@@ -97,6 +97,7 @@ void hmp_object_del(Monitor *mon, const QDict *qdict);
 void hmp_info_memdev(Monitor *mon, const QDict *qdict);
 void hmp_log_dirty_bitmap(Monitor *mon, const QDict *qdict);
 void hmp_log_dirty_bitmap_cancel(Monitor *mon, const QDict *qdict);
+void hmp_log_dirty_bitmap_set_period(Monitor *mon, const QDict *qdict);
 void object_add_completion(ReadLineState *rs, int nb_args, const char *str);
 void object_del_completion(ReadLineState *rs, int nb_args, const char *str);
 void device_add_completion(ReadLineState *rs, int nb_args, const char *str);
diff --git a/qapi-schema.json b/qapi-schema.json
index 0e90e9a..87b9297 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3555,3 +3555,15 @@
 # Since 2.2
 ##
 { 'command': 'log-dirty-bitmap-cancel' }
+
+##
+# @log-dirty-bitmap-set-period
+#
+# sets the period of the dirty bitmap logging process
+# @frequency: the updated period value (in milliseconds).
+# The min and max values are 10 and 10 respectively.
+#
+# Since 2.2
+##
+{ 'command': 'log-dirty-bitmap-set-period',
+  'data': { 'period': 'int' } }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 890a393..f229a2f 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -3831,3 +3831,27 @@ Example:
 -> { "execute": "log-dirty-bitmap-cancel" }
 <- { "return": {} }
 EQMP
+
+{
+.name   = "log-dirty-bitmap-set-period",
+.args_type  = "period:i",
+.mhandler.cmd_new = qmp_marshal_input_log_dirty_bitmap_set_period,
+},
+
+SQMP
+log-dirty-bitmap-set-period
+---
+
+Update the period for the remaining iterations.
+
+Arguments:
+
+- "period": The updated period (json-int) (in milliseconds).
+The min and max values are 10 and 10 respectively.
+
+Example:
+
+-> { "execute": "log-dirty-bitmap-set-period", "arguments": { "period": 1024 } 
}
+<- { "return": {} }
+
+EQMP
diff --git a/savevm.c b/savevm.c
index 51995b4..17af116 100644
--- a/savevm.c
+++ b/savevm.c
@@ -1546,6 +1546,20 @@ void qmp_log_dirty_bitmap_cancel(Error **errp)
 } while (b->state != LOG_BITMAP_STATE_CANCELING);
 }
 
+void qmp_log_dirty_bitmap_set_period(int64_t period, Error **errp)
+{
+BitmapLogState *b = log_bitmap_get_current_state();
+Error *local_err = NULL;
+if (value_in_range(period, MIN_PERIOD_VALUE,
+   MAX_PERIOD_VALUE, "period", &local_err)) {
+if (local_err) {
+error_propagate(errp, local_err);
+return;
+}
+}
+b->current_period = period;
+}
+
 void qmp_xen_save_devices_state(const char *filename, Error **errp)
 {
 QEMUFile *f;
-- 
1.9.1




[Qemu-devel] [PATCH v6 0/6] Obtain dirty bitmap via VM logging

2014-09-13 Thread Sanidhya Kashyap
Hi,

The following patches introduce the support of the dirty bitmap logging and
dumping to a specified file. This patch series addresses the previous issues
raised by David and Eric.

v5 --> v6
* The shared function between migration and log bitmap has been again modified
  (David's advice).
* Again changed the naming conventions for shared state between migration and
  log dirty bitmap (David's and Eric's advice).
* Removed acronyms (Eric's advice).
* Fixed grammatical mistakes and macros (Eric's advice).
* Modified the python script to utilize less memory as well as dump the snapshot
  into a file instead of separate window (David's advice).

v4 --> v5
* Removed the runstates code (Eric's and David's advice).
* Now, using global variable to resolve the issue between migration and
  bitmap dump (David's advice).
* Merged the hmp and qmp interface's patch (Eric's advice).
* Modified the code to support the dynamic change in last_ram_offset (David's
  advice).
* Formatted the strings in the python code i.e. length followed by text
  (David's advice).
* Added some code to generate black and white figure based on the bitmap.
* Modified the shared function to be more generic (David's advice).

v3 --> v4
* Added new qmp interface for information extraction from the bitmap process

v2 --> v3
* Reformatted the code and removed some unnecessary parts.
* Printing block info along with length and offset.
* Changed the functions that were directly using RUN_STATE_RUNNING as state.

v1 --> v2:
* Added two new run states to avoid simultaneous execution of both migration and
  bitmap dump process.
* Removed FILE pointer usage.
* Dumping the data only in machine-readable format.
* Tried to rectify mistakes of the previous version.



Sanidhya Kashyap (6):
  generic function between migration and bitmap dump
  BitmapLog: bitmap dump code
  BitmapLog: get the information about the parameters
  BitmapLog: cancel mechanism for an already running dump bitmap process
  BitmapLog: set the period of the dump bitmap process
  BitmapLog: python script for extracting bitmap from a binary file

 arch_init.c   |  19 ++-
 hmp-commands.hx   |  47 ++
 hmp.c |  56 ++
 hmp.h |   4 +
 include/exec/cpu-all.h|   5 +-
 include/exec/ram_addr.h   |   4 +
 include/sysemu/sysemu.h   |   5 +
 migration.c   |  12 ++
 monitor.c |   7 +
 qapi-schema.json  |  86 ++
 qmp-commands.hx   | 101 +++
 savevm.c  | 423 ++
 scripts/extract-bitmap.py | 213 +++
 vl.c  |  23 +++
 14 files changed, 996 insertions(+), 9 deletions(-)
 create mode 100755 scripts/extract-bitmap.py

-- 
1.9.1




[Qemu-devel] [PATCH v6 2/6] BitmapLog: bitmap dump code

2014-09-13 Thread Sanidhya Kashyap
Signed-off-by: Sanidhya Kashyap 
---

No functional change, except:
- naming convention i.e. QemuProcess has been changed to QemuDirtyBitmapUser.
- rectified mistakes in documentation in qapi-schema.json.
- removed acronyms

 hmp-commands.hx |  16 ++
 hmp.c   |  18 +++
 hmp.h   |   1 +
 include/exec/cpu-all.h  |   5 +-
 include/sysemu/sysemu.h |   5 +
 migration.c |  12 ++
 qapi-schema.json|  37 +
 qmp-commands.hx |  32 
 savevm.c| 378 
 vl.c|  23 +++
 10 files changed, 526 insertions(+), 1 deletion(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index f859f8d..d104232 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1786,6 +1786,22 @@ STEXI
 show available trace events and their state
 ETEXI
 
+ {
+.name   = "log_dirty_bitmap",
+.args_type  = "filename:s,iterations:i?,period:i?",
+.params = "filename iterations period",
+.help   = "dumps the memory's dirty bitmap to file\n\t\t\t"
+  "filename: name of the file in which the bitmap will be 
saved\n\t\t\t"
+  "iterations: number of times the memory will be 
logged\n\t\t\t"
+  "period: time difference in milliseconds between each 
iteration",
+.mhandler.cmd = hmp_log_dirty_bitmap,
+},
+STEXI
+@item log_dirty_bitmap @var{filename}
+@findex log_dirty_bitmap
+dumps the writable working set of a VM's memory to a file
+ETEXI
+
 STEXI
 @end table
 ETEXI
diff --git a/hmp.c b/hmp.c
index 4d1838e..d067420 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1318,6 +1318,24 @@ void hmp_device_del(Monitor *mon, const QDict *qdict)
 hmp_handle_error(mon, &err);
 }
 
+void hmp_log_dirty_bitmap(Monitor *mon, const QDict *qdict)
+{
+const char *filename = qdict_get_str(qdict, "filename");
+bool has_iterations = qdict_haskey(qdict, "iterations");
+int64_t iterations = qdict_get_try_int(qdict, "iterations", 3);
+bool has_period = qdict_haskey(qdict, "period");
+int64_t period = qdict_get_try_int(qdict, "period", 10);
+Error *err = NULL;
+
+qmp_log_dirty_bitmap(filename, has_iterations, iterations,
+ has_period, period, &err);
+if (err) {
+monitor_printf(mon, "log_dirty_bitmap: %s\n", error_get_pretty(err));
+error_free(err);
+return;
+}
+}
+
 void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
 {
 Error *err = NULL;
diff --git a/hmp.h b/hmp.h
index 4fd3c4a..0895182 100644
--- a/hmp.h
+++ b/hmp.h
@@ -94,6 +94,7 @@ void hmp_cpu_add(Monitor *mon, const QDict *qdict);
 void hmp_object_add(Monitor *mon, const QDict *qdict);
 void hmp_object_del(Monitor *mon, const QDict *qdict);
 void hmp_info_memdev(Monitor *mon, const QDict *qdict);
+void hmp_log_dirty_bitmap(Monitor *mon, const QDict *qdict);
 void object_add_completion(ReadLineState *rs, int nb_args, const char *str);
 void object_del_completion(ReadLineState *rs, int nb_args, const char *str);
 void device_add_completion(ReadLineState *rs, int nb_args, const char *str);
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index f9d132f..4824d36 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -299,13 +299,16 @@ CPUArchState *cpu_copy(CPUArchState *env);
 
 /* memory API */
 
+/* global name which is used with both migration and bitmap dump */
+#define RAMBLOCK_NAME_LENGTH 256
+
 typedef struct RAMBlock {
 struct MemoryRegion *mr;
 uint8_t *host;
 ram_addr_t offset;
 ram_addr_t length;
 uint32_t flags;
-char idstr[256];
+char idstr[RAMBLOCK_NAME_LENGTH];
 /* Reads can take either the iothread or the ramlist lock.
  * Writes must take both locks.
  */
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index d8539fd..b5525ea 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -227,4 +227,9 @@ extern QemuOptsList qemu_net_opts;
 extern QemuOptsList qemu_global_opts;
 extern QemuOptsList qemu_mon_opts;
 
+/* migration vs dirty bitmap process */
+bool qemu_process_check(QemuDirtyBitmapUser user);
+void qemu_process_set(QemuDirtyBitmapUser user);
+const char *get_qemu_dirty_bitmap_user_as_string(void);
+
 #endif
diff --git a/migration.c b/migration.c
index 8d675b3..6a02b40 100644
--- a/migration.c
+++ b/migration.c
@@ -117,6 +117,7 @@ static void process_incoming_migration_co(void *opaque)
 } else {
 runstate_set(RUN_STATE_PAUSED);
 }
+qemu_process_set(QEMU_DIRTY_BITMAP_USER_NONE);
 }
 
 void process_incoming_migration(QEMUFile *f)
@@ -317,6 +318,7 @@ static void migrate_fd_cleanup(void *opaque)
 }
 
 notifier_list_notify(&migration_state_notifiers, s);
+qemu_process_set(QEMU_DIRTY_BITMAP_USER_NONE);
 }
 
 void migrate_fd_error(MigrationState *s)
@@ -326,6 +328,7 @@ void migrate_fd_error(MigrationState *s)
 s->state = MIG_STATE_ERROR;
  

[Qemu-devel] [PATCH v6 4/6] BitmapLog: cancel mechanism for an already running dump bitmap process

2014-09-13 Thread Sanidhya Kashyap
Signed-off-by: Sanidhya Kashyap 
---

No functional change, except acronyms have been removed.

Removed acronyms, no functional change.

 hmp-commands.hx  | 14 ++
 hmp.c|  5 +
 hmp.h|  1 +
 qapi-schema.json |  9 +
 qmp-commands.hx  | 20 
 savevm.c | 14 ++
 6 files changed, 63 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index d336f20..b253239 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1804,6 +1804,20 @@ STEXI
 dumps the writable working set of a VM's memory to a file
 ETEXI
 
+   {
+   .name   = "log_dirty_bitmap_cancel",
+   .args_type  = "",
+   .params = "",
+   .help   = "cancel the current bitmap dump process",
+   .mhandler.cmd = hmp_log_dirty_bitmap_cancel,
+},
+
+STEXI
+@item log_dirty_bitmap_cancel
+@findex log_dirty_bitmap_cancel
+Cancel the current bitmap dump process
+ETEXI
+
 STEXI
 @end table
 ETEXI
diff --git a/hmp.c b/hmp.c
index 4533dcd..80b4e5d 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1336,6 +1336,11 @@ void hmp_log_dirty_bitmap(Monitor *mon, const QDict 
*qdict)
 }
 }
 
+void hmp_log_dirty_bitmap_cancel(Monitor *mon, const QDict *qdict)
+{
+qmp_log_dirty_bitmap_cancel(NULL);
+}
+
 void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
 {
 Error *err = NULL;
diff --git a/hmp.h b/hmp.h
index 02e8ee4..fcfb10f 100644
--- a/hmp.h
+++ b/hmp.h
@@ -96,6 +96,7 @@ void hmp_object_add(Monitor *mon, const QDict *qdict);
 void hmp_object_del(Monitor *mon, const QDict *qdict);
 void hmp_info_memdev(Monitor *mon, const QDict *qdict);
 void hmp_log_dirty_bitmap(Monitor *mon, const QDict *qdict);
+void hmp_log_dirty_bitmap_cancel(Monitor *mon, const QDict *qdict);
 void object_add_completion(ReadLineState *rs, int nb_args, const char *str);
 void object_del_completion(ReadLineState *rs, int nb_args, const char *str);
 void device_add_completion(ReadLineState *rs, int nb_args, const char *str);
diff --git a/qapi-schema.json b/qapi-schema.json
index d1b44f4..0e90e9a 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3546,3 +3546,12 @@
 # Since 2.2
 ##
 { 'command': 'query-log-dirty-bitmap', 'returns': 'BitmapLogStateInfo' }
+
+##
+# @log-dirty-bitmap-cancel
+#
+# cancel the dirty bitmap logging process
+#
+# Since 2.2
+##
+{ 'command': 'log-dirty-bitmap-cancel' }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 9582bc7..890a393 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -3811,3 +3811,23 @@ Example:
 "iterations": 10,
 "period": 100 } }
 EQMP
+
+   {
+.name   = "log-dirty-bitmap-cancel",
+.args_type  = "",
+.mhandler.cmd_new = qmp_marshal_input_log_dirty_bitmap_cancel,
+},
+
+SQMP
+log-dirty-bitmap-cancel
+---
+
+Cancel the current bitmap dump process.
+
+Arguments: None.
+
+Example:
+
+-> { "execute": "log-dirty-bitmap-cancel" }
+<- { "return": {} }
+EQMP
diff --git a/savevm.c b/savevm.c
index 75fdd04..51995b4 100644
--- a/savevm.c
+++ b/savevm.c
@@ -1532,6 +1532,20 @@ BitmapLogStateInfo *qmp_query_log_dirty_bitmap(Error 
**errp)
 return info;
 }
 
+void qmp_log_dirty_bitmap_cancel(Error **errp)
+{
+BitmapLogState *b = log_bitmap_get_current_state();
+int old_state;
+do {
+old_state = b->state;
+if (old_state != LOG_BITMAP_STATE_ACTIVE) {
+break;
+}
+log_bitmap_set_status(b, old_state,
+ LOG_BITMAP_STATE_CANCELING);
+} while (b->state != LOG_BITMAP_STATE_CANCELING);
+}
+
 void qmp_xen_save_devices_state(const char *filename, Error **errp)
 {
 QEMUFile *f;
-- 
1.9.1




[Qemu-devel] Development of BSP for new architecture

2014-09-13 Thread Piyush Pandey
Hi Guys

I am new to this forum and I have joined this forum in order to contribute
to this forum and also get benefit from it.

Actually I have a development board based on ARM9 architecture named as
mini2440.

I want to develop a BSP for this board so that the qemu can support this
board also in its machine list as it supports the other Development Boards.

I want to develop the BSP for mini2440 because I want to test the
applications and an want to speed up the kernel development by testing and
debugging it in the qemu.

So I want to know guys that how should I proceed.

I am asking this to developer section as I am going to develop the new BSP
or provide the support for the new board in the qemu.


Thanks and Regards

Piyush Pandey


Re: [Qemu-devel] [RFC 09/10] ahci: factor out FIS decomposition

2014-09-13 Thread Paolo Bonzini
Il 13/09/2014 06:34, John Snow ha scritto:
> Signed-off-by: John Snow 
> ---
>  hw/ide/ahci.c | 169 
> ++
>  1 file changed, 86 insertions(+), 83 deletions(-)

Reviewed-by: Paolo Bonzini 

> diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
> index e4eae0c..5bc5a92 100644
> --- a/hw/ide/ahci.c
> +++ b/hw/ide/ahci.c
> @@ -936,10 +936,94 @@ static void process_ncq_command(AHCIState *s, int port, 
> uint8_t *cmd_fis,
>  }
>  }
>  
> +static void handle_reg_h2d_fis(AHCIState *s, int port,
> +   int slot, uint8_t *cmd_fis)
> +{
> +IDEState *ide_state = &s->dev[port].port.ifs[0];
> +AHCICmdHdr *cmd = s->dev[port].cur_cmd;
> +uint32_t opts = le32_to_cpu(cmd->opts);
> +
> +if (cmd_fis[1] & 0x0F) {
> +DPRINTF(port, "Port Multiplier not supported."
> +" cmd_fis[0]=%02x cmd_fis[1]=%02x cmd_fis[2]=%02x\n",
> +cmd_fis[0], cmd_fis[1], cmd_fis[2]);
> +return;
> +}
> +
> +if (cmd_fis[1] & 0x70) {
> +DPRINTF(port, "Reserved flags set in H2D Register FIS."
> +" cmd_fis[0]=%02x cmd_fis[1]=%02x cmd_fis[2]=%02x\n",
> +cmd_fis[0], cmd_fis[1], cmd_fis[2]);
> +return;
> +}
> +
> +if (!(cmd_fis[1] & SATA_FIS_REG_H2D_UPDATE_COMMAND_REGISTER)) {
> +switch (s->dev[port].port_state) {
> +case STATE_RUN:
> +if (cmd_fis[15] & ATA_SRST) {
> +s->dev[port].port_state = STATE_RESET;
> +}
> +break;
> +case STATE_RESET:
> +if (!(cmd_fis[15] & ATA_SRST)) {
> +ahci_reset_port(s, port);
> +}
> +break;
> +}
> +return;
> +}
> +
> +/* Check for NCQ command */
> +if (is_ncq(cmd_fis[2])) {
> +process_ncq_command(s, port, cmd_fis, slot);
> +return;
> +}
> +
> +/* Decompose the FIS:
> + * AHCI does not interpret FIS packets, it only forwards them.
> + * SATA 1.0 describes how to decode LBA28 and CHS FIS packets.
> + * Later specifications, e.g, SATA 3.2, describe LBA48 FIS packets.
> + *
> + * ATA4 describes sector number for LBA28/CHS commands.
> + * ATA6 describes sector number for LBA48 commands.
> + * ATA8 deprecates CHS fully, describing only LBA28/48.
> + *
> + * We dutifully convert the FIS into IDE registers, and allow the
> + * core layer to interpret them as needed. */
> +ide_state->feature = cmd_fis[3];
> +ide_state->sector = cmd_fis[4];  /* LBA 7:0 */
> +ide_state->lcyl = cmd_fis[5];/* LBA 15:8  */
> +ide_state->hcyl = cmd_fis[6];/* LBA 23:16 */
> +ide_state->select = cmd_fis[7];  /* LBA 27:24 (LBA28) */
> +ide_state->hob_sector = cmd_fis[8];  /* LBA 31:24 */
> +ide_state->hob_lcyl = cmd_fis[9];/* LBA 39:32 */
> +ide_state->hob_hcyl = cmd_fis[10];   /* LBA 47:40 */
> +ide_state->hob_feature = cmd_fis[11];
> +ide_state->nsector = (int64_t)((cmd_fis[13] << 8) | cmd_fis[12]);
> +/* 14, 16, 17, 18, 19: Reserved (SATA 1.0) */
> +/* 15: Only valid when UPDATE_COMMAND not set. */
> +
> +/* Copy the ACMD field (ATAPI packet, if any) from the AHCI command
> + * table to ide_state->io_buffer */
> +if (opts & AHCI_CMD_ATAPI) {
> +memcpy(ide_state->io_buffer, &cmd_fis[AHCI_COMMAND_TABLE_ACMD], 
> 0x10);
> +debug_print_fis(ide_state->io_buffer, 0x10);
> +s->dev[port].done_atapi_packet = false;
> +/* XXX send PIO setup FIS */
> +}
> +
> +ide_state->error = 0;
> +
> +/* Reset transferred byte counter */
> +cmd->status = 0;
> +
> +/* We're ready to process the command in FIS byte 2. */
> +ide_exec_cmd(&s->dev[port].port, cmd_fis[2]);
> +}
> +
>  static int handle_cmd(AHCIState *s, int port, int slot)
>  {
>  IDEState *ide_state;
> -uint32_t opts;
>  uint64_t tbl_addr;
>  AHCICmdHdr *cmd;
>  uint8_t *cmd_fis;
> @@ -966,7 +1050,6 @@ static int handle_cmd(AHCIState *s, int port, int slot)
>  return -1;
>  }
>  
> -opts = le32_to_cpu(cmd->opts);
>  tbl_addr = le64_to_cpu(cmd->tbl_addr);
>  cmd_len = 0x80;
>  cmd_fis = dma_memory_map(s->as, tbl_addr, &cmd_len,
> @@ -984,95 +1067,15 @@ static int handle_cmd(AHCIState *s, int port, int slot)
>  
>  switch (cmd_fis[0]) {
>  case SATA_FIS_TYPE_REGISTER_H2D:
> +handle_reg_h2d_fis(s, port, slot, cmd_fis);
>  break;
>  default:
>  DPRINTF(port, "unknown command cmd_fis[0]=%02x cmd_fis[1]=%02x "
>"cmd_fis[2]=%02x\n", cmd_fis[0], cmd_fis[1],
>cmd_fis[2]);
> -goto out;
>  break;
>  }
>  
> -if (cmd_fis[1] & 0x0F) {
> -DPRINTF(port, "Port Multiplier not supported."
> -" cmd_fis[0]=%02x cmd_fis[1]=%02x cmd_fis[2]=%02x\n",
> -cmd_fis[

Re: [Qemu-devel] [RFC 08/10] ahci: Check cmd_fis[1] more explicitly

2014-09-13 Thread Paolo Bonzini
Il 13/09/2014 06:34, John Snow ha scritto:
> Instead of checking for a known byte, inspect the
> fields of this byte explicitly to produce more meaningful
> error messages and improve the readability of this section.
> 
> Signed-off-by: John Snow 
> ---
>  hw/ide/ahci.c | 23 ---
>  1 file changed, 12 insertions(+), 11 deletions(-)
> 
> diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
> index 1153ce9..e4eae0c 100644
> --- a/hw/ide/ahci.c
> +++ b/hw/ide/ahci.c
> @@ -993,17 +993,18 @@ static int handle_cmd(AHCIState *s, int port, int slot)
>  break;
>  }
>  
> -switch (cmd_fis[1]) {
> -case SATA_FIS_REG_H2D_UPDATE_COMMAND_REGISTER:
> -break;
> -case 0:
> -break;
> -default:
> -DPRINTF(port, "unknown command cmd_fis[0]=%02x cmd_fis[1]=%02x "
> -  "cmd_fis[2]=%02x\n", cmd_fis[0], cmd_fis[1],
> -  cmd_fis[2]);
> -goto out;
> -break;
> +if (cmd_fis[1] & 0x0F) {
> +DPRINTF(port, "Port Multiplier not supported."
> +" cmd_fis[0]=%02x cmd_fis[1]=%02x cmd_fis[2]=%02x\n",
> +cmd_fis[0], cmd_fis[1], cmd_fis[2]);
> +goto out;
> +}
> +
> +if (cmd_fis[1] & 0x70) {
> +DPRINTF(port, "Reserved flags set in H2D Register FIS."
> +" cmd_fis[0]=%02x cmd_fis[1]=%02x cmd_fis[2]=%02x\n",
> +cmd_fis[0], cmd_fis[1], cmd_fis[2]);
> +goto out;
>  }
>  
>  if (!(cmd_fis[1] & SATA_FIS_REG_H2D_UPDATE_COMMAND_REGISTER)) {
> 

Reviewed-by: Paolo Bonzini 



Re: [Qemu-devel] [RFC 07/10] ide/ahci: Reorder error cases in handle_cmd

2014-09-13 Thread Paolo Bonzini
Il 13/09/2014 06:34, John Snow ha scritto:
> Error checking in ahci's handle_cmd is re-ordered so that we
> initialize as few things as possible before we've done our
> sanity checking. This simplifies returning from this call
> in case of an error.
> 
> A check to make sure the DMA memory map succeeds with the
> correct size is also added, and the debug print of the
> command fis is cleaned up with its size corrected.
> 
> Signed-off-by: John Snow 
> ---
>  hw/ide/ahci.c | 28 +---
>  1 file changed, 13 insertions(+), 15 deletions(-)
> 
> diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
> index c2fa733..1153ce9 100644
> --- a/hw/ide/ahci.c
> +++ b/hw/ide/ahci.c
> @@ -951,38 +951,36 @@ static int handle_cmd(AHCIState *s, int port, int slot)
>  return -1;
>  }
>  
> -cmd = &((AHCICmdHdr *)s->dev[port].lst)[slot];
> -
>  if (!s->dev[port].lst) {
>  DPRINTF(port, "error: lst not given but cmd handled");
>  return -1;
>  }
> -
> +cmd = &((AHCICmdHdr *)s->dev[port].lst)[slot];
>  /* remember current slot handle for later */
>  s->dev[port].cur_cmd = cmd;
>  
> +/* The device we are working for */
> +ide_state = &s->dev[port].port.ifs[0];
> +if (!ide_state->bs) {
> +DPRINTF(port, "error: guest accessed unused port");
> +return -1;
> +}
> +
>  opts = le32_to_cpu(cmd->opts);
>  tbl_addr = le64_to_cpu(cmd->tbl_addr);
> -
>  cmd_len = 0x80;
>  cmd_fis = dma_memory_map(s->as, tbl_addr, &cmd_len,
>   DMA_DIRECTION_FROM_DEVICE);
> -
>  if (!cmd_fis) {
>  DPRINTF(port, "error: guest passed us an invalid cmd fis\n");
>  return -1;
> -}
> -
> -/* The device we are working for */
> -ide_state = &s->dev[port].port.ifs[0];
> -
> -if (!ide_state->bs) {
> -DPRINTF(port, "error: guest accessed unused port");
> +} else if (cmd_len != 0x80) {
> +ahci_trigger_irq(s, &s->dev[port], PORT_IRQ_HBUS_ERR);
> +DPRINTF(port, "error: dma_memory_map failed (len (%02x) < 0x80)\n",
> +cmd_len);
>  goto out;
>  }
> -
> -debug_print_fis(cmd_fis, 0x90);
> -//debug_print_fis(cmd_fis, (opts & AHCI_CMD_HDR_CMD_FIS_LEN) * 4);
> +debug_print_fis(cmd_fis, 0x80);
>  
>  switch (cmd_fis[0]) {
>  case SATA_FIS_TYPE_REGISTER_H2D:
> 

Reviewed-by: Paolo Bonzini 



Re: [Qemu-devel] [RFC 03/10] AHCI: Add PRD interrupt

2014-09-13 Thread Paolo Bonzini
Il 13/09/2014 06:34, John Snow ha scritto:
> AHCI devices support a feature where individual entries in the
> scatter-gather list may have interrupt request bits set, in order
> to receive notification partway through a command that a portion
> of a transfer has completed. AHCI specs refer to this as the
> DPS bit or Descriptor Processed Status. It is named the
> "Interrupt on Completion" bit inside the PRDT.
> 
> This is not currently feasible in QEMU without reworking the inner
> DMA loop extensively, but we can at least record if we saw such
> a bit in advance and sent the interrupt at the end of the transfer,
> in case a guest is expecting to see the PRD/DPS interrupt bit set.
> 
> Signed-off-by: John Snow 
> ---
>  hw/ide/ahci.c | 11 +++
>  hw/ide/ahci.h |  5 -
>  2 files changed, 15 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
> index d3ece78..8e6a352 100644
> --- a/hw/ide/ahci.c
> +++ b/hw/ide/ahci.c
> @@ -501,6 +501,7 @@ static void ahci_reset_port(AHCIState *s, int port)
>  pr->scr_err = 0;
>  pr->scr_act = 0;
>  d->busy_slot = -1;
> +d->dp_intr_req = false;
>  d->init_d2h_sent = false;
>  
>  ide_state = &s->dev[port].port.ifs[0];
> @@ -775,11 +776,15 @@ static int ahci_populate_sglist(AHCIDevice *ad, 
> QEMUSGList *sglist, int offset)
>   ad->hba->as);
>  qemu_sglist_add(sglist, le64_to_cpu(tbl[off_idx].addr + off_pos),
>  prdt_tbl_entry_size(&tbl[off_idx]) - off_pos);
> +ad->dp_intr_req = le32_to_cpu(tbl[off_idx].flags_size) & 
> AHCI_PRDT_INTR;

Why is this also not an "OR"?  It feels safer that way.

>  for (i = off_idx + 1; i < sglist_alloc_hint; i++) {
>  /* flags_size is zero-based */
>  qemu_sglist_add(sglist, le64_to_cpu(tbl[i].addr),
>  prdt_tbl_entry_size(&tbl[i]));
> +if (le32_to_cpu(tbl[i].flags_size) & AHCI_PRDT_INTR) {
> +ad->dp_intr_req = 1;
> +}
>  }
>  }
>  
> @@ -1151,6 +1156,11 @@ static int ahci_commit_buf(IDEDMA *dma, int xfer_ok)
>  
>  qemu_sglist_destroy(&s->sg);
>  
> +if (ad->dp_intr_req) {
> +ahci_trigger_irq(ad->hba, ad, PORT_IRQ_SG_DONE);
> +ad->dp_intr_req = 0;
> +}

Is it also needed in the error case?  Especially the short-PRDT case
that you are adding in the next patch.

>  return s->sg.size != 0;
>  }
>  
> @@ -1307,6 +1317,7 @@ static const VMStateDescription vmstate_ahci_device = {
>  VMSTATE_UINT32(port_regs.cmd_issue, AHCIDevice),
>  VMSTATE_BOOL(done_atapi_packet, AHCIDevice),
>  VMSTATE_INT32(busy_slot, AHCIDevice),
> +VMSTATE_BOOL(dp_intr_req, AHCIDevice),
>  VMSTATE_BOOL(init_d2h_sent, AHCIDevice),
>  VMSTATE_END_OF_LIST()
>  },
> diff --git a/hw/ide/ahci.h b/hw/ide/ahci.h
> index 1543df7..31f32d3 100644
> --- a/hw/ide/ahci.h
> +++ b/hw/ide/ahci.h
> @@ -180,7 +180,9 @@
>  
>  #define AHCI_COMMAND_TABLE_ACMD0x40
>  
> -#define AHCI_PRDT_SIZE_MASK0x3f
> +#define AHCI_PRDT_SIZE_MASK0x003f
> +#define AHCI_PRDT_RESERVED 0x7fc0
> +#define AHCI_PRDT_INTR 0x8000
>  
>  #define IDE_FEATURE_DMA1
>  
> @@ -265,6 +267,7 @@ struct AHCIDevice {
>  bool done_atapi_packet;
>  int32_t busy_slot;
>  bool init_d2h_sent;
> +bool dp_intr_req;
>  AHCICmdHdr *cur_cmd;
>  NCQTransferState ncq_tfs[AHCI_MAX_CMDS];
>  };
> 




Re: [Qemu-devel] [RFC 04/10] ide: Correct handling of malformed/short PRDTs

2014-09-13 Thread Paolo Bonzini
Il 13/09/2014 06:34, John Snow ha scritto:
> This impacts both BMDMA and AHCI HBA interfaces for IDE.
> Currently, we confuse the difference between a PRD having
> "0 bytes" and a PRD having "0 complete sectors."
> 
> This leads to, in the BMDMA case, leaked memory for short PRDTs,
> and infinite loops in the AHCI case.
> 
> the "prepare_buf" callback is reworked to return 0 if it could
> not allocate a full sector's worth of buffer space, instead of
> returning non-zero if it allocated any number of bytes.
> 
> ide_dma_cb adds a call to commit_buf in order to delete
> the short PRDT that it will not attempt to use to finish
> the DMA operation.
> 
> This patch corrects both occurrences and adds an assertion to
> prevent future regression. This assertion is tested in the
> existing ide-test, and is covered in a forthcoming AHCI test.
> 
> Signed-off-by: John Snow 
> ---
>  dma-helpers.c | 3 +++
>  hw/ide/ahci.c | 2 +-
>  hw/ide/core.c | 1 +
>  hw/ide/pci.c  | 5 +++--
>  4 files changed, 8 insertions(+), 3 deletions(-)
> 
> diff --git a/dma-helpers.c b/dma-helpers.c
> index ba965a3..3f9766d 100644
> --- a/dma-helpers.c
> +++ b/dma-helpers.c
> @@ -38,6 +38,9 @@ int dma_memory_set(AddressSpace *as, dma_addr_t addr, 
> uint8_t c, dma_addr_t len)
>  void qemu_sglist_init(QEMUSGList *qsg, DeviceState *dev, int alloc_hint,
>AddressSpace *as)
>  {
> +/* If this is true, you're leaking memory. */
> +assert(qsg->sg == NULL);
> +
>  qsg->sg = g_malloc(alloc_hint * sizeof(ScatterGatherEntry));
>  qsg->nsg = 0;
>  qsg->nalloc = alloc_hint;
> diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
> index 8e6a352..42a77c4 100644
> --- a/hw/ide/ahci.c
> +++ b/hw/ide/ahci.c
> @@ -1132,7 +1132,7 @@ static int ahci_dma_prepare_buf(IDEDMA *dma, int 
> is_write)
>  s->io_buffer_size = s->sg.size;
>  
>  DPRINTF(ad->port_no, "len=%#x\n", s->io_buffer_size);
> -return s->io_buffer_size != 0;
> +return s->io_buffer_size / 512 != 0;
>  }
>  
>  /**
> diff --git a/hw/ide/core.c b/hw/ide/core.c
> index b2980e9..1685f6d 100644
> --- a/hw/ide/core.c
> +++ b/hw/ide/core.c
> @@ -726,6 +726,7 @@ void ide_dma_cb(void *opaque, int ret)
>  /* The PRDs were too short. Reset the Active bit, but don't raise an
>   * interrupt. */
>  s->status = READY_STAT | SEEK_STAT;
> +dma_buf_commit(s, false);
>  goto eot;
>  }
>  
> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
> index 2397f35..3f643c2 100644
> --- a/hw/ide/pci.c
> +++ b/hw/ide/pci.c
> @@ -74,8 +74,9 @@ static int bmdma_prepare_buf(IDEDMA *dma, int is_write)
>  if (bm->cur_prd_len == 0) {
>  /* end of table (with a fail safe of one page) */
>  if (bm->cur_prd_last ||
> -(bm->cur_addr - bm->addr) >= BMDMA_PAGE_SIZE)
> -return s->io_buffer_size != 0;
> +(bm->cur_addr - bm->addr) >= BMDMA_PAGE_SIZE) {
> +return (s->io_buffer_size / 512) != 0;
> +}
>  pci_dma_read(pci_dev, bm->cur_addr, &prd, 8);
>  bm->cur_addr += 8;
>  prd.addr = le32_to_cpu(prd.addr);
> 

Reviewed-by: Paolo Bonzini 

The changes I suggested in patch 2 shouldn't be a hurdle here.

Paolo



Re: [Qemu-devel] [RFC 02/10] AHCI: Update byte count after DMA completion

2014-09-13 Thread Paolo Bonzini
Il 13/09/2014 06:34, John Snow ha scritto:
> Currently, DMA read/write operations neglect to update
> the byte count after a successful transfer like ATAPI
> DMA read or PIO read/write operations do.
> 
> We correct this oversight by adding another callback into
> the IDEDMAOps structure. The commit callback is called
> whenever we are cleaning up a scatter-gather list.
> AHCI can register this callback in order to update post-
> transfer information such as byte count updates.
> 
> We use this callback in AHCI to consolidate where we delete
> the SGlist as generated from the PRDT, as well as update the
> byte count after the transfer is complete.
> 
> The QEMUSGList structure has an init flag added to it in order
> to make qemu_sglist_destroy a nop if it is called when
> there is no sglist, which simplifies cleanup and error paths.
> 
> This patch fixes several AHCI problems, notably Non-NCQ modes
> of operation for Windows 7 as well as Hibernate support for Windows 7.

I think this patch is touching the internals more than it should.
There's obviously some good stuff here, but the abstractions needed to
fix the problem are already there.

> Signed-off-by: John Snow 
> ---
>  dma-helpers.c|  5 +
>  hw/ide/ahci.c| 47 +--
>  hw/ide/core.c| 14 +-
>  hw/ide/internal.h|  1 +
>  include/sysemu/dma.h |  1 +
>  5 files changed, 53 insertions(+), 15 deletions(-)
> 
> diff --git a/dma-helpers.c b/dma-helpers.c
> index 499b52b..ba965a3 100644
> --- a/dma-helpers.c
> +++ b/dma-helpers.c
> @@ -45,6 +45,7 @@ void qemu_sglist_init(QEMUSGList *qsg, DeviceState *dev, 
> int alloc_hint,
>  qsg->as = as;
>  qsg->dev = dev;
>  object_ref(OBJECT(dev));
> +qsg->init = true;
>  }
>  
>  void qemu_sglist_add(QEMUSGList *qsg, dma_addr_t base, dma_addr_t len)
> @@ -61,6 +62,10 @@ void qemu_sglist_add(QEMUSGList *qsg, dma_addr_t base, 
> dma_addr_t len)
>  
>  void qemu_sglist_destroy(QEMUSGList *qsg)
>  {
> +if (!qsg->init) {
> +return;
> +}
> +
>  object_unref(OBJECT(qsg->dev));
>  g_free(qsg->sg);
>  memset(qsg, 0, sizeof(*qsg));

Why do you need this?  qemu_sglist_destroy is idempotent (neither free
nor unref of NULL cause problems).

> diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
> index 0ee713b..d3ece78 100644
> --- a/hw/ide/ahci.c
> +++ b/hw/ide/ahci.c
> @@ -48,6 +48,9 @@ static int handle_cmd(AHCIState *s,int port,int slot);
>  static void ahci_reset_port(AHCIState *s, int port);
>  static void ahci_write_fis_d2h(AHCIDevice *ad, uint8_t *cmd_fis);
>  static void ahci_init_d2h(AHCIDevice *ad);
> +static int ahci_dma_prepare_buf(IDEDMA *dma, int is_write);
> +static int ahci_commit_buf(IDEDMA *dma, int xfer_ok);
> +
>  
>  static uint32_t  ahci_port_read(AHCIState *s, int port, int offset)
>  {
> @@ -1084,16 +1087,12 @@ static void ahci_start_transfer(IDEDMA *dma)
>  }
>  }
>  
> -/* update number of transferred bytes */
> -ad->cur_cmd->status = cpu_to_le32(le32_to_cpu(ad->cur_cmd->status) + 
> size);
> -
>  out:
>  /* declare that we processed everything */
>  s->data_ptr = s->data_end;
>  
> -if (has_sglist) {
> -qemu_sglist_destroy(&s->sg);
> -}
> +/* Update number of transferred bytes, destroy sglist */
> +ahci_commit_buf(dma, true);
>  
>  s->end_transfer_func(s);
>  
> @@ -1114,6 +1113,11 @@ static void ahci_start_dma(IDEDMA *dma, IDEState *s,
>  dma_cb(s, 0);
>  }
>  
> +/**
> + * Called in DMA R/W chains to read the PRDTL, utilizing 
> ahci_populate_sglist.
> + * Not currently invoked by PIO R/W chains,
> + * which invoke ahci_populate_sglist via ahci_start_transfer.
> + */
>  static int ahci_dma_prepare_buf(IDEDMA *dma, int is_write)
>  {
>  AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
> @@ -1126,6 +1130,30 @@ static int ahci_dma_prepare_buf(IDEDMA *dma, int 
> is_write)
>  return s->io_buffer_size != 0;
>  }
>  
> +/**
> + * Destroys the scatter-gather list,
> + * and updates the command header with a bytes-read value.
> + * called explicitly via ahci_dma_rw_buf (ATAPI DMA),
> + * and ahci_start_transfer (PIO R/W),
> + * and called via callback from ide_dma_cb for DMA R/W paths.
> + */
> +static int ahci_commit_buf(IDEDMA *dma, int xfer_ok)
> +{
> +AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
> +IDEState *s = &ad->port.ifs[0];
> +uint32_t byte_count;
> +
> +if (xfer_ok) {
> +byte_count = le32_to_cpu(ad->cur_cmd->status);
> +byte_count += s->sg.size;
> +ad->cur_cmd->status = cpu_to_le32(byte_count);
> +}

If you leave qemu_sglist_destroy in the caller, you do not need to call
ahci_commit_buf in the error cases.  Maybe I'm wrong, but I have a
feeling that it would be much simpler to me if your commit hook is simply

   byte_count += le32_to_cpu(ad->cur_cmd->status);
   ad->cur_cmd->status = cpu_to_le32(byte_count);

where byte_count is the second argument to the 

Re: [Qemu-devel] [RFC 01/10] ide: add is_write() macro for semantic consistency

2014-09-13 Thread Paolo Bonzini
Il 13/09/2014 06:34, John Snow ha scritto:
> The prepare_buf callback takes an argument named /is_write/,
> however in core.c we are checking to see if this DMA command
> is /is_read/. I am adding a small macro to correct this oversight.
> 
> Impact: Nothing, yet.
> -The prepare_buf callback is only used in ahci and pci, and both
>  versions of this callback name the incoming argument is_write.
> -Both functions ignore this hint currently, anyway.
> 
> This is therefore a simple patch to avoid future mistakes.
> 
> Signed-off-by: John Snow 
> ---
>  hw/ide/core.c | 2 +-
>  hw/ide/internal.h | 2 ++
>  2 files changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/ide/core.c b/hw/ide/core.c
> index 191f893..3d682e2 100644
> --- a/hw/ide/core.c
> +++ b/hw/ide/core.c
> @@ -718,7 +718,7 @@ void ide_dma_cb(void *opaque, int ret)
>  n = s->nsector;
>  s->io_buffer_index = 0;
>  s->io_buffer_size = n * 512;
> -if (s->bus->dma->ops->prepare_buf(s->bus->dma, ide_cmd_is_read(s)) == 0) 
> {
> +if (s->bus->dma->ops->prepare_buf(s->bus->dma, ide_cmd_is_write(s)) == 
> 0) {
>  /* The PRDs were too short. Reset the Active bit, but don't raise an
>   * interrupt. */
>  s->status = READY_STAT | SEEK_STAT;
> diff --git a/hw/ide/internal.h b/hw/ide/internal.h
> index 5c19f79..72d0147 100644
> --- a/hw/ide/internal.h
> +++ b/hw/ide/internal.h
> @@ -338,6 +338,8 @@ enum ide_dma_cmd {
>  
>  #define ide_cmd_is_read(s) \
>   ((s)->dma_cmd == IDE_DMA_READ)
> +#define ide_cmd_is_write(s) \
> +((s)->dma_cmd == IDE_DMA_WRITE)
>  
>  /* NOTE: IDEState represents in fact one drive */
>  struct IDEState {
> 

Actually the code is right (!).

A read command corresponds to a DMA write.  A write or trim will read
data from memory, so it is a DMA read.

See for example how rw_buf is only used from the READ CD command, but
passes 1 for the second argument of prepare_buf.

Paolo



Re: [Qemu-devel] [PATCH 3/4] qemu-nbd: Destroy the BlockDriverState properly

2014-09-13 Thread Paolo Bonzini
Il 12/09/2014 21:26, Markus Armbruster ha scritto:
> Match the bdrv_new() with a bdrv_unref(), just to be tidy.
> 
> Signed-off-by: Markus Armbruster 
> ---
>  qemu-nbd.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/qemu-nbd.c b/qemu-nbd.c
> index 9bc152e..f3cf8a2 100644
> --- a/qemu-nbd.c
> +++ b/qemu-nbd.c
> @@ -769,7 +769,7 @@ int main(int argc, char **argv)
>  }
>  } while (state != TERMINATED);
>  
> -bdrv_close(bs);
> +bdrv_unref(bs);
>  if (sockpath) {
>  unlink(sockpath);
>  }
> 

Applying to nbd-next, thanks.

Paolo



Re: [Qemu-devel] [PATCH v2 1/1] ide/atapi: Mark non-data commands as complete

2014-09-13 Thread Paolo Bonzini
Il 13/09/2014 05:51, John Snow ha scritto:
> When the command completion code in IDE and AHCI
> was unified to put all command completion inside
> of a callback, "cmd_done," we neglected to
> ensure that all AHCI/ATAPI command paths would
> eventually register as finished. for the PCI
> interface to IDE this is not a problem because
> cmd_done is a nop, but the AHCI implementation
> needs to send a D2H_REG_FIS and interrupt back
> to the guest to inform of completion.
> 
> This patch adds calls to ide_stop_transfer,
> which calls ide_cmd_done, inside of
> ide_atapi_cmd_ok and ide_atapi_cmd_error.
> 
> This fixes regressions observed by trying to boot QEMU
> with a Fedora 20 live CD under Q35/AHCI, which uses
> ATAPI command 0x00, which is a status check that may
> cause a hang because we never complete, and ATAPI
> command 0x56, which is unsupported by our current
> implementation and results in an error that we never
> report back to the guest.
> 
> Signed-off-by: John Snow 
> ---
>  hw/ide/atapi.c | 7 +++
>  1 file changed, 3 insertions(+), 4 deletions(-)
> 
> diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
> index 3d92b52..ee80c22 100644
> --- a/hw/ide/atapi.c
> +++ b/hw/ide/atapi.c
> @@ -134,6 +134,7 @@ void ide_atapi_cmd_ok(IDEState *s)
>  s->error = 0;
>  s->status = READY_STAT | SEEK_STAT;
>  s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | 
> ATAPI_INT_REASON_CD;
> +ide_transfer_stop(s);
>  ide_set_irq(s->bus);
>  }
>  
> @@ -147,6 +148,7 @@ void ide_atapi_cmd_error(IDEState *s, int sense_key, int 
> asc)
>  s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | 
> ATAPI_INT_REASON_CD;
>  s->sense_key = sense_key;
>  s->asc = asc;
> +ide_transfer_stop(s);
>  ide_set_irq(s->bus);
>  }
>  
> @@ -174,9 +176,7 @@ void ide_atapi_cmd_reply_end(IDEState *s)
>  #endif
>  if (s->packet_transfer_size <= 0) {
>  /* end of transfer */
> -s->status = READY_STAT | SEEK_STAT;
> -s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | 
> ATAPI_INT_REASON_CD;
> -ide_transfer_stop(s);
> +ide_atapi_cmd_ok(s);
>  ide_set_irq(s->bus);
>  #ifdef DEBUG_IDE_ATAPI
>  printf("status=0x%x\n", s->status);
> @@ -186,7 +186,6 @@ void ide_atapi_cmd_reply_end(IDEState *s)
>  if (s->lba != -1 && s->io_buffer_index >= s->cd_sector_size) {
>  ret = cd_read_sector(s, s->lba, s->io_buffer, s->cd_sector_size);
>  if (ret < 0) {
> -ide_transfer_stop(s);
>  ide_atapi_io_error(s, ret);
>  return;
>  }
> 

Reviewed-by: Paolo Bonzini 



Re: [Qemu-devel] [PATCH 10/10] aio-win32: add support for sockets

2014-09-13 Thread Paolo Bonzini
Il 13/09/2014 04:22, TeLeMan ha scritto:
> On Fri, Sep 12, 2014 at 6:05 PM, Paolo Bonzini  wrote:
>> Il 12/09/2014 03:39, TeLeMan ha scritto:
>>> On Wed, Jul 9, 2014 at 5:53 PM, Paolo Bonzini  wrote:
 diff --git a/aio-win32.c b/aio-win32.c
 index 4542270..61e3d2d 100644
 --- a/aio-win32.c
 +++ b/aio-win32.c
 +bool was_dispatching, progress, have_select_revents, first;
>>> have_select_revents has no initial value.
>>
>> Good catch here...
>>
>>>
 @@ -183,6 +318,7 @@ bool aio_poll(AioContext *ctx, bool blocking)

  /* wait until next event */
  while (count > 0) {
 +HANDLE event;
  int ret;

  timeout = blocking
 @@ -196,13 +332,17 @@ bool aio_poll(AioContext *ctx, bool blocking)
  first = false;

  /* if we have any signaled events, dispatch event */
 -if ((DWORD) (ret - WAIT_OBJECT_0) >= count) {
 +event = NULL;
 +if ((DWORD) (ret - WAIT_OBJECT_0) < count) {
 +event = events[ret - WAIT_OBJECT_0];
 +} else if (!have_select_revents) {
>>>
>>> when (ret - WAIT_OBJECT_0) >= count and have_select_revents is true,
>>> the following events[ret - WAIT_OBJECT_0] will be overflowed.
>>
>> ... this instead is not a problem, ret - WAIT_OBJECT_0 can be at most
>> equal to count, and events[] is declared with MAXIMUM_WAIT_OBJECTS + 1
>> places.  So the
>>
>> events[ret - WAIT_OBJECT_0] = events[--count];
>>
>> is equal to
>>
>> events[count] = events[count - 1];
>> --count;
>>
>> and this is harmless.
> 
> WAIT_ABANDONED_0 & WAIT_TIMEOUT & WAIT_FAILED are larger than
> MAXIMUM_WAIT_OBJECTS.

WAIT_ABANDONED_0 and WAIT_FAILED cannot happen, but you're right about
WAIT_TIMEOUT.  Are you going to send a patch?

Paolo

>> Paolo
>>
  break;
  }

 +have_select_revents = false;
  blocking = false;

 -progress |= aio_dispatch_handlers(ctx, events[ret - 
 WAIT_OBJECT_0]);
 +progress |= aio_dispatch_handlers(ctx, event);

  /* Try again, but only call each handler once.  */
  events[ret - WAIT_OBJECT_0] = events[--count];
>>
> 
> 




[Qemu-devel] [PATCH] tcx: Implement hardware acceleration

2014-09-13 Thread Mark Cave-Ayland
The S24/TCX framebuffer is a mildly accelerated video card with
blitter, stippler and hardware cursor.

* Solaris and NetBSD 6.x use all the hardware acceleration features
* The Xorg driver (used by Linux) can use the hardware cursor only

This patch implements hardware acceleration in both 8 bit and 24 bit
modes. It is based on the NetBSD driver sources and from tests with
Solaris.

Signed-off-by: Olivier Danet 
Signed-off-by: Mark Cave-Ayland 
---
 hw/display/tcx.c |  677 --
 hw/sparc/sun4m.c |   56 +++--
 2 files changed, 596 insertions(+), 137 deletions(-)

diff --git a/hw/display/tcx.c b/hw/display/tcx.c
index 28c742c..d6bb56f 100644
--- a/hw/display/tcx.c
+++ b/hw/display/tcx.c
@@ -33,10 +33,20 @@
 
 #define MAXX 1024
 #define MAXY 768
-#define TCX_DAC_NREGS 16
-#define TCX_THC_NREGS_8  0x081c
-#define TCX_THC_NREGS_24 0x1000
+#define TCX_DAC_NREGS16
+#define TCX_THC_NREGS0x1000
+#define TCX_DHC_NREGS0x4000
 #define TCX_TEC_NREGS0x1000
+#define TCX_ALT_NREGS0x8000
+#define TCX_STIP_NREGS   0x80
+#define TCX_BLIT_NREGS   0x80
+#define TCX_RSTIP_NREGS  0x80
+#define TCX_RBLIT_NREGS  0x80
+
+#define TCX_THC_MISC 0x818
+#define TCX_THC_CURSXY   0x8fc
+#define TCX_THC_CURSMASK 0x900
+#define TCX_THC_CURSBITS 0x980
 
 #define TYPE_TCX "SUNW,tcx"
 #define TCX(obj) OBJECT_CHECK(TCXState, (obj), TYPE_TCX)
@@ -45,6 +55,7 @@ typedef struct TCXState {
 SysBusDevice parent_obj;
 
 QemuConsole *con;
+qemu_irq irq;
 uint8_t *vram;
 uint32_t *vram24, *cplane;
 hwaddr prom_addr;
@@ -52,17 +63,30 @@ typedef struct TCXState {
 MemoryRegion vram_mem;
 MemoryRegion vram_8bit;
 MemoryRegion vram_24bit;
+MemoryRegion stip;
+MemoryRegion blit;
 MemoryRegion vram_cplane;
-MemoryRegion dac;
+MemoryRegion rstip;
+MemoryRegion rblit;
 MemoryRegion tec;
+MemoryRegion dac;
+MemoryRegion thc;
+MemoryRegion dhc;
+MemoryRegion alt;
 MemoryRegion thc24;
-MemoryRegion thc8;
+
 ram_addr_t vram24_offset, cplane_offset;
+uint32_t tmpblit;
 uint32_t vram_size;
-uint32_t palette[256];
-uint8_t r[256], g[256], b[256];
+uint32_t palette[260];
+uint8_t r[260], g[260], b[260];
 uint16_t width, height, depth;
 uint8_t dac_index, dac_state;
+uint32_t thcmisc;
+uint32_t cursmask[32];
+uint32_t cursbits[32];
+uint16_t cursx;
+uint16_t cursy;
 } TCXState;
 
 static void tcx_set_dirty(TCXState *s)
@@ -70,10 +94,36 @@ static void tcx_set_dirty(TCXState *s)
 memory_region_set_dirty(&s->vram_mem, 0, MAXX * MAXY);
 }
 
-static void tcx24_set_dirty(TCXState *s)
+static inline int tcx24_check_dirty(TCXState *s, ram_addr_t page,
+ram_addr_t page24, ram_addr_t cpage)
 {
-memory_region_set_dirty(&s->vram_mem, s->vram24_offset, MAXX * MAXY * 4);
-memory_region_set_dirty(&s->vram_mem, s->cplane_offset, MAXX * MAXY * 4);
+int ret;
+
+ret = memory_region_get_dirty(&s->vram_mem, page, TARGET_PAGE_SIZE,
+  DIRTY_MEMORY_VGA);
+ret |= memory_region_get_dirty(&s->vram_mem, page24, TARGET_PAGE_SIZE * 4,
+   DIRTY_MEMORY_VGA);
+ret |= memory_region_get_dirty(&s->vram_mem, cpage, TARGET_PAGE_SIZE * 4,
+   DIRTY_MEMORY_VGA);
+return ret;
+}
+
+static inline void tcx24_reset_dirty(TCXState *ts, ram_addr_t page_min,
+   ram_addr_t page_max, ram_addr_t page24,
+  ram_addr_t cpage)
+{
+memory_region_reset_dirty(&ts->vram_mem,
+  page_min,
+  (page_max - page_min) + TARGET_PAGE_SIZE,
+  DIRTY_MEMORY_VGA);
+memory_region_reset_dirty(&ts->vram_mem,
+  page24 + page_min * 4,
+  (page_max - page_min) * 4 + TARGET_PAGE_SIZE,
+  DIRTY_MEMORY_VGA);
+memory_region_reset_dirty(&ts->vram_mem,
+  cpage + page_min * 4,
+  (page_max - page_min) * 4 + TARGET_PAGE_SIZE,
+  DIRTY_MEMORY_VGA);
 }
 
 static void update_palette_entries(TCXState *s, int start, int end)
@@ -102,11 +152,7 @@ static void update_palette_entries(TCXState *s, int start, 
int end)
 break;
 }
 }
-if (s->depth == 24) {
-tcx24_set_dirty(s);
-} else {
-tcx_set_dirty(s);
-}
+tcx_set_dirty(s);
 }
 
 static void tcx_draw_line32(TCXState *s1, uint8_t *d,
@@ -116,7 +162,7 @@ static void tcx_draw_line32(TCXState *s1, uint8_t *d,
 uint8_t val;
 uint32_t *p = (uint32_t *)d;
 
-for(x = 0; x < width; x++) {
+for (x = 0; x < width; x++) {
 val = *s++;
 *p++ = s1->palette[val];
 }
@@ -129,7 +175,7 @@ static void tcx_draw_line16(TCXState *

Re: [Qemu-devel] [PULL v2 6/7] qtest: Adapt vhost-user-test to latest vhost-user changes

2014-09-13 Thread Linhaifeng
How to test send data to VM?

On 2014/7/18 7:44, Michael S. Tsirkin wrote:
> From: Nikolay Nikolaev 
> 
> A new field mmap_offset was added in the vhost-user message, we need to 
> reflect
> this change in the test too.
> 
> Signed-off-by: Nikolay Nikolaev 
> Reviewed-by: Michael S. Tsirkin 
> Signed-off-by: Michael S. Tsirkin 
> ---
>  tests/vhost-user-test.c | 11 +--
>  1 file changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c
> index 406ba70..75fedf0 100644
> --- a/tests/vhost-user-test.c
> +++ b/tests/vhost-user-test.c
> @@ -76,6 +76,7 @@ typedef struct VhostUserMemoryRegion {
>  uint64_t guest_phys_addr;
>  uint64_t memory_size;
>  uint64_t userspace_addr;
> +uint64_t mmap_offset;
>  } VhostUserMemoryRegion;
>  
>  typedef struct VhostUserMemory {
> @@ -205,6 +206,7 @@ static void read_guest_mem(void)
>  uint32_t *guest_mem;
>  gint64 end_time;
>  int i, j;
> +size_t size;
>  
>  g_mutex_lock(data_mutex);
>  
> @@ -231,8 +233,13 @@ static void read_guest_mem(void)
>  
>  g_assert_cmpint(memory.regions[i].memory_size, >, 1024);
>  
> -guest_mem = mmap(0, memory.regions[i].memory_size,
> -PROT_READ | PROT_WRITE, MAP_SHARED, fds[i], 0);
> +size =  memory.regions[i].memory_size + 
> memory.regions[i].mmap_offset;
> +
> +guest_mem = mmap(0, size, PROT_READ | PROT_WRITE,
> + MAP_SHARED, fds[i], 0);
> +
> +g_assert(guest_mem != MAP_FAILED);
> +guest_mem += (memory.regions[i].mmap_offset / sizeof(*guest_mem));
>  
>  for (j = 0; j < 256; j++) {
>  uint32_t a = readl(memory.regions[i].guest_phys_addr + j*4);
> 




[Qemu-devel] commit 56bd9ea1a breaks display

2014-09-13 Thread BALATON Zoltan

Hello,

It looks like that commit 56bd9ea1a37395012adecca8b9c4762da15b01e7 
(console: reimplement qemu_default_pixelformat) breaks display with 
qemu-system-ppc on x86_64 host with SDL. The window just stays black after 
this commit (although the machine still runs, it cannot be seen). Can you 
check please?


Regards,
BALATON Zoltan