Re: [Qemu-devel] [PATCH 12/15] savevm: split the process of different stages for loadvm/savevm

2017-04-20 Thread Hailiang Zhang

On 2017/4/20 17:09, Dr. David Alan Gilbert wrote:

* Hailiang Zhang (zhang.zhanghaili...@huawei.com) wrote:

On 2017/4/8 1:18, Dr. David Alan Gilbert wrote:

* zhanghailiang (zhang.zhanghaili...@huawei.com) wrote:

There are several stages during loadvm/savevm process. In different stage,
migration incoming processes different types of sections.
We want to control these stages more accuracy, it will benefit COLO
performance, we don't have to save type of QEMU_VM_SECTION_START
sections everytime while do checkpoint, besides, we want to separate
the process of saving/loading memory and devices state.

So we add three new helper functions: qemu_loadvm_state_begin(),
qemu_load_device_state() and qemu_savevm_live_state() to achieve
different process during migration.

Besides, we make qemu_loadvm_state_main() and qemu_save_device_state()
public.

Cc: Juan Quintela 
Signed-off-by: zhanghailiang 
Signed-off-by: Li Zhijian 
Reviewed-by: Dr. David Alan Gilbert 
---
   include/sysemu/sysemu.h |  6 ++
   migration/savevm.c  | 55 
++---
   2 files changed, 54 insertions(+), 7 deletions(-)

diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 7ed665a..95cae41 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -132,7 +132,13 @@ void qemu_savevm_send_postcopy_ram_discard(QEMUFile *f, 
const char *name,
  uint64_t *start_list,
  uint64_t *length_list);
+void qemu_savevm_live_state(QEMUFile *f);
+int qemu_save_device_state(QEMUFile *f);
+
   int qemu_loadvm_state(QEMUFile *f);
+int qemu_loadvm_state_begin(QEMUFile *f);
+int qemu_loadvm_state_main(QEMUFile *f, MigrationIncomingState *mis);
+int qemu_load_device_state(QEMUFile *f);
   extern int autostart;
diff --git a/migration/savevm.c b/migration/savevm.c
index 9c2d239..dac478b 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -54,6 +54,7 @@
   #include "qemu/cutils.h"
   #include "io/channel-buffer.h"
   #include "io/channel-file.h"
+#include "migration/colo.h"
   #ifndef ETH_P_RARP
   #define ETH_P_RARP 0x8035
@@ -1279,13 +1280,21 @@ done:
   return ret;
   }
-static int qemu_save_device_state(QEMUFile *f)
+void qemu_savevm_live_state(QEMUFile *f)
   {
-SaveStateEntry *se;
+/* save QEMU_VM_SECTION_END section */
+qemu_savevm_state_complete_precopy(f, true);
+qemu_put_byte(f, QEMU_VM_EOF);
+}
-qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
-qemu_put_be32(f, QEMU_VM_FILE_VERSION);
+int qemu_save_device_state(QEMUFile *f)
+{
+SaveStateEntry *se;
+if (!migration_in_colo_state()) {
+qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
+qemu_put_be32(f, QEMU_VM_FILE_VERSION);
+}

Note that got split out into qemu_savevm_state_header() at some point.

Do you mean i should use the wrapper qemu_savevm_state_heade() here ?

Yes, I think so; best to keep the code that writes the file headers in one 
place.


OK, Will fix in next version, thanks.


Dave


Dave


   cpu_synchronize_all_states();
   QTAILQ_FOREACH(se, &savevm_state.handlers, entry) {
@@ -1336,8 +1345,6 @@ enum LoadVMExitCodes {
   LOADVM_QUIT =  1,
   };
-static int qemu_loadvm_state_main(QEMUFile *f, MigrationIncomingState *mis);
-
   /* -- incoming postcopy messages -- */
   /* 'advise' arrives before any transfers just to tell us that a postcopy
* *might* happen - it might be skipped if precopy transferred everything
@@ -1942,7 +1949,7 @@ qemu_loadvm_section_part_end(QEMUFile *f, 
MigrationIncomingState *mis)
   return 0;
   }
-static int qemu_loadvm_state_main(QEMUFile *f, MigrationIncomingState *mis)
+int qemu_loadvm_state_main(QEMUFile *f, MigrationIncomingState *mis)
   {
   uint8_t section_type;
   int ret = 0;
@@ -2080,6 +2087,40 @@ int qemu_loadvm_state(QEMUFile *f)
   return ret;
   }
+int qemu_loadvm_state_begin(QEMUFile *f)
+{
+MigrationIncomingState *mis = migration_incoming_get_current();
+Error *local_err = NULL;
+int ret;
+
+if (qemu_savevm_state_blocked(&local_err)) {
+error_report_err(local_err);
+return -EINVAL;
+}
+/* Load QEMU_VM_SECTION_START section */
+ret = qemu_loadvm_state_main(f, mis);
+if (ret < 0) {
+error_report("Failed to loadvm begin work: %d", ret);
+}
+return ret;
+}
+
+int qemu_load_device_state(QEMUFile *f)
+{
+MigrationIncomingState *mis = migration_incoming_get_current();
+int ret;
+
+/* Load QEMU_VM_SECTION_FULL section */
+ret = qemu_loadvm_state_main(f, mis);
+if (ret < 0) {
+error_report("Failed to load device state: %d", ret);
+return ret;
+}
+
+cpu_synchronize_all_post_init();
+return 0;
+}
+
   int save_vmstate(Monitor *mon, const char *name)
   {
   BlockDriverState *bs, *bs1;
--
1.8.3.1



--
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK

.




--
Dr. David Alan Gilbert / dgilb...@r

[Qemu-devel] [PATCH] Block layer core: Fix qemu-img 'amend' subcommand failure of adjusting backing file in different path

2017-04-20 Thread Ping Li
Currently, qemu-img 'amend' subcommand would fail to adjust image's backing file
which was moved into different path.
For example, parent.qcow2, the backing file of leaf.qcow2, first is at /home/a/,
then moved into /home/b/. Originally this command,
 "qemu-img amend -f qcow2 -o 
backing_fmt=qcow2,backing_file=/home/b/parent.qcow2 leaf.qcow2",
 would fail because qemu-img failed to open the old backing file of leaf.qcow2.
Give the 'amend' subcommand a '-u' option to not open the old backing file
 while openning leaf.qcow2.

Signed-off-by: Li Ping
---
 qemu-img.c | 16 ++--
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index b220cf7..a32e9d6 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -145,9 +145,10 @@ static void QEMU_NORETURN help(void)
"  'snapshot_id_or_name' is deprecated, use 'snapshot_param'\n"
"instead\n"
"  '-c' indicates that target image must be compressed (qcow format 
only)\n"
-   "  '-u' enables unsafe rebasing. It is assumed that old and new 
backing file\n"
-   "   match exactly. The image doesn't need a working backing 
file before\n"
-   "   rebasing in this case (useful for renaming the backing 
file)\n"
+   "  '-u' enables unsafe rebasing or amending. It is assumed that old 
and new\n"
+   "   backing file match exactly. For rebasing, the image doesn't 
need a working\n"
+   "   backing file before rebasing in this case(useful for 
renaming the backing file).\n"
+   "   For amending, it doesn't open backing file(useful for 
moving images)\n"
"  '-h' with or without a command shows this help and lists the 
supported formats\n"
"  '-p' show progress of command (only certain commands)\n"
"  '-q' use Quiet mode - do not print any output (except errors)\n"
@@ -3538,7 +3539,7 @@ static int img_amend(int argc, char **argv)
 QemuOptsList *create_opts = NULL;
 QemuOpts *opts = NULL;
 const char *fmt = NULL, *filename, *cache;
-int flags;
+int flags = 0;
 bool writethrough;
 bool quiet = false, progress = false;
 BlockBackend *blk = NULL;
@@ -3553,7 +3554,7 @@ static int img_amend(int argc, char **argv)
 {"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
 {0, 0, 0, 0}
 };
-c = getopt_long(argc, argv, ":ho:f:t:pq",
+c = getopt_long(argc, argv, ":ho:f:t:pqu",
 long_options, NULL);
 if (c == -1) {
 break;
@@ -3595,6 +3596,9 @@ static int img_amend(int argc, char **argv)
 case 'q':
 quiet = true;
 break;
+case 'u':
+flags |= BDRV_O_NO_BACKING;
+break;
 case OPTION_OBJECT:
 opts = qemu_opts_parse_noisily(&qemu_object_opts,
optarg, true);
@@ -3639,7 +3643,7 @@ static int img_amend(int argc, char **argv)
 goto out;
 }
 
-flags = BDRV_O_RDWR;
+flags |= BDRV_O_RDWR;
 ret = bdrv_parse_cache_mode(cache, &flags, &writethrough);
 if (ret < 0) {
 error_report("Invalid cache option: %s", cache);
-- 
1.8.3.1





[Qemu-devel] Require for English style review (was RE: [PATCH v17 0/2] virtio-crypto: virtio crypto device specification)

2017-04-20 Thread Gonglei (Arei)
Hi all,

As a non-native English speaker,
I sincerely hope you give me more suggestions about English
style and/or grammar for the spec.


Thanks in advance!

-Gonglei


> -Original Message-
> From: Gonglei (Arei)
> Sent: Thursday, April 13, 2017 5:11 PM
> To: qemu-devel@nongnu.org; virtio-...@lists.oasis-open.org
> Cc: Luonengjun; m...@redhat.com; cornelia.h...@de.ibm.com;
> stefa...@redhat.com; denglin...@chinamobile.com; Jani Kokkonen;
> ola.liljed...@arm.com; varun.se...@freescale.com; xin.z...@intel.com;
> brian.a.keat...@intel.com; liang.j...@intel.com; john.grif...@intel.com;
> Huangweidong (C); mike.cara...@nxp.com; ag...@suse.de;
> jasow...@redhat.com; nmo...@kalray.eu; vincent.jar...@6wind.com; Wubin
> (H); arei.gong...@hotmail.com; pa...@linux.vnet.ibm.com; Zhbzg; Chenshanxi
> (Eety Chen, Euler); Zhanghuimin (Amy); Maoningning; Gonglei (Arei)
> Subject: [PATCH v17 0/2] virtio-crypto: virtio crypto device specification
> 
> Thanks to Stefan, Michael, Halil, Cornelia for reviewing. The v17 has some
> big changes, so I don't add Stefan's R-by until I get a response for the
> new version :)
> 
> v17 -> v16:
>  - Some grammar fixes [Stefan, Halil, Michael]
>  - add a section named "Supported crypto services" in order to explain bit
>numbers and valuse clearly. [Halil, Cornelia]
>  - avoid word reptition [Halil]
>  - rename non-session mode to stateless mode [Halil]
>  - change descriptions for all elements in struct virtio_crypto_config [Halil]
>  - add Halil as a reviewer in the ackonwledgement part, thanks for his work.
>  - other fixes here and there.
> 
> Changes since v15:
>  - use feature bits for non-session mode in order to keep compatibility with
>pre-existing code. [Halil & Michael]
>  - introduce VIRTIO_CRYPTO_F_ NON_SESSION_MODE feature bit to control all
> other
>non-session mode feature bits.
>  - fix some typos. [Stefan]
>  - introduce struct virtio_crypto_op_data_req_mux to support both session
>and non-session based crypto operations and keep compatibility with
>pre-existing code.
> 
> Changes since v14:
>  - drop VIRTIO_CRYPTO_S_STARTED status [Halil & Cornelia]
>  - correct a sentence about dataqueue and controlq in the first paragraph.
> [Halil]
>  - change a MAY to MUST about max_dataqueues. [Halil]
>  - add non-session mode support
>a) add four features for different crypto services to identify wheather
> support session mode.
>b) rewrite some
> 
> For pervious versions of virtio crypto spec, Pls see:
> 
> [v14]:
> https://lists.gnu.org/archive/html/qemu-devel/2016-11/msg02212.html
> 
> [v13]:
> https://lists.gnu.org/archive/html/qemu-devel/2016-10/msg07348.html
> 
> For more information, please see:
>  http://qemu-project.org/Features/VirtioCrypto
> 
> Please help to review, thanks.
> 
> Gonglei (2):
>   virtio-crypto: Add virtio crypto device specification
>   virtio-crypto: Add conformance clauses
> 
>  acknowledgements.tex |1 +
>  conformance.tex  |   29 ++
>  content.tex  |2 +
>  virtio-crypto.tex| 1305
> ++
>  4 files changed, 1337 insertions(+)
>  create mode 100644 virtio-crypto.tex
> 
> --
> 1.7.12.4
> 




Re: [Qemu-devel] [PATCH] sheepdog: Set error when connection fails

2017-04-20 Thread Markus Armbruster
Kevin Wolf  writes:

> Am 20.04.2017 um 17:30 hat Daniel P. Berrange geschrieben:
>> On Thu, Apr 20, 2017 at 12:00:03PM +0800, Fam Zheng wrote:
>> > Signed-off-by: Fam Zheng 
>> > ---
>> >  block/sheepdog.c | 1 +
>> >  1 file changed, 1 insertion(+)
>> > 
>> > diff --git a/block/sheepdog.c b/block/sheepdog.c
>> > index fb9203e..7e889ee 100644
>> > --- a/block/sheepdog.c
>> > +++ b/block/sheepdog.c
>> > @@ -608,6 +608,7 @@ static int connect_to_sdog(BDRVSheepdogState *s, Error 
>> > **errp)
>> >  qemu_set_nonblock(fd);
>> >  } else {
>> >  fd = -EIO;
>> > +error_setg(errp, "Failed to connect to sheepdog server");
>> >  }
>> 
>> This doesn't make much sense to me. The lines just above the
>> diff context have this:
>> 
>> fd = socket_connect(s->addr, errp, NULL, NULL);
>> 
>> socket_connect should have already reported an error on "errp"
>> in the scenario that 'fd == -1'.
>
> By the way, am I the only one who thinks that having errp anywhere else
> than as the last argument is bad style? I can easily see myself missing
> that this functions sets it because the last argument is NULL.

Yes, it's bad style because it's suprising.  Worth fixing.



[Qemu-devel] [PULL 3/4] versatile: remove cannot_destroy_with_object_finalize_yet

2017-04-20 Thread Markus Armbruster
From: Laurent Vivier 

cannot_destroy_with_object_finalize_yet was added by 4c315c2
("qdev: Protect device-list-properties against broken devices")
because "realview_pci" and "versatile_pci" were hanging
during "device-list-properties" cleanup (an infinite loop in
bus_unparent()).

We have this problem because the child is not removed from
the list of the PCI bus children because it has no defined parent:
qdev_set_parent_bus() set the device parent_bus pointer to bus, and
adds the device in the bus children list, but doesn't update the
device parent pointer.

To fix the problem, move all the involved parts to the realize function.

Signed-off-by: Laurent Vivier 
Message-Id: <20170414083717.13641-4-lviv...@redhat.com>
Reviewed-by: Markus Armbruster 
Acked-by: Peter Maydell 
[Commit message tweaked]
Signed-off-by: Markus Armbruster 
---
 hw/pci-host/versatile.c | 35 ---
 1 file changed, 12 insertions(+), 23 deletions(-)

diff --git a/hw/pci-host/versatile.c b/hw/pci-host/versatile.c
index 467cbb9..27fde46 100644
--- a/hw/pci-host/versatile.c
+++ b/hw/pci-host/versatile.c
@@ -380,20 +380,8 @@ static void pci_vpb_reset(DeviceState *d)
 
 static void pci_vpb_init(Object *obj)
 {
-PCIHostState *h = PCI_HOST_BRIDGE(obj);
 PCIVPBState *s = PCI_VPB(obj);
 
-memory_region_init(&s->pci_io_space, OBJECT(s), "pci_io", 1ULL << 32);
-memory_region_init(&s->pci_mem_space, OBJECT(s), "pci_mem", 1ULL << 32);
-
-pci_bus_new_inplace(&s->pci_bus, sizeof(s->pci_bus), DEVICE(obj), "pci",
-&s->pci_mem_space, &s->pci_io_space,
-PCI_DEVFN(11, 0), TYPE_PCI_BUS);
-h->bus = &s->pci_bus;
-
-object_initialize(&s->pci_dev, sizeof(s->pci_dev), 
TYPE_VERSATILE_PCI_HOST);
-qdev_set_parent_bus(DEVICE(&s->pci_dev), BUS(&s->pci_bus));
-
 /* Window sizes for VersatilePB; realview_pci's init will override */
 s->mem_win_size[0] = 0x0c00;
 s->mem_win_size[1] = 0x1000;
@@ -403,10 +391,22 @@ static void pci_vpb_init(Object *obj)
 static void pci_vpb_realize(DeviceState *dev, Error **errp)
 {
 PCIVPBState *s = PCI_VPB(dev);
+PCIHostState *h = PCI_HOST_BRIDGE(dev);
 SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
 pci_map_irq_fn mapfn;
 int i;
 
+memory_region_init(&s->pci_io_space, OBJECT(s), "pci_io", 1ULL << 32);
+memory_region_init(&s->pci_mem_space, OBJECT(s), "pci_mem", 1ULL << 32);
+
+pci_bus_new_inplace(&s->pci_bus, sizeof(s->pci_bus), dev, "pci",
+&s->pci_mem_space, &s->pci_io_space,
+PCI_DEVFN(11, 0), TYPE_PCI_BUS);
+h->bus = &s->pci_bus;
+
+object_initialize(&s->pci_dev, sizeof(s->pci_dev), 
TYPE_VERSATILE_PCI_HOST);
+qdev_set_parent_bus(DEVICE(&s->pci_dev), BUS(&s->pci_bus));
+
 for (i = 0; i < 4; i++) {
 sysbus_init_irq(sbd, &s->irq[i]);
 }
@@ -503,8 +503,6 @@ static void pci_vpb_class_init(ObjectClass *klass, void 
*data)
 dc->reset = pci_vpb_reset;
 dc->vmsd = &pci_vpb_vmstate;
 dc->props = pci_vpb_properties;
-/* Reason: object_unref() hangs */
-dc->cannot_destroy_with_object_finalize_yet = true;
 }
 
 static const TypeInfo pci_vpb_info = {
@@ -526,19 +524,10 @@ static void pci_realview_init(Object *obj)
 s->mem_win_size[2] = 0x0800;
 }
 
-static void pci_realview_class_init(ObjectClass *class, void *data)
-{
-DeviceClass *dc = DEVICE_CLASS(class);
-
-/* Reason: object_unref() hangs */
-dc->cannot_destroy_with_object_finalize_yet = true;
-}
-
 static const TypeInfo pci_realview_info = {
 .name  = "realview_pci",
 .parent= TYPE_VERSATILE_PCI,
 .instance_init = pci_realview_init,
-.class_init= pci_realview_class_init,
 };
 
 static void versatile_pci_register_types(void)
-- 
2.7.4




Re: [Qemu-devel] [PATCH v2 0/4] qdev: remove all remaining cannot_destroy_with_object_finalize_yet

2017-04-20 Thread Markus Armbruster
Laurent Vivier  writes:

> This series removes all the remaining uses of
> cannot_destroy_with_object_finalize_yet to finally remove
> the flag itself.
>
> The ARM patch has already been sent alone and reviewed by Markus.
> I have tested the ppc one on ppc64 machine with KVM and using
> QDM device-list-properties command.
>
> For the versatile one, the flag allowed to workaround a problem
> in the bus unparent function: the bus unparent is trying to
> unparent all the children of the bus. To do that, it has a list
> of the children of the bus, and calls object_unparent() for each
> child, and object_unparent() calls object_property_del_child() if
> obj->parent is not NULL.  As qdev_set_parent_bus() set only
> parent_bus and the list of children, parent is NULL and the child
> is never deleted.  We can avoid the problem by moving the
> qdev_set_parent_bus() to the realize part.
>
> I've tested all the changes with "make check" (including
> device-introspect-test). I've booted a versatilepb machine
> with a 3.16.0-4 debian installer kernel.

Applied to my tree, thanks!



[Qemu-devel] [PULL 2/4] ppc: remove cannot_destroy_with_object_finalize_yet

2017-04-20 Thread Markus Armbruster
From: Laurent Vivier 

This removes the assert(kvm_enabled()) from kvmppc_host_cpu_initfn()

This assert can never be triggered as the function is only registered
when KVM is available (see also 4c315c2
"qdev: Protect device-list-properties against broken devices").

So we can remove the cannot_destroy_with_object_finalize_yet from
kvmppc_host_cpu_class_init() without fear and beyond reproach.
(as it has already be done for i386 with 771a13e "i386: Unset
cannot_destroy_with_object_finalize_yet on "host" model" and
e435601 "target-i386: Remove assert(kvm_enabled()) from
host_x86_cpu_initfn()")

Signed-off-by: Laurent Vivier 
Message-Id: <20170414083717.13641-3-lviv...@redhat.com>
Acked-by: Peter Maydell 
Acked-by: David Gibson 
Signed-off-by: Markus Armbruster 
---
 target/ppc/kvm.c | 10 --
 1 file changed, 10 deletions(-)

diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 9f1f132..64017ac 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -2245,14 +2245,8 @@ static void alter_insns(uint64_t *word, uint64_t flags, 
bool on)
 }
 }
 
-static void kvmppc_host_cpu_initfn(Object *obj)
-{
-assert(kvm_enabled());
-}
-
 static void kvmppc_host_cpu_class_init(ObjectClass *oc, void *data)
 {
-DeviceClass *dc = DEVICE_CLASS(oc);
 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
 uint32_t vmx = kvmppc_get_vmx();
 uint32_t dfp = kvmppc_get_dfp();
@@ -2279,9 +2273,6 @@ static void kvmppc_host_cpu_class_init(ObjectClass *oc, 
void *data)
 if (icache_size != -1) {
 pcc->l1_icache_size = icache_size;
 }
-
-/* Reason: kvmppc_host_cpu_initfn() dies when !kvm_enabled() */
-dc->cannot_destroy_with_object_finalize_yet = true;
 }
 
 bool kvmppc_has_cap_epr(void)
@@ -2333,7 +2324,6 @@ static int kvm_ppc_register_host_cpu_type(void)
 {
 TypeInfo type_info = {
 .name = TYPE_HOST_POWERPC_CPU,
-.instance_init = kvmppc_host_cpu_initfn,
 .class_init = kvmppc_host_cpu_class_init,
 };
 PowerPCCPUClass *pvr_pcc;
-- 
2.7.4




[Qemu-devel] [PULL 0/4] qdev patches for 2017-04-21

2017-04-20 Thread Markus Armbruster
The following changes since commit 359c41abe32638adad503e386969fa428cecff52:

  Update version for v2.9.0 release (2017-04-20 15:31:34 +0100)

are available in the git repository at:

  git://repo.or.cz/qemu/armbru.git tags/pull-qdev-2017-04-21

for you to fetch changes up to 08f00df4f4b8b4e38ad620477cc90cf5f73832d9:

  qdev: remove cannot_destroy_with_object_finalize_yet (2017-04-21 07:18:34 
+0200)


qdev patches for 2017-04-21


Laurent Vivier (4):
  arm: remove remaining cannot_destroy_with_object_finalize_yet
  ppc: remove cannot_destroy_with_object_finalize_yet
  versatile: remove cannot_destroy_with_object_finalize_yet
  qdev: remove cannot_destroy_with_object_finalize_yet

 hw/arm/allwinner-a10.c  |  6 --
 hw/arm/bcm2836.c|  6 --
 hw/arm/digic.c  |  6 --
 hw/arm/fsl-imx25.c  |  5 -
 hw/arm/fsl-imx31.c  |  5 -
 hw/arm/fsl-imx6.c   |  5 -
 hw/arm/xlnx-zynqmp.c|  6 --
 hw/pci-host/versatile.c | 35 ---
 include/hw/qdev-core.h  | 13 -
 qmp.c   |  5 -
 target/ppc/kvm.c| 10 --
 11 files changed, 12 insertions(+), 90 deletions(-)

-- 
2.7.4




[Qemu-devel] [PULL 4/4] qdev: remove cannot_destroy_with_object_finalize_yet

2017-04-20 Thread Markus Armbruster
From: Laurent Vivier 

As all users have been removed, we can remove
cannot_destroy_with_object_finalize_yet field
from the DeviceClass structure.

Signed-off-by: Laurent Vivier 
Message-Id: <20170414083717.13641-5-lviv...@redhat.com>
Reviewed-by: Markus Armbruster 
Acked-by: Peter Maydell 
Signed-off-by: Markus Armbruster 
---
 include/hw/qdev-core.h | 13 -
 qmp.c  |  5 -
 2 files changed, 18 deletions(-)

diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index b44b476..ac682a6 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -113,19 +113,6 @@ typedef struct DeviceClass {
  * TODO remove once we're there
  */
 bool cannot_instantiate_with_device_add_yet;
-/*
- * Does this device model survive object_unref(object_new(TNAME))?
- * All device models should, and this flag shouldn't exist.  Some
- * devices crash in object_new(), some crash or hang in
- * object_unref().  Makes introspecting properties with
- * qmp_device_list_properties() dangerous.  Bad, because it's used
- * by -device FOO,help.  This flag serves to protect that code.
- * It should never be set without a comment explaining why it is
- * set.
- * TODO remove once we're there
- */
-bool cannot_destroy_with_object_finalize_yet;
-
 bool hotpluggable;
 
 /* callbacks */
diff --git a/qmp.c b/qmp.c
index a744e44..ab74cd7 100644
--- a/qmp.c
+++ b/qmp.c
@@ -548,11 +548,6 @@ DevicePropertyInfoList *qmp_device_list_properties(const 
char *typename,
 return NULL;
 }
 
-if (DEVICE_CLASS(klass)->cannot_destroy_with_object_finalize_yet) {
-error_setg(errp, "Can't list properties of device '%s'", typename);
-return NULL;
-}
-
 obj = object_new(typename);
 
 object_property_iter_init(&iter, obj);
-- 
2.7.4




[Qemu-devel] [PULL 1/4] arm: remove remaining cannot_destroy_with_object_finalize_yet

2017-04-20 Thread Markus Armbruster
From: Laurent Vivier 

With commit ce5b1bbf624b ("exec: move cpu_exec_init() calls to
realize functions"), we can now remove all the
remaining cannot_destroy_with_object_finalize_yet as
unsafe references have been moved to cpu_exec_realizefn().
(tested with QOM command provided by commit 4c315c27).

Suggested-by: Markus Armbruster 
Signed-off-by: Laurent Vivier 
Reviewed-by: Markus Armbruster 
Message-Id: <20170414083717.13641-2-lviv...@redhat.com>
Acked-by: Alistair Francis 
Acked-by: Peter Maydell 
Signed-off-by: Markus Armbruster 
---
 hw/arm/allwinner-a10.c | 6 --
 hw/arm/bcm2836.c   | 6 --
 hw/arm/digic.c | 6 --
 hw/arm/fsl-imx25.c | 5 -
 hw/arm/fsl-imx31.c | 5 -
 hw/arm/fsl-imx6.c  | 5 -
 hw/arm/xlnx-zynqmp.c   | 6 --
 7 files changed, 39 deletions(-)

diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
index ca15d1c..f62a9a3 100644
--- a/hw/arm/allwinner-a10.c
+++ b/hw/arm/allwinner-a10.c
@@ -118,12 +118,6 @@ static void aw_a10_class_init(ObjectClass *oc, void *data)
 DeviceClass *dc = DEVICE_CLASS(oc);
 
 dc->realize = aw_a10_realize;
-
-/*
- * Reason: creates an ARM CPU, thus use after free(), see
- * arm_cpu_class_init()
- */
-dc->cannot_destroy_with_object_finalize_yet = true;
 }
 
 static const TypeInfo aw_a10_type_info = {
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
index 8451190..8c43291 100644
--- a/hw/arm/bcm2836.c
+++ b/hw/arm/bcm2836.c
@@ -160,12 +160,6 @@ static void bcm2836_class_init(ObjectClass *oc, void *data)
 
 dc->props = bcm2836_props;
 dc->realize = bcm2836_realize;
-
-/*
- * Reason: creates an ARM CPU, thus use after free(), see
- * arm_cpu_class_init()
- */
-dc->cannot_destroy_with_object_finalize_yet = true;
 }
 
 static const TypeInfo bcm2836_type_info = {
diff --git a/hw/arm/digic.c b/hw/arm/digic.c
index d60ea39..94f3263 100644
--- a/hw/arm/digic.c
+++ b/hw/arm/digic.c
@@ -101,12 +101,6 @@ static void digic_class_init(ObjectClass *oc, void *data)
 DeviceClass *dc = DEVICE_CLASS(oc);
 
 dc->realize = digic_realize;
-
-/*
- * Reason: creates an ARM CPU, thus use after free(), see
- * arm_cpu_class_init()
- */
-dc->cannot_destroy_with_object_finalize_yet = true;
 }
 
 static const TypeInfo digic_type_info = {
diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c
index 2126f73..9056f27 100644
--- a/hw/arm/fsl-imx25.c
+++ b/hw/arm/fsl-imx25.c
@@ -290,11 +290,6 @@ static void fsl_imx25_class_init(ObjectClass *oc, void 
*data)
 
 dc->realize = fsl_imx25_realize;
 
-/*
- * Reason: creates an ARM CPU, thus use after free(), see
- * arm_cpu_class_init()
- */
-dc->cannot_destroy_with_object_finalize_yet = true;
 dc->desc = "i.MX25 SOC";
 }
 
diff --git a/hw/arm/fsl-imx31.c b/hw/arm/fsl-imx31.c
index dd1c713..d7e2d83 100644
--- a/hw/arm/fsl-imx31.c
+++ b/hw/arm/fsl-imx31.c
@@ -262,11 +262,6 @@ static void fsl_imx31_class_init(ObjectClass *oc, void 
*data)
 
 dc->realize = fsl_imx31_realize;
 
-/*
- * Reason: creates an ARM CPU, thus use after free(), see
- * arm_cpu_class_init()
- */
-dc->cannot_destroy_with_object_finalize_yet = true;
 dc->desc = "i.MX31 SOC";
 }
 
diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
index 76dd8a4..6969e73 100644
--- a/hw/arm/fsl-imx6.c
+++ b/hw/arm/fsl-imx6.c
@@ -442,11 +442,6 @@ static void fsl_imx6_class_init(ObjectClass *oc, void 
*data)
 
 dc->realize = fsl_imx6_realize;
 
-/*
- * Reason: creates an ARM CPU, thus use after free(), see
- * arm_cpu_class_init()
- */
-dc->cannot_destroy_with_object_finalize_yet = true;
 dc->desc = "i.MX6 SOC";
 }
 
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
index bc4e66b..4f67158 100644
--- a/hw/arm/xlnx-zynqmp.c
+++ b/hw/arm/xlnx-zynqmp.c
@@ -439,12 +439,6 @@ static void xlnx_zynqmp_class_init(ObjectClass *oc, void 
*data)
 
 dc->props = xlnx_zynqmp_props;
 dc->realize = xlnx_zynqmp_realize;
-
-/*
- * Reason: creates an ARM CPU, thus use after free(), see
- * arm_cpu_class_init()
- */
-dc->cannot_destroy_with_object_finalize_yet = true;
 }
 
 static const TypeInfo xlnx_zynqmp_type_info = {
-- 
2.7.4




Re: [Qemu-devel] [PATCH] qemu-img: use blk_co_pwrite_zeroes for zero sectors when compressed

2017-04-20 Thread 858585 jemmy
On Fri, Apr 21, 2017 at 10:58 AM, 858585 jemmy  wrote:
> On Thu, Apr 20, 2017 at 6:00 PM, Kevin Wolf  wrote:
>> Am 20.04.2017 um 10:38 hat jemmy858...@gmail.com geschrieben:
>>> From: Lidong Chen 
>>>
>>> when the buffer is zero, blk_co_pwrite_zeroes is more effectively than
>>> blk_co_pwritev with BDRV_REQ_WRITE_COMPRESSED. this patch can reduces
>>> the time when converts the qcow2 image with lots of zero.
>>>
>>> Signed-off-by: Lidong Chen 
>>
>> Good catch, using blk_co_pwrite_zeroes() makes sense even for compressed
>> images.
>>
>>> diff --git a/qemu-img.c b/qemu-img.c
>>> index b220cf7..0256539 100644
>>> --- a/qemu-img.c
>>> +++ b/qemu-img.c
>>> @@ -1675,13 +1675,20 @@ static int coroutine_fn 
>>> convert_co_write(ImgConvertState *s, int64_t sector_num,
>>>   * write if the buffer is completely zeroed and we're allowed 
>>> to
>>>   * keep the target sparse. */
>>>  if (s->compressed) {
>>> -if (s->has_zero_init && s->min_sparse &&
>>> -buffer_is_zero(buf, n * BDRV_SECTOR_SIZE))
>>> -{
>>> -assert(!s->target_has_backing);
>>> -break;
>>> +if (buffer_is_zero(buf, n * BDRV_SECTOR_SIZE)) {
>>> +if (s->has_zero_init && s->min_sparse) {
>>> +assert(!s->target_has_backing);
>>> +break;
>>> +} else {
>>> +ret = blk_co_pwrite_zeroes(s->target,
>>> +   sector_num << BDRV_SECTOR_BITS,
>>> +   n << BDRV_SECTOR_BITS, 0);
>>> +if (ret < 0) {
>>> +return ret;
>>> +}
>>> +break;
>>> +}
>>>  }
>>
>> If s->min_sparse == 0, we may neither skip the write not use
>> blk_co_pwrite_zeroes(), because this requires actual full allocation
>> with explicit zero sectors.
>>
>> Of course, if you fix this, what you end up with here is a duplicate of
>> the code path for non-compressed images. The remaining difference seems
>> to be the BDRV_REQ_WRITE_COMPRESSED flag and buffer_is_zero() vs.
>> is_allocated_sectors_min() (because uncompressed clusters can be written
>> partially, but compressed clusters can't).
>
> I have a try to unify the code.
>
> I don't understand why use  is_allocated_sectors_min when don't compressed.
> the s->min_sparse is 8 default, which is smaller than cluster_sectors.
>
> if a cluster which data is  8 sector zero and 8 sector non-zero
> repeated, it will call
> blk_co_pwritev and blk_co_pwrite_zeroes many times for a cluster.
>
> why not compare the zero by cluster_sectors size?

I write this code, run in guest os.

#include 
#include 
#include 

int main()
{
char *zero;
char *nonzero;
FILE* fp = fopen("./test.dat", "ab");

zero = malloc(sizeof(char)*512*8);
nonzero = malloc(sizeof(char)*512*8);

memset(zero, 0, sizeof(char)*512*8);
memset(nonzero, 1, sizeof(char)*512*8);

while (1) {
fwrite(zero, sizeof(char)*512*8, 1, fp);
fwrite(nonzero, sizeof(char)*512*8, 1, fp);
}
fclose(fp);
}

qemu-img info /mnt/img2016111016860868.qcow2
image: /mnt/img2016111016860868.qcow2
file format: qcow2
virtual size: 20G (21474836480 bytes)
disk size: 19G (20061552640 bytes)
cluster_size: 65536
backing file: /baseimage/img2016042213665396/img2016042213665396.qcow2

use -S 65536 option.

time /root/kvm/bin/qemu-img convert -p -B
/baseimage/img2016042213665396/img2016042213665396.qcow2 -O qcow2
/mnt/img2016111016860868.qcow2 /mnt/img2017041611162809_zip_new.qcow2
-S 65536
(100.00/100%)

real0m32.203s
user0m5.165s
sys 0m27.887s

time /root/kvm/bin/qemu-img convert -p -B
/baseimage/img2016042213665396/img2016042213665396.qcow2 -O qcow2
/mnt/img2016111016860868.qcow2 /mnt/img2017041611162809_zip_new.qcow2
(100.00/100%)

real1m38.665s
user0m45.418s
sys 1m7.518s

should we set cluster_sectors as the default value of s->min_sparse?

>
>>
>> So I suppose that instead of just fixing the above bug, we could actually
>> mostly unify the two code paths, if you want to have a try at it.
>>
>> Kevin



Re: [Qemu-devel] [PATCH] hw: make *_exit functions return void

2017-04-20 Thread Zihan Yang
(I forgot to reply all in last email, so I resend the reply again)
I have resubmitted two split-out patches in https://lists.nongnu.org/
archive/html/qemu-devel/2017-04/msg03096.html, which change the exit
funtion of sclp and virtio-ccw. But the exit function of DeviceClass still
returns int after the patch because it involves other folders like hw/audio,
and as suggested by Markus Armbruster, the exit function of DeviceClass
should be converted to unrealize(), so I just leave `virtio_ccw_busdev_exit`
at present because it is an exit function of DeviceClass.


2017-04-19 0:15 GMT+08:00 Cornelia Huck :

> On Sun, 16 Apr 2017 20:26:01 +0800
> Zihan Yang  wrote:
>
> > According to the second suggestion listed on Dead code Removal
> > of BiteSizedTasks, I modify some *_exit functions to make them
> > return void. Some *_exit and *_exitfn functions that already
> > return void remain unchanged. Also, the checks for the callers
> > are deleted.
> >
> > Signed-off-by: Zihan Yang 
> > ---
> >  hw/audio/hda-codec.c  | 3 +--
> >  hw/audio/intel-hda.c  | 3 +--
> >  hw/audio/intel-hda.h  | 2 +-
> >  hw/char/sclpconsole-lm.c  | 3 +--
> >  hw/char/sclpconsole.c | 3 +--
> >  hw/core/qdev.c| 6 +-
> >  hw/s390x/event-facility.c | 6 +-
> >  hw/s390x/virtio-ccw.c | 7 +++
> >  hw/s390x/virtio-ccw.h | 2 +-
> >  hw/usb/dev-smartcard-reader.c | 3 +--
> >  include/hw/qdev-core.h| 2 +-
> >  include/hw/s390x/event-facility.h | 2 +-
> >  12 files changed, 14 insertions(+), 28 deletions(-)
>
> Hm, I wondered why I had a deja vu... ah, here:
> https://marc.info/?t=14900329128&r=1&w=2
>
> The author of that patch did not follow up AFAICS, but some of the
> suggestions made in that thread apply to your patch as well.
>
> In particular:
>
>
> > diff --git a/hw/char/sclpconsole-lm.c b/hw/char/sclpconsole-lm.c
> > index 07d6ebd..6fa8922 100644
> > --- a/hw/char/sclpconsole-lm.c
> > +++ b/hw/char/sclpconsole-lm.c
> > @@ -318,9 +318,8 @@ static int console_init(SCLPEvent *event)
> >  return 0;
> >  }
> >
> > -static int console_exit(SCLPEvent *event)
> > +static void console_exit(SCLPEvent *event)
> >  {
> > -return 0;
> >  }
> >
> >  static void console_reset(DeviceState *dev)
> > diff --git a/hw/char/sclpconsole.c b/hw/char/sclpconsole.c
> > index b78f240..d9bbc5e 100644
> > --- a/hw/char/sclpconsole.c
> > +++ b/hw/char/sclpconsole.c
> > @@ -246,9 +246,8 @@ static void console_reset(DeviceState *dev)
> > scon->notify = false;
> >  }
> >
> > -static int console_exit(SCLPEvent *event)
> > +static void console_exit(SCLPEvent *event)
> >  {
> > -return 0;
> >  }
>
> These two now empty functions are not very useful; it is better to
> simply remove them.
>
> With that change, I'd take a split-out patch for sclp and virtio-ccw
> through my tree, or I'd ack a not-split-out version.
>
>


Re: [Qemu-devel] [PATCH 1/1] Fix wrong mss bug.

2017-04-20 Thread Philippe Mathieu-Daudé

Hi Tao,

On 04/20/2017 04:36 PM, Tao Wu wrote:

This bug was introduced by https://github.com/qemu/qemu/commit/98c6305


Nice catch...

In 98c6305 Guillaume probably missed parentheses :S
- mss = min(IF_MTU, IF_MRU) - sizeof(struct tcpiphdr);
+ mss = min(IF_MTU, IF_MRU) - sizeof(struct tcphdr) + sizeof(struct ip);

This would have been ok:
mss = min(IF_MTU, IF_MRU) - (sizeof(struct tcphdr) + sizeof(struct ip));

"The MSS value to be sent in an MSS option should be equal to the 
effective MTU minus the fixed IP and TCP headers." (RFC6691)



Signed-off-by: Tao Wu 


Reviewed-by: Philippe Mathieu-Daudé 


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

diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c
index edb98f06f3..07bcbdb2dd 100644
--- a/slirp/tcp_input.c
+++ b/slirp/tcp_input.c
@@ -1587,11 +1587,11 @@ tcp_mss(struct tcpcb *tp, u_int offer)
switch (so->so_ffamily) {
case AF_INET:
 mss = MIN(IF_MTU, IF_MRU) - sizeof(struct tcphdr)
- + sizeof(struct ip);
+ - sizeof(struct ip);
break;
case AF_INET6:
 mss = MIN(IF_MTU, IF_MRU) - sizeof(struct tcphdr)
- + sizeof(struct ip6);
+ - sizeof(struct ip6);
break;
default:
g_assert_not_reached();





Re: [Qemu-devel] [PATCH V2 1/2] COLO-compare: Optimize tcp compare for option field

2017-04-20 Thread Jason Wang



On 2017年04月21日 11:48, Zhang Chen wrote:



On 04/20/2017 02:43 PM, Jason Wang wrote:



On 2017年04月18日 10:20, Zhang Chen wrote:

In this patch we support packet that have tcp options field.
Add tcp options field check, If the packet have options
field we just skip it and compare tcp payload,
Avoid unnecessary checkpoint, optimize performance.

Signed-off-by: Zhang Chen 
---
  net/colo-compare.c | 27 ++-
  1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/net/colo-compare.c b/net/colo-compare.c
index aada04e..049f6f8 100644
--- a/net/colo-compare.c
+++ b/net/colo-compare.c
@@ -248,7 +248,32 @@ static int colo_packet_compare_tcp(Packet 
*spkt, Packet *ppkt)

  spkt->ip->ip_sum = ppkt->ip->ip_sum;
  }
  -if (ptcp->th_sum == stcp->th_sum) {
+/*
+ * Check tcp header length for tcp option field.
+ * th_off > 5 means this tcp packet have options field.
+ * The tcp options maybe always different.
+ * for example:
+ * From RFC 7323.
+ * TCP Timestamps option (TSopt):
+ * Kind: 8
+ *
+ * Length: 10 bytes
+ *
+ * +---+---+-+-+
+ *|Kind=8 |  10   |   TS Value (TSval)  |TS Echo Reply 
(TSecr)|

+ * +---+---+-+-+
+ *   1   1  4 4
+ *
+ * In this case the primary guest's timestamp always different 
with

+ * the secondary guest's timestamp. COLO just focus on payload,
+ * so we just need skip this field.h


Probably a good explanation why we can skip this kind of header. But 
it does not explain why we can skip all the rest?


I found tcp options have many kind number to express different meaning,
Here I just give an example for the different options situation,
and this field not the COLO-proxy focus on, COLO just concern the 
payload.
Maybe we will optimize in the feature. Currently we want to make COLO 
full-function

running in qemu upstream.


I see, but the questions are:

- If we see packets with different options (except for the case you 
explain above), does it mean primary and secondary run out of sync?
- What will happen if we compare and ask for synchronization if we find 
options are not exactly the same?


Thanks



Thanks
Zhang Chen



Thanks


+ */
+if (ptcp->th_off > 5) {
+ptrdiff_t tcp_offset;
+tcp_offset = ppkt->transport_header - (uint8_t *)ppkt->data
+ + (ptcp->th_off * 4);
+res = colo_packet_compare_common(ppkt, spkt, tcp_offset);
+} else if (ptcp->th_sum == stcp->th_sum) {
  res = colo_packet_compare_common(ppkt, spkt, ETH_HLEN);
  } else {
  res = -1;




.








[Qemu-devel] [PATCH v14 20/20] qemu-iotests: Add test case 153 for image locking

2017-04-20 Thread Fam Zheng
Signed-off-by: Fam Zheng 
---
 tests/qemu-iotests/153 | 219 
 tests/qemu-iotests/153.out | 627 +
 tests/qemu-iotests/group   |   1 +
 3 files changed, 847 insertions(+)
 create mode 100755 tests/qemu-iotests/153
 create mode 100644 tests/qemu-iotests/153.out

diff --git a/tests/qemu-iotests/153 b/tests/qemu-iotests/153
new file mode 100755
index 000..ff22615
--- /dev/null
+++ b/tests/qemu-iotests/153
@@ -0,0 +1,219 @@
+#!/bin/bash
+#
+# Test image locking
+#
+# Copyright 2016, 2017 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see .
+#
+
+# creator
+owner=f...@redhat.com
+
+seq="$(basename $0)"
+echo "QA output created by $seq"
+
+here="$PWD"
+tmp=/tmp/$$
+status=1   # failure is the default!
+
+_cleanup()
+{
+_cleanup_test_img
+rm -f "${TEST_IMG}.base"
+rm -f "${TEST_IMG}.convert"
+rm -f "${TEST_IMG}.a"
+rm -f "${TEST_IMG}.b"
+rm -f "${TEST_IMG}.lnk"
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+. ./common.qemu
+
+_supported_fmt qcow2
+_supported_proto file
+_supported_os Linux
+
+size=32M
+
+_run_cmd()
+{
+echo
+(echo "$@"; "$@" 2>&1 1>/dev/null) | _filter_testdir
+}
+
+function _do_run_qemu()
+{
+(
+if ! test -t 0; then
+while read cmd; do
+echo $cmd
+done
+fi
+echo quit
+) | $QEMU -nographic -monitor stdio -serial none "$@" 1>/dev/null
+}
+
+function _run_qemu_with_images()
+{
+_do_run_qemu \
+$(for i in $@; do echo "-drive if=none,file=$i"; done) 2>&1 \
+| _filter_testdir | _filter_qemu
+}
+
+test_opts="$(echo readonly={on,off},force-shared-write={on,off})"
+
+for opts1 in "" $test_opts; do
+echo
+echo "== Creating base image =="
+TEST_IMG="${TEST_IMG}.base" _make_test_img $size
+
+echo
+echo "== Creating test image =="
+$QEMU_IMG create -f $IMGFMT "${TEST_IMG}" -b ${TEST_IMG}.base | 
_filter_img_create
+
+echo
+echo "== Launching QEMU, opts: '$opts1' =="
+_launch_qemu -drive file="${TEST_IMG}",if=none,$opts1
+h=$QEMU_HANDLE
+
+for opts2 in "" $test_opts; do
+echo
+echo "== Launching another QEMU, opts: '$opts2' =="
+echo "quit" | \
+$QEMU -nographic -monitor stdio \
+-drive file="${TEST_IMG}",if=none,$opts2 2>&1 1>/dev/null | \
+_filter_testdir | _filter_qemu
+done
+
+for L in "" "-U"; do
+
+echo
+echo "== Running utility commands $L =="
+_run_cmd $QEMU_IO $L -c "read 0 512" "${TEST_IMG}"
+_run_cmd $QEMU_IO $L -r -c "read 0 512" "${TEST_IMG}"
+_run_cmd $QEMU_IO -c "open $L ${TEST_IMG}" -c "read 0 512"
+_run_cmd $QEMU_IO -c "open -r $L ${TEST_IMG}" -c "read 0 512"
+_run_cmd $QEMU_IMG info$L "${TEST_IMG}"
+_run_cmd $QEMU_IMG check   $L "${TEST_IMG}"
+_run_cmd $QEMU_IMG compare $L "${TEST_IMG}" "${TEST_IMG}"
+_run_cmd $QEMU_IMG map $L "${TEST_IMG}"
+_run_cmd $QEMU_IMG amend -o "" $L "${TEST_IMG}"
+_run_cmd $QEMU_IMG commit  $L "${TEST_IMG}"
+_run_cmd $QEMU_IMG resize  $L "${TEST_IMG}" $size
+_run_cmd $QEMU_IMG rebase  $L "${TEST_IMG}" -b "${TEST_IMG}.base"
+_run_cmd $QEMU_IMG snapshot -l $L "${TEST_IMG}"
+_run_cmd $QEMU_IMG convert $L "${TEST_IMG}" "${TEST_IMG}.convert"
+_run_cmd $QEMU_IMG dd  $L if="${TEST_IMG}" 
of="${TEST_IMG}.convert" bs=512 count=1
+_run_cmd $QEMU_IMG bench   $L -c 1 "${TEST_IMG}"
+_run_cmd $QEMU_IMG bench   $L -w -c 1 "${TEST_IMG}"
+done
+_send_qemu_cmd $h "{ 'execute': 'quit', }" ""
+echo
+echo "Round done"
+_cleanup_qemu
+done
+
+for opt1 in $test_opts; do
+for opt2 in $test_opts; do
+echo
+echo "== Two devices with the same image ($opt1 - $opt2) =="
+_run_qemu_with_images "${TEST_IMG},$opt1" "${TEST_IMG},$opt2"
+done
+done
+
+echo "== Creating ${TEST_IMG}.[abc] =="
+(
+$QEMU_IMG create -f qcow2 "${TEST_IMG}.a" -b "${TEST_IMG}"
+$QEMU_IMG create -f qcow2 "${TEST_IMG}.b" -b "${TEST_IMG}"
+$QEMU_IMG create -f qcow2 "${TEST_IMG}.c" -b "${TEST_IMG}.b"
+) | _filter_img_create
+
+echo
+echo "== Two devices sharing the same file in ba

[Qemu-devel] [PATCH v14 15/20] file-posix: Add 'locking' option

2017-04-20 Thread Fam Zheng
Making this option available even before implementing it will let
converting tests easier: in coming patches they can specify the option
already when necessary, before we actually write code to lock the
images.

Signed-off-by: Fam Zheng 
---
 block/file-posix.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/block/file-posix.c b/block/file-posix.c
index ade71db..2114720 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -392,6 +392,11 @@ static QemuOptsList raw_runtime_opts = {
 .type = QEMU_OPT_STRING,
 .help = "host AIO implementation (threads, native)",
 },
+{
+.name = "locking",
+.type = QEMU_OPT_BOOL,
+.help = "lock the file",
+},
 { /* end of list */ }
 },
 };
-- 
2.9.3




[Qemu-devel] [PATCH v14 17/20] block: Reuse bs as backing hd for drive-backup sync=none

2017-04-20 Thread Fam Zheng
Signed-off-by: Fam Zheng 
---
 blockdev.c | 15 ++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/blockdev.c b/blockdev.c
index 4927914..4e04dec 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -3174,6 +3174,7 @@ static BlockJob *do_drive_backup(DriveBackup *backup, 
BlockJobTxn *txn,
 Error *local_err = NULL;
 int flags;
 int64_t size;
+bool set_backing_hd = false;
 
 if (!backup->has_speed) {
 backup->speed = 0;
@@ -3224,6 +3225,8 @@ static BlockJob *do_drive_backup(DriveBackup *backup, 
BlockJobTxn *txn,
 }
 if (backup->sync == MIRROR_SYNC_MODE_NONE) {
 source = bs;
+flags |= BDRV_O_NO_BACKING;
+set_backing_hd = true;
 }
 
 size = bdrv_getlength(bs);
@@ -3250,7 +3253,9 @@ static BlockJob *do_drive_backup(DriveBackup *backup, 
BlockJobTxn *txn,
 }
 
 if (backup->format) {
-options = qdict_new();
+if (!options) {
+options = qdict_new();
+}
 qdict_put(options, "driver", qstring_from_str(backup->format));
 }
 
@@ -3261,6 +3266,14 @@ static BlockJob *do_drive_backup(DriveBackup *backup, 
BlockJobTxn *txn,
 
 bdrv_set_aio_context(target_bs, aio_context);
 
+if (set_backing_hd) {
+bdrv_set_backing_hd(target_bs, source, &local_err);
+if (local_err) {
+bdrv_unref(target_bs);
+goto out;
+}
+}
+
 if (backup->has_bitmap) {
 bmap = bdrv_find_dirty_bitmap(bs, backup->bitmap);
 if (!bmap) {
-- 
2.9.3




[Qemu-devel] [PATCH v14 12/20] iotests: 091: Quit QEMU before checking image

2017-04-20 Thread Fam Zheng
Signed-off-by: Fam Zheng 
Reviewed-by: Max Reitz 
---
 tests/qemu-iotests/091 | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/tests/qemu-iotests/091 b/tests/qemu-iotests/091
index 32bbd56..10ac4a8 100755
--- a/tests/qemu-iotests/091
+++ b/tests/qemu-iotests/091
@@ -95,7 +95,9 @@ echo "vm2: qemu process running successfully"
 echo "vm2: flush io, and quit"
 _send_qemu_cmd $h2 'qemu-io disk flush' "(qemu)"
 _send_qemu_cmd $h2 'quit' ""
+_send_qemu_cmd $h1 'quit' ""
 
+wait
 echo "Check image pattern"
 ${QEMU_IO} -c "read -P 0x22 0 4M" "${TEST_IMG}" | _filter_testdir | 
_filter_qemu_io
 
-- 
2.9.3




[Qemu-devel] [PATCH v14 14/20] tests: Use null-co:// instead of /dev/null as the dummy image

2017-04-20 Thread Fam Zheng
Signed-off-by: Fam Zheng 
Reviewed-by: Max Reitz 
---
 tests/drive_del-test.c| 2 +-
 tests/nvme-test.c | 2 +-
 tests/usb-hcd-uhci-test.c | 2 +-
 tests/usb-hcd-xhci-test.c | 2 +-
 tests/virtio-blk-test.c   | 2 +-
 tests/virtio-scsi-test.c  | 4 ++--
 6 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/tests/drive_del-test.c b/tests/drive_del-test.c
index 121b9c9..2175139 100644
--- a/tests/drive_del-test.c
+++ b/tests/drive_del-test.c
@@ -92,7 +92,7 @@ static void test_after_failed_device_add(void)
 static void test_drive_del_device_del(void)
 {
 /* Start with a drive used by a device that unplugs instantaneously */
-qtest_start("-drive if=none,id=drive0,file=/dev/null,format=raw"
+qtest_start("-drive if=none,id=drive0,file=null-co://,format=raw"
 " -device virtio-scsi-pci"
 " -device scsi-hd,drive=drive0,id=dev0");
 
diff --git a/tests/nvme-test.c b/tests/nvme-test.c
index c8bece4..7674a44 100644
--- a/tests/nvme-test.c
+++ b/tests/nvme-test.c
@@ -22,7 +22,7 @@ int main(int argc, char **argv)
 g_test_init(&argc, &argv, NULL);
 qtest_add_func("/nvme/nop", nop);
 
-qtest_start("-drive id=drv0,if=none,file=/dev/null,format=raw "
+qtest_start("-drive id=drv0,if=none,file=null-co://,format=raw "
 "-device nvme,drive=drv0,serial=foo");
 ret = g_test_run();
 
diff --git a/tests/usb-hcd-uhci-test.c b/tests/usb-hcd-uhci-test.c
index f25bae5..5b500fe 100644
--- a/tests/usb-hcd-uhci-test.c
+++ b/tests/usb-hcd-uhci-test.c
@@ -79,7 +79,7 @@ int main(int argc, char **argv)
 {
 const char *arch = qtest_get_arch();
 const char *cmd = "-device piix3-usb-uhci,id=uhci,addr=1d.0"
-  " -drive id=drive0,if=none,file=/dev/null,format=raw"
+  " -drive id=drive0,if=none,file=null-co://,format=raw"
   " -device usb-tablet,bus=uhci.0,port=1";
 int ret;
 
diff --git a/tests/usb-hcd-xhci-test.c b/tests/usb-hcd-xhci-test.c
index 22513e9..031764d 100644
--- a/tests/usb-hcd-xhci-test.c
+++ b/tests/usb-hcd-xhci-test.c
@@ -89,7 +89,7 @@ int main(int argc, char **argv)
 qtest_add_func("/xhci/pci/hotplug/usb-uas", test_usb_uas_hotplug);
 
 qtest_start("-device nec-usb-xhci,id=xhci"
-" -drive id=drive0,if=none,file=/dev/null,format=raw");
+" -drive id=drive0,if=none,file=null-co://,format=raw");
 ret = g_test_run();
 qtest_end();
 
diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c
index 1eee95d..fd2078c 100644
--- a/tests/virtio-blk-test.c
+++ b/tests/virtio-blk-test.c
@@ -63,7 +63,7 @@ static QOSState *pci_test_start(void)
 const char *arch = qtest_get_arch();
 char *tmp_path;
 const char *cmd = "-drive if=none,id=drive0,file=%s,format=raw "
-  "-drive if=none,id=drive1,file=/dev/null,format=raw "
+  "-drive if=none,id=drive1,file=null-co://,format=raw "
   "-device virtio-blk-pci,id=drv0,drive=drive0,"
   "addr=%x.%x";
 
diff --git a/tests/virtio-scsi-test.c b/tests/virtio-scsi-test.c
index 0eabd56..5e2ff14 100644
--- a/tests/virtio-scsi-test.c
+++ b/tests/virtio-scsi-test.c
@@ -35,7 +35,7 @@ typedef struct {
 static QOSState *qvirtio_scsi_start(const char *extra_opts)
 {
 const char *arch = qtest_get_arch();
-const char *cmd = "-drive id=drv0,if=none,file=/dev/null,format=raw "
+const char *cmd = "-drive id=drv0,if=none,file=null-co://,format=raw "
   "-device virtio-scsi-pci,id=vs0 "
   "-device scsi-hd,bus=vs0.0,drive=drv0 %s";
 
@@ -195,7 +195,7 @@ static void hotplug(void)
 QDict *response;
 QOSState *qs;
 
-qs = qvirtio_scsi_start("-drive 
id=drv1,if=none,file=/dev/null,format=raw");
+qs = qvirtio_scsi_start("-drive 
id=drv1,if=none,file=null-co://,format=raw");
 response = qmp("{\"execute\": \"device_add\","
" \"arguments\": {"
"   \"driver\": \"scsi-hd\","
-- 
2.9.3




[Qemu-devel] [PATCH v14 18/20] osdep: Add qemu_lock_fd and qemu_unlock_fd

2017-04-20 Thread Fam Zheng
They are wrappers of POSIX fcntl "file private locking", with a
convenient "try lock" wrapper implemented with F_OFD_GETLK.

Signed-off-by: Fam Zheng 
Reviewed-by: Max Reitz 
---
 include/qemu/osdep.h |  3 +++
 util/osdep.c | 48 
 2 files changed, 51 insertions(+)

diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 122ff06..1c9f5e2 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -341,6 +341,9 @@ int qemu_close(int fd);
 #ifndef _WIN32
 int qemu_dup(int fd);
 #endif
+int qemu_lock_fd(int fd, int64_t start, int64_t len, bool exclusive);
+int qemu_unlock_fd(int fd, int64_t start, int64_t len);
+int qemu_lock_fd_test(int fd, int64_t start, int64_t len, bool exclusive);
 
 #if defined(__HAIKU__) && defined(__i386__)
 #define FMT_pid "%ld"
diff --git a/util/osdep.c b/util/osdep.c
index 06fb1cf..3de4a18 100644
--- a/util/osdep.c
+++ b/util/osdep.c
@@ -140,6 +140,54 @@ static int qemu_parse_fdset(const char *param)
 {
 return qemu_parse_fd(param);
 }
+
+static int qemu_lock_fcntl(int fd, int64_t start, int64_t len, int fl_type)
+{
+#ifdef F_OFD_SETLK
+int ret;
+struct flock fl = {
+.l_whence = SEEK_SET,
+.l_start  = start,
+.l_len= len,
+.l_type   = fl_type,
+};
+ret = fcntl(fd, F_OFD_SETLK, &fl);
+return ret == -1 ? -errno : 0;
+#else
+return -ENOTSUP;
+#endif
+}
+
+int qemu_lock_fd(int fd, int64_t start, int64_t len, bool exclusive)
+{
+return qemu_lock_fcntl(fd, start, len, exclusive ? F_WRLCK : F_RDLCK);
+}
+
+int qemu_unlock_fd(int fd, int64_t start, int64_t len)
+{
+return qemu_lock_fcntl(fd, start, len, F_UNLCK);
+}
+
+int qemu_lock_fd_test(int fd, int64_t start, int64_t len, bool exclusive)
+{
+#ifdef F_OFD_SETLK
+int ret;
+struct flock fl = {
+.l_whence = SEEK_SET,
+.l_start  = start,
+.l_len= len,
+.l_type   = exclusive ? F_WRLCK : F_RDLCK,
+};
+ret = fcntl(fd, F_OFD_GETLK, &fl);
+if (ret == -1) {
+return -errno;
+} else {
+return fl.l_type == F_UNLCK ? 0 : -EAGAIN;
+}
+#else
+return -ENOTSUP;
+#endif
+}
 #endif
 
 /*
-- 
2.9.3




[Qemu-devel] [PATCH v14 09/20] iotests: 055: Don't attach the target image already for drive-backup

2017-04-20 Thread Fam Zheng
Double attach is not a valid usage of the target image, drive-backup
will open the blockdev itself so skip the add_drive call in this case.

Signed-off-by: Fam Zheng 
Reviewed-by: Max Reitz 
---
 tests/qemu-iotests/055 | 32 ++--
 1 file changed, 18 insertions(+), 14 deletions(-)

diff --git a/tests/qemu-iotests/055 b/tests/qemu-iotests/055
index aafcd24..ba4da65 100755
--- a/tests/qemu-iotests/055
+++ b/tests/qemu-iotests/055
@@ -458,17 +458,18 @@ class TestDriveCompression(iotests.QMPTestCase):
 except OSError:
 pass
 
-def do_prepare_drives(self, fmt, args):
+def do_prepare_drives(self, fmt, args, attach_target):
 self.vm = iotests.VM().add_drive(test_img)
 
 qemu_img('create', '-f', fmt, blockdev_target_img,
  str(TestDriveCompression.image_len), *args)
-self.vm.add_drive(blockdev_target_img, format=fmt, interface="none")
+if attach_target:
+self.vm.add_drive(blockdev_target_img, format=fmt, 
interface="none")
 
 self.vm.launch()
 
-def do_test_compress_complete(self, cmd, format, **args):
-self.do_prepare_drives(format['type'], format['args'])
+def do_test_compress_complete(self, cmd, format, attach_target, **args):
+self.do_prepare_drives(format['type'], format['args'], attach_target)
 
 self.assert_no_active_block_jobs()
 
@@ -484,15 +485,16 @@ class TestDriveCompression(iotests.QMPTestCase):
 
 def test_complete_compress_drive_backup(self):
 for format in TestDriveCompression.fmt_supports_compression:
-self.do_test_compress_complete('drive-backup', format,
+self.do_test_compress_complete('drive-backup', format, False,
target=blockdev_target_img, 
mode='existing')
 
 def test_complete_compress_blockdev_backup(self):
 for format in TestDriveCompression.fmt_supports_compression:
-self.do_test_compress_complete('blockdev-backup', format, 
target='drive1')
+self.do_test_compress_complete('blockdev-backup', format, True,
+   target='drive1')
 
-def do_test_compress_cancel(self, cmd, format, **args):
-self.do_prepare_drives(format['type'], format['args'])
+def do_test_compress_cancel(self, cmd, format, attach_target, **args):
+self.do_prepare_drives(format['type'], format['args'], attach_target)
 
 self.assert_no_active_block_jobs()
 
@@ -506,15 +508,16 @@ class TestDriveCompression(iotests.QMPTestCase):
 
 def test_compress_cancel_drive_backup(self):
 for format in TestDriveCompression.fmt_supports_compression:
-self.do_test_compress_cancel('drive-backup', format,
+self.do_test_compress_cancel('drive-backup', format, False,
  target=blockdev_target_img, 
mode='existing')
 
 def test_compress_cancel_blockdev_backup(self):
for format in TestDriveCompression.fmt_supports_compression:
-self.do_test_compress_cancel('blockdev-backup', format, 
target='drive1')
+self.do_test_compress_cancel('blockdev-backup', format, True,
+ target='drive1')
 
-def do_test_compress_pause(self, cmd, format, **args):
-self.do_prepare_drives(format['type'], format['args'])
+def do_test_compress_pause(self, cmd, format, attach_target, **args):
+self.do_prepare_drives(format['type'], format['args'], attach_target)
 
 self.assert_no_active_block_jobs()
 
@@ -546,12 +549,13 @@ class TestDriveCompression(iotests.QMPTestCase):
 
 def test_compress_pause_drive_backup(self):
 for format in TestDriveCompression.fmt_supports_compression:
-self.do_test_compress_pause('drive-backup', format,
+self.do_test_compress_pause('drive-backup', format, False,
 target=blockdev_target_img, 
mode='existing')
 
 def test_compress_pause_blockdev_backup(self):
 for format in TestDriveCompression.fmt_supports_compression:
-self.do_test_compress_pause('blockdev-backup', format, 
target='drive1')
+self.do_test_compress_pause('blockdev-backup', format, True,
+target='drive1')
 
 if __name__ == '__main__':
 iotests.main(supported_fmts=['raw', 'qcow2'])
-- 
2.9.3




[Qemu-devel] [PATCH v14 19/20] file-posix: Add image locking in perm operations

2017-04-20 Thread Fam Zheng
virtlockd in libvirt locks the first byte, so we start looking at the
file bytes from 0x10.

The complication is in the transactional interface.  To make the reopen
logic managable, and allow better reuse, the code is internally
organized with a table from old mode to the new one.

Signed-off-by: Fam Zheng 
---
 block/file-posix.c | 739 -
 1 file changed, 736 insertions(+), 3 deletions(-)

diff --git a/block/file-posix.c b/block/file-posix.c
index 2114720..c307493 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -129,8 +129,54 @@ do { \
 
 #define MAX_BLOCKSIZE  4096
 
+/* Posix file locking bytes. Libvirt takes byte 0, we start from byte 0x10,
+ * leaving a few more bytes for its future use. */
+#define RAW_LOCK_BYTE_MIN 0x10
+#define RAW_LOCK_BYTE_NO_OTHER_WRITER 0x10
+#define RAW_LOCK_BYTE_WRITE   0x11
+#ifdef F_OFD_SETLK
+#define RAW_LOCK_SUPPORTED 1
+#else
+#define RAW_LOCK_SUPPORTED 0
+#endif
+
+/*
+ ** reader that can tolerate writers: Don't do anything
+ *
+ ** reader that can't tolerate writers: Take shared lock on byte 0x10. Test
+ *  byte 0x11 is unlocked.
+ *
+ ** shared writer: Take shared lock on byte 0x11. Test byte 0x10 is unlocked.
+ *
+ ** exclusive writer: Take exclusive locks on both bytes.
+ */
+
+typedef enum {
+/* Read only and accept other writers. */
+RAW_L_READ_SHARE_RW,
+/* Read only and try to forbid other writers. */
+RAW_L_READ,
+/* Read/write and accept other writers. */
+RAW_L_WRITE_SHARE_RW,
+/* Read/write and try to forbid other writers. */
+RAW_L_WRITE,
+} BDRVRawLockMode;
+
+typedef struct BDRVRawLockUpdateState {
+/* A dup of @fd used for acquiring lock. */
+int image_fd;
+int lock_fd;
+int open_flags;
+BDRVRawLockMode new_lock;
+bool use_lock;
+} BDRVRawLockUpdateState;
+
 typedef struct BDRVRawState {
 int fd;
+/* A dup of @fd to make manipulating lock easier, especially during reopen,
+ * where this will accept BDRVRawReopenState.lock_fd. */
+int lock_fd;
+bool use_lock;
 int type;
 int open_flags;
 size_t buf_align;
@@ -145,6 +191,11 @@ typedef struct BDRVRawState {
 bool page_cache_inconsistent:1;
 bool has_fallocate;
 bool needs_alignment;
+/* The current lock mode we are in. Note that in incoming migration this is
+ * the "desired" mode to be applied at bdrv_invalidate_cache. */
+BDRVRawLockMode cur_lock_mode;
+/* Used by raw_check_perm/raw_set_perm. */
+BDRVRawLockUpdateState *lock_update;
 } BDRVRawState;
 
 typedef struct BDRVRawReopenState {
@@ -367,6 +418,59 @@ static void raw_parse_flags(int bdrv_flags, int 
*open_flags)
 }
 }
 
+static int raw_lock_fd(int fd, BDRVRawLockMode mode, Error **errp)
+{
+int ret;
+assert(fd >= 0);
+assert(RAW_LOCK_SUPPORTED);
+switch (mode) {
+case RAW_L_READ_SHARE_RW:
+ret = qemu_unlock_fd(fd, RAW_LOCK_BYTE_MIN, 2);
+if (ret) {
+error_setg_errno(errp, -ret, "Failed to unlock fd");
+goto fail;
+}
+break;
+case RAW_L_READ:
+ret = qemu_lock_fd(fd, RAW_LOCK_BYTE_NO_OTHER_WRITER, 1, false);
+if (ret) {
+error_setg_errno(errp, -ret, "Failed to lock share byte");
+goto fail;
+}
+ret = qemu_lock_fd_test(fd, RAW_LOCK_BYTE_WRITE, 1, true);
+if (ret) {
+error_setg_errno(errp, -ret, "Write byte lock is taken");
+goto fail;
+}
+break;
+case RAW_L_WRITE_SHARE_RW:
+ret = qemu_lock_fd(fd, RAW_LOCK_BYTE_WRITE, 1, false);
+if (ret) {
+error_setg_errno(errp, -ret, "Failed to lock write byte");
+goto fail;
+}
+ret = qemu_lock_fd_test(fd, RAW_LOCK_BYTE_NO_OTHER_WRITER, 1, true);
+if (ret) {
+error_setg_errno(errp, -ret, "Share byte lock is taken");
+goto fail;
+}
+break;
+case RAW_L_WRITE:
+ret = qemu_lock_fd(fd, RAW_LOCK_BYTE_MIN, 2, true);
+if (ret) {
+error_setg_errno(errp, -ret, "Failed to lock image");
+goto fail;
+}
+break;
+default:
+abort();
+}
+return 0;
+fail:
+qemu_unlock_fd(fd, RAW_LOCK_BYTE_MIN, 2);
+return ret;
+}
+
 static void raw_parse_filename(const char *filename, QDict *options,
Error **errp)
 {
@@ -401,6 +505,23 @@ static QemuOptsList raw_runtime_opts = {
 },
 };
 
+static BDRVRawLockMode raw_get_lock_mode(bool write, bool shared)
+{
+if (write) {
+if (shared) {
+return RAW_L_WRITE_SHARE_RW;
+} else {
+return RAW_L_WRITE;
+}
+} else {
+if (shared) {
+return RAW_L_READ_SHARE_RW;
+} else {
+return RAW_L_READ;
+}
+}
+}
+
 static int raw_open_common(BlockDriverState *bs, QDict *options,

[Qemu-devel] [PATCH v14 11/20] iotests: 087: Don't attach test image twice

2017-04-20 Thread Fam Zheng
The test scenario doesn't require the same image, instead it focuses on
the duplicated node-name, so use null-co to avoid locking conflict.

Reviewed-by: Max Reitz 
Signed-off-by: Fam Zheng 
---
 tests/qemu-iotests/087 | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/tests/qemu-iotests/087 b/tests/qemu-iotests/087
index 9de57dd..6d52f7d 100755
--- a/tests/qemu-iotests/087
+++ b/tests/qemu-iotests/087
@@ -82,8 +82,7 @@ run_qemu -drive 
driver=$IMGFMT,id=disk,node-name=test-node,file="$TEST_IMG" <

[Qemu-devel] [PATCH v14 13/20] iotests: 172: Use separate images for multiple devices

2017-04-20 Thread Fam Zheng
To avoid image lock failures.

Signed-off-by: Fam Zheng 
---
 tests/qemu-iotests/172 | 55 +-
 tests/qemu-iotests/172.out | 50 +
 2 files changed, 56 insertions(+), 49 deletions(-)

diff --git a/tests/qemu-iotests/172 b/tests/qemu-iotests/172
index 1b7d3a1..826d6fe 100755
--- a/tests/qemu-iotests/172
+++ b/tests/qemu-iotests/172
@@ -30,6 +30,8 @@ status=1  # failure is the default!
 _cleanup()
 {
_cleanup_test_img
+rm -f "$TEST_IMG.2"
+rm -f "$TEST_IMG.3"
 }
 trap "_cleanup; exit \$status" 0 1 2 3 15
 
@@ -86,6 +88,9 @@ size=720k
 
 _make_test_img $size
 
+TEST_IMG="$TEST_IMG.2" _make_test_img $size
+TEST_IMG="$TEST_IMG.3" _make_test_img $size
+
 # Default drive semantics:
 #
 # By default you get a single empty floppy drive. You can override it with
@@ -105,7 +110,7 @@ echo === Using -fda/-fdb options ===
 
 check_floppy_qtree -fda "$TEST_IMG"
 check_floppy_qtree -fdb "$TEST_IMG"
-check_floppy_qtree -fda "$TEST_IMG" -fdb "$TEST_IMG"
+check_floppy_qtree -fda "$TEST_IMG" -fdb "$TEST_IMG.2"
 
 
 echo
@@ -114,7 +119,7 @@ echo === Using -drive options ===
 
 check_floppy_qtree -drive if=floppy,file="$TEST_IMG"
 check_floppy_qtree -drive if=floppy,file="$TEST_IMG",index=1
-check_floppy_qtree -drive if=floppy,file="$TEST_IMG" -drive 
if=floppy,file="$TEST_IMG",index=1
+check_floppy_qtree -drive if=floppy,file="$TEST_IMG" -drive 
if=floppy,file="$TEST_IMG.2",index=1
 
 echo
 echo
@@ -122,7 +127,7 @@ echo === Using -drive if=none and -global ===
 
 check_floppy_qtree -drive if=none,file="$TEST_IMG" -global isa-fdc.driveA=none0
 check_floppy_qtree -drive if=none,file="$TEST_IMG" -global isa-fdc.driveB=none0
-check_floppy_qtree -drive if=none,file="$TEST_IMG" -drive 
if=none,file="$TEST_IMG" \
+check_floppy_qtree -drive if=none,file="$TEST_IMG" -drive 
if=none,file="$TEST_IMG.2" \
-global isa-fdc.driveA=none0 -global isa-fdc.driveB=none1
 
 echo
@@ -131,7 +136,7 @@ echo === Using -drive if=none and -device ===
 
 check_floppy_qtree -drive if=none,file="$TEST_IMG" -device floppy,drive=none0
 check_floppy_qtree -drive if=none,file="$TEST_IMG" -device 
floppy,drive=none0,unit=1
-check_floppy_qtree -drive if=none,file="$TEST_IMG" -drive 
if=none,file="$TEST_IMG" \
+check_floppy_qtree -drive if=none,file="$TEST_IMG" -drive 
if=none,file="$TEST_IMG.2" \
-device floppy,drive=none0 -device floppy,drive=none1,unit=1
 
 echo
@@ -139,58 +144,58 @@ echo
 echo === Mixing -fdX and -global ===
 
 # Working
-check_floppy_qtree -fda "$TEST_IMG" -drive if=none,file="$TEST_IMG" -global 
isa-fdc.driveB=none0
-check_floppy_qtree -fdb "$TEST_IMG" -drive if=none,file="$TEST_IMG" -global 
isa-fdc.driveA=none0
+check_floppy_qtree -fda "$TEST_IMG" -drive if=none,file="$TEST_IMG.2" -global 
isa-fdc.driveB=none0
+check_floppy_qtree -fdb "$TEST_IMG" -drive if=none,file="$TEST_IMG.2" -global 
isa-fdc.driveA=none0
 
 # Conflicting (-fdX wins)
-check_floppy_qtree -fda "$TEST_IMG" -drive if=none,file="$TEST_IMG" -global 
isa-fdc.driveA=none0
-check_floppy_qtree -fdb "$TEST_IMG" -drive if=none,file="$TEST_IMG" -global 
isa-fdc.driveB=none0
+check_floppy_qtree -fda "$TEST_IMG" -drive if=none,file="$TEST_IMG.2" -global 
isa-fdc.driveA=none0
+check_floppy_qtree -fdb "$TEST_IMG" -drive if=none,file="$TEST_IMG.2" -global 
isa-fdc.driveB=none0
 
 echo
 echo
 echo === Mixing -fdX and -device ===
 
 # Working
-check_floppy_qtree -fda "$TEST_IMG" -drive if=none,file="$TEST_IMG" -device 
floppy,drive=none0
-check_floppy_qtree -fda "$TEST_IMG" -drive if=none,file="$TEST_IMG" -device 
floppy,drive=none0,unit=1
+check_floppy_qtree -fda "$TEST_IMG" -drive if=none,file="$TEST_IMG.2" -device 
floppy,drive=none0
+check_floppy_qtree -fda "$TEST_IMG" -drive if=none,file="$TEST_IMG.2" -device 
floppy,drive=none0,unit=1
 
-check_floppy_qtree -fdb "$TEST_IMG" -drive if=none,file="$TEST_IMG" -device 
floppy,drive=none0
-check_floppy_qtree -fdb "$TEST_IMG" -drive if=none,file="$TEST_IMG" -device 
floppy,drive=none0,unit=0
+check_floppy_qtree -fdb "$TEST_IMG" -drive if=none,file="$TEST_IMG.2" -device 
floppy,drive=none0
+check_floppy_qtree -fdb "$TEST_IMG" -drive if=none,file="$TEST_IMG.2" -device 
floppy,drive=none0,unit=0
 
 # Conflicting
-check_floppy_qtree -fda "$TEST_IMG" -drive if=none,file="$TEST_IMG" -device 
floppy,drive=none0,unit=0
-check_floppy_qtree -fdb "$TEST_IMG" -drive if=none,file="$TEST_IMG" -device 
floppy,drive=none0,unit=1
+check_floppy_qtree -fda "$TEST_IMG" -drive if=none,file="$TEST_IMG.2" -device 
floppy,drive=none0,unit=0
+check_floppy_qtree -fdb "$TEST_IMG" -drive if=none,file="$TEST_IMG.2" -device 
floppy,drive=none0,unit=1
 
 echo
 echo
 echo === Mixing -drive and -device ===
 
 # Working
-check_floppy_qtree -drive if=floppy,file="$TEST_IMG" -drive 
if=none,file="$TEST_IMG" -device floppy,drive=none0
-check_floppy_qtree -drive if=floppy,file="$TEST_IMG" -drive 
if=none,file="$TEST_IMG" -device floppy

[Qemu-devel] [PATCH v14 16/20] tests: Disable image lock in test-replication

2017-04-20 Thread Fam Zheng
The COLO block replication architecture requires one disk to be shared
between primary and secondary, in the test both processes use posix file
protocol (instead of over NBD) so it is affected by image locking.
Disable the lock.

Signed-off-by: Fam Zheng 
---
 tests/test-replication.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/tests/test-replication.c b/tests/test-replication.c
index fac2da3..e1c4235 100644
--- a/tests/test-replication.c
+++ b/tests/test-replication.c
@@ -179,7 +179,8 @@ static BlockBackend *start_primary(void)
 char *cmdline;
 
 cmdline = g_strdup_printf("driver=replication,mode=primary,node-name=xxx,"
-  "file.driver=qcow2,file.file.filename=%s"
+  "file.driver=qcow2,file.file.filename=%s,"
+  "file.file.locking=off"
   , p_local_disk);
 opts = qemu_opts_parse_noisily(&qemu_drive_opts, cmdline, false);
 g_free(cmdline);
@@ -310,7 +311,9 @@ static BlockBackend *start_secondary(void)
 Error *local_err = NULL;
 
 /* add s_local_disk and forge S_LOCAL_DISK_ID */
-cmdline = g_strdup_printf("file.filename=%s,driver=qcow2", s_local_disk);
+cmdline = g_strdup_printf("file.filename=%s,driver=qcow2,"
+  "file.locking=off",
+  s_local_disk);
 opts = qemu_opts_parse_noisily(&qemu_drive_opts, cmdline, false);
 g_free(cmdline);
 
@@ -331,8 +334,10 @@ static BlockBackend *start_secondary(void)
 /* add S_(ACTIVE/HIDDEN)_DISK and forge S_ID */
 cmdline = g_strdup_printf("driver=replication,mode=secondary,top-id=%s,"
   "file.driver=qcow2,file.file.filename=%s,"
+  "file.file.locking=off,"
   "file.backing.driver=qcow2,"
   "file.backing.file.filename=%s,"
+  "file.backing.file.locking=off,"
   "file.backing.backing=%s"
   , S_ID, s_active_disk, s_hidden_disk
   , S_LOCAL_DISK_ID);
-- 
2.9.3




[Qemu-devel] [PATCH v14 10/20] iotests: 085: Avoid image locking conflict

2017-04-20 Thread Fam Zheng
In the case where we test the expected error when a blockdev-snapshot
target already has a backing image, the backing chain is opened multiple
times. This will be a problem when we use image locking, so use a
different backing file that is not already open.

Signed-off-by: Fam Zheng 
---
 tests/qemu-iotests/085 | 34 --
 tests/qemu-iotests/085.out |  3 ++-
 2 files changed, 22 insertions(+), 15 deletions(-)

diff --git a/tests/qemu-iotests/085 b/tests/qemu-iotests/085
index c53e97f..cc6efd8 100755
--- a/tests/qemu-iotests/085
+++ b/tests/qemu-iotests/085
@@ -45,7 +45,7 @@ _cleanup()
 rm -f "${TEST_DIR}/${i}-${snapshot_virt0}"
 rm -f "${TEST_DIR}/${i}-${snapshot_virt1}"
 done
-rm -f "${TEST_IMG}.1" "${TEST_IMG}.2"
+rm -f "${TEST_IMG}" "${TEST_IMG}.1" "${TEST_IMG}.2" "${TEST_IMG}.base"
 
 }
 trap "_cleanup; exit \$status" 0 1 2 3 15
@@ -87,24 +87,26 @@ function create_group_snapshot()
 }
 
 # ${1}: unique identifier for the snapshot filename
-# ${2}: true: open backing images; false: don't open them (default)
+# ${2}: extra_params to the blockdev-add command
+# ${3}: filename
+function do_blockdev_add()
+{
+cmd="{ 'execute': 'blockdev-add', 'arguments':
+   { 'driver': 'qcow2', 'node-name': 'snap_${1}', ${2}
+ 'file':
+ { 'driver': 'file', 'filename': '${3}',
+   'node-name': 'file_${1}' } } }"
+_send_qemu_cmd $h "${cmd}" "return"
+}
+
+# ${1}: unique identifier for the snapshot filename
 function add_snapshot_image()
 {
-if [ "${2}" = "true" ]; then
-extra_params=""
-else
-extra_params="'backing': '', "
-fi
 base_image="${TEST_DIR}/$((${1}-1))-${snapshot_virt0}"
 snapshot_file="${TEST_DIR}/${1}-${snapshot_virt0}"
 _make_test_img -b "${base_image}" "$size"
 mv "${TEST_IMG}" "${snapshot_file}"
-cmd="{ 'execute': 'blockdev-add', 'arguments':
-   { 'driver': 'qcow2', 'node-name': 'snap_${1}', ${extra_params}
- 'file':
- { 'driver': 'file', 'filename': '${snapshot_file}',
-   'node-name': 'file_${1}' } } }"
-_send_qemu_cmd $h "${cmd}" "return"
+do_blockdev_add "$1" "'backing': '', " "${snapshot_file}"
 }
 
 # ${1}: unique identifier for the snapshot filename
@@ -222,7 +224,11 @@ echo === Invalid command - snapshot node has a backing 
image ===
 echo
 
 SNAPSHOTS=$((${SNAPSHOTS}+1))
-add_snapshot_image ${SNAPSHOTS} true
+
+_make_test_img "$size"
+mv "${TEST_IMG}" "${TEST_IMG}.base"
+_make_test_img -b "${TEST_IMG}.base" "$size"
+do_blockdev_add ${SNAPSHOTS} "" "${TEST_IMG}"
 blockdev_snapshot ${SNAPSHOTS} error
 
 echo
diff --git a/tests/qemu-iotests/085.out b/tests/qemu-iotests/085.out
index 182acb4..65b0f68 100644
--- a/tests/qemu-iotests/085.out
+++ b/tests/qemu-iotests/085.out
@@ -78,7 +78,8 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 
backing_file=TEST_DIR/
 
 === Invalid command - snapshot node has a backing image ===
 
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 
backing_file=TEST_DIR/12-snapshot-v0.IMGFMT
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 
backing_file=TEST_DIR/t.IMGFMT.base
 {"return": {}}
 {"error": {"class": "GenericError", "desc": "The snapshot already has a 
backing image"}}
 
-- 
2.9.3




[Qemu-devel] [PATCH v14 04/20] qemu-img: Add --share-rw option to subcommands

2017-04-20 Thread Fam Zheng
Similar to share-rw qdev property, this will force the opened images to
allow shared write permission of other programs.

Signed-off-by: Fam Zheng 
---
 qemu-img.c | 155 +++--
 1 file changed, 119 insertions(+), 36 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index ed24371..df88a79 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -28,6 +28,7 @@
 #include "qapi/qobject-output-visitor.h"
 #include "qapi/qmp/qerror.h"
 #include "qapi/qmp/qjson.h"
+#include "qapi/qmp/qbool.h"
 #include "qemu/cutils.h"
 #include "qemu/config-file.h"
 #include "qemu/option.h"
@@ -283,12 +284,15 @@ static int img_open_password(BlockBackend *blk, const 
char *filename,
 
 static BlockBackend *img_open_opts(const char *optstr,
QemuOpts *opts, int flags, bool 
writethrough,
-   bool quiet)
+   bool quiet, bool share_rw)
 {
 QDict *options;
 Error *local_err = NULL;
 BlockBackend *blk;
 options = qemu_opts_to_qdict(opts, NULL);
+if (share_rw) {
+qdict_put(options, BDRV_OPT_FORCE_SHARED_WRITE, qbool_from_bool(true));
+}
 blk = blk_new_open(NULL, NULL, options, flags, &local_err);
 if (!blk) {
 error_reportf_err(local_err, "Could not open '%s': ", optstr);
@@ -305,17 +309,19 @@ static BlockBackend *img_open_opts(const char *optstr,
 
 static BlockBackend *img_open_file(const char *filename,
const char *fmt, int flags,
-   bool writethrough, bool quiet)
+   bool writethrough, bool quiet, bool 
share_rw)
 {
 BlockBackend *blk;
 Error *local_err = NULL;
-QDict *options = NULL;
+QDict *options = qdict_new();
 
 if (fmt) {
-options = qdict_new();
 qdict_put(options, "driver", qstring_from_str(fmt));
 }
 
+if (share_rw) {
+qdict_put(options, BDRV_OPT_FORCE_SHARED_WRITE, qbool_from_bool(true));
+}
 blk = blk_new_open(filename, NULL, options, flags, &local_err);
 if (!blk) {
 error_reportf_err(local_err, "Could not open '%s': ", filename);
@@ -334,7 +340,7 @@ static BlockBackend *img_open_file(const char *filename,
 static BlockBackend *img_open(bool image_opts,
   const char *filename,
   const char *fmt, int flags, bool writethrough,
-  bool quiet)
+  bool quiet, bool share_rw)
 {
 BlockBackend *blk;
 if (image_opts) {
@@ -348,9 +354,9 @@ static BlockBackend *img_open(bool image_opts,
 if (!opts) {
 return NULL;
 }
-blk = img_open_opts(filename, opts, flags, writethrough, quiet);
+blk = img_open_opts(filename, opts, flags, writethrough, quiet, 
share_rw);
 } else {
-blk = img_open_file(filename, fmt, flags, writethrough, quiet);
+blk = img_open_file(filename, fmt, flags, writethrough, quiet, 
share_rw);
 }
 return blk;
 }
@@ -650,6 +656,7 @@ static int img_check(int argc, char **argv)
 ImageCheck *check;
 bool quiet = false;
 bool image_opts = false;
+bool share_rw = false;
 
 fmt = NULL;
 output = NULL;
@@ -664,9 +671,10 @@ static int img_check(int argc, char **argv)
 {"output", required_argument, 0, OPTION_OUTPUT},
 {"object", required_argument, 0, OPTION_OBJECT},
 {"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
+{"share-rw", no_argument, 0, 'U'},
 {0, 0, 0, 0}
 };
-c = getopt_long(argc, argv, ":hf:r:T:q",
+c = getopt_long(argc, argv, ":hf:r:T:qU",
 long_options, &option_index);
 if (c == -1) {
 break;
@@ -705,6 +713,9 @@ static int img_check(int argc, char **argv)
 case 'q':
 quiet = true;
 break;
+case 'U':
+share_rw = true;
+break;
 case OPTION_OBJECT: {
 QemuOpts *opts;
 opts = qemu_opts_parse_noisily(&qemu_object_opts,
@@ -744,7 +755,8 @@ static int img_check(int argc, char **argv)
 return 1;
 }
 
-blk = img_open(image_opts, filename, fmt, flags, writethrough, quiet);
+blk = img_open(image_opts, filename, fmt, flags, writethrough, quiet,
+   share_rw);
 if (!blk) {
 return 1;
 }
@@ -864,6 +876,7 @@ static int img_commit(int argc, char **argv)
 CommonBlockJobCBInfo cbi;
 bool image_opts = false;
 AioContext *aio_context;
+bool share_rw = false;
 
 fmt = NULL;
 cache = BDRV_DEFAULT_CACHE;
@@ -873,9 +886,10 @@ static int img_commit(int argc, char **argv)
 {"help", no_argument, 0, 'h'},
 {"object", required_argument, 0, OPTION_OBJECT},
 {"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
+{"share-rw", no_argument,

[Qemu-devel] [PATCH v14 05/20] qemu-img: Update documentation for --share-rw

2017-04-20 Thread Fam Zheng
Signed-off-by: Fam Zheng 
---
 qemu-img-cmds.hx | 48 
 1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 8ac7822..1b00bb8 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -10,15 +10,15 @@ STEXI
 ETEXI
 
 DEF("bench", img_bench,
-"bench [-c count] [-d depth] [-f fmt] [--flush-interval=flush_interval] 
[-n] [--no-drain] [-o offset] [--pattern=pattern] [-q] [-s buffer_size] [-S 
step_size] [-t cache] [-w] filename")
+"bench [-c count] [-d depth] [-f fmt] [--flush-interval=flush_interval] 
[-n] [--no-drain] [-o offset] [--pattern=pattern] [-q] [-s buffer_size] [-S 
step_size] [-t cache] [-w] [--share-rw] filename")
 STEXI
-@item bench [-c @var{count}] [-d @var{depth}] [-f @var{fmt}] 
[--flush-interval=@var{flush_interval}] [-n] [--no-drain] [-o @var{offset}] 
[--pattern=@var{pattern}] [-q] [-s @var{buffer_size}] [-S @var{step_size}] [-t 
@var{cache}] [-w] @var{filename}
+@item bench [-c @var{count}] [-d @var{depth}] [-f @var{fmt}] 
[--flush-interval=@var{flush_interval}] [-n] [--no-drain] [-o @var{offset}] 
[--pattern=@var{pattern}] [-q] [-s @var{buffer_size}] [-S @var{step_size}] [-t 
@var{cache}] [-w] [--share-rw] @var{filename}
 ETEXI
 
 DEF("check", img_check,
-"check [-q] [--object objectdef] [--image-opts] [-f fmt] [--output=ofmt] 
[-r [leaks | all]] [-T src_cache] filename")
+"check [-q] [--object objectdef] [--image-opts] [-f fmt] [--output=ofmt] 
[-r [leaks | all]] [-T src_cache] [--share-rw] filename")
 STEXI
-@item check [--object @var{objectdef}] [--image-opts] [-q] [-f @var{fmt}] 
[--output=@var{ofmt}] [-r [leaks | all]] [-T @var{src_cache}] @var{filename}
+@item check [--object @var{objectdef}] [--image-opts] [-q] [-f @var{fmt}] 
[--output=@var{ofmt}] [-r [leaks | all]] [-T @var{src_cache}] [--share-rw] 
@var{filename}
 ETEXI
 
 DEF("create", img_create,
@@ -28,62 +28,62 @@ STEXI
 ETEXI
 
 DEF("commit", img_commit,
-"commit [-q] [--object objectdef] [--image-opts] [-f fmt] [-t cache] [-b 
base] [-d] [-p] filename")
+"commit [-q] [--object objectdef] [--image-opts] [-f fmt] [-t cache] [-b 
base] [-d] [-p] [--share-rw] filename")
 STEXI
-@item commit [--object @var{objectdef}] [--image-opts] [-q] [-f @var{fmt}] [-t 
@var{cache}] [-b @var{base}] [-d] [-p] @var{filename}
+@item commit [--object @var{objectdef}] [--image-opts] [-q] [-f @var{fmt}] [-t 
@var{cache}] [-b @var{base}] [-d] [-p] [--share-rw] @var{filename}
 ETEXI
 
 DEF("compare", img_compare,
-"compare [--object objectdef] [--image-opts] [-f fmt] [-F fmt] [-T 
src_cache] [-p] [-q] [-s] filename1 filename2")
+"compare [--object objectdef] [--image-opts] [-f fmt] [-F fmt] [-T 
src_cache] [-p] [-q] [-s] [--share-rw] filename1 filename2")
 STEXI
-@item compare [--object @var{objectdef}] [--image-opts] [-f @var{fmt}] [-F 
@var{fmt}] [-T @var{src_cache}] [-p] [-q] [-s] @var{filename1} @var{filename2}
+@item compare [--object @var{objectdef}] [--image-opts] [-f @var{fmt}] [-F 
@var{fmt}] [-T @var{src_cache}] [-p] [-q] [-s] [--share-rw] @var{filename1} 
@var{filename2}
 ETEXI
 
 DEF("convert", img_convert,
-"convert [--object objectdef] [--image-opts] [-c] [-p] [-q] [-n] [-f fmt] 
[-t cache] [-T src_cache] [-O output_fmt] [-o options] [-s snapshot_id_or_name] 
[-l snapshot_param] [-S sparse_size] [-m num_coroutines] [-W] filename 
[filename2 [...]] output_filename")
+"convert [--object objectdef] [--image-opts] [-c] [-p] [-q] [-n] [-f fmt] 
[-t cache] [-T src_cache] [-O output_fmt] [-o options] [-s snapshot_id_or_name] 
[-l snapshot_param] [-S sparse_size] [-m num_coroutines] [-W] [--share-rw] 
filename [filename2 [...]] output_filename")
 STEXI
-@item convert [--object @var{objectdef}] [--image-opts] [-c] [-p] [-q] [-n] 
[-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-o 
@var{options}] [-s @var{snapshot_id_or_name}] [-l @var{snapshot_param}] [-S 
@var{sparse_size}] [-m @var{num_coroutines}] [-W] @var{filename} 
[@var{filename2} [...]] @var{output_filename}
+@item convert [--object @var{objectdef}] [--image-opts] [-c] [-p] [-q] [-n] 
[-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-o 
@var{options}] [-s @var{snapshot_id_or_name}] [-l @var{snapshot_param}] [-S 
@var{sparse_size}] [-m @var{num_coroutines}] [-W] [--share-rw] @var{filename} 
[@var{filename2} [...]] @var{output_filename}
 ETEXI
 
 DEF("dd", img_dd,
-"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
[skip=blocks] if=input of=output")
+"dd [--image-opts] [--share-rw] [-f fmt] [-O output_fmt] [bs=block_size] 
[count=blocks] [skip=blocks] if=input of=output")
 STEXI
-@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] if=@var{input} 
of=@var{output}
+@item dd [--image-opts] [--share-rw] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blo

[Qemu-devel] [PATCH v14 07/20] iotests: 030: Prepare for image locking

2017-04-20 Thread Fam Zheng
qemu-img and qemu-io commands when guest is running need "-U" option,
add it.

Signed-off-by: Fam Zheng 
---
 tests/qemu-iotests/030 | 24 
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/tests/qemu-iotests/030 b/tests/qemu-iotests/030
index 0d472d5..5f1dce8 100755
--- a/tests/qemu-iotests/030
+++ b/tests/qemu-iotests/030
@@ -63,8 +63,8 @@ class TestSingleDrive(iotests.QMPTestCase):
 def test_stream_intermediate(self):
 self.assert_no_active_block_jobs()
 
-self.assertNotEqual(qemu_io('-f', 'raw', '-c', 'map', backing_img),
-qemu_io('-f', iotests.imgfmt, '-c', 'map', 
mid_img),
+self.assertNotEqual(qemu_io('-f', 'raw', '-rU', '-c', 'map', 
backing_img),
+qemu_io('-f', iotests.imgfmt, '-rU', '-c', 'map', 
mid_img),
 'image file map matches backing file before 
streaming')
 
 result = self.vm.qmp('block-stream', device='mid', job_id='stream-mid')
@@ -114,7 +114,7 @@ class TestSingleDrive(iotests.QMPTestCase):
 self.assert_no_active_block_jobs()
 
 # The image map is empty before the operation
-empty_map = qemu_io('-f', iotests.imgfmt, '-c', 'map', test_img)
+empty_map = qemu_io('-f', iotests.imgfmt, '-rU', '-c', 'map', test_img)
 
 # This is a no-op: no data should ever be copied from the base image
 result = self.vm.qmp('block-stream', device='drive0', base=mid_img)
@@ -125,7 +125,7 @@ class TestSingleDrive(iotests.QMPTestCase):
 self.assert_no_active_block_jobs()
 self.vm.shutdown()
 
-self.assertEqual(qemu_io('-f', iotests.imgfmt, '-c', 'map', test_img),
+self.assertEqual(qemu_io('-f', iotests.imgfmt, '-c', 'map', '-r', 
test_img),
  empty_map, 'image file map changed after a no-op')
 
 def test_stream_partial(self):
@@ -197,8 +197,8 @@ class TestParallelOps(iotests.QMPTestCase):
 
 # Check that the maps don't match before the streaming operations
 for i in range(2, self.num_imgs, 2):
-self.assertNotEqual(qemu_io('-f', iotests.imgfmt, '-c', 'map', 
self.imgs[i]),
-qemu_io('-f', iotests.imgfmt, '-c', 'map', 
self.imgs[i-1]),
+self.assertNotEqual(qemu_io('-f', iotests.imgfmt, '-U', '-c', 
'map', self.imgs[i]),
+qemu_io('-f', iotests.imgfmt, '-U', '-c', 
'map', self.imgs[i-1]),
 'image file map matches backing file before 
streaming')
 
 # Create all streaming jobs
@@ -351,8 +351,8 @@ class TestParallelOps(iotests.QMPTestCase):
 def test_stream_base_node_name(self):
 self.assert_no_active_block_jobs()
 
-self.assertNotEqual(qemu_io('-f', iotests.imgfmt, '-c', 'map', 
self.imgs[4]),
-qemu_io('-f', iotests.imgfmt, '-c', 'map', 
self.imgs[3]),
+self.assertNotEqual(qemu_io('-f', iotests.imgfmt, '-U', '-c', 'map', 
self.imgs[4]),
+qemu_io('-f', iotests.imgfmt, '-U', '-c', 'map', 
self.imgs[3]),
 'image file map matches backing file before 
streaming')
 
 # Error: the base node does not exist
@@ -422,8 +422,8 @@ class TestQuorum(iotests.QMPTestCase):
 if not iotests.supports_quorum():
 return
 
-self.assertNotEqual(qemu_io('-f', iotests.imgfmt, '-c', 'map', 
self.children[0]),
-qemu_io('-f', iotests.imgfmt, '-c', 'map', 
self.backing[0]),
+self.assertNotEqual(qemu_io('-f', iotests.imgfmt, '-U', '-c', 'map', 
self.children[0]),
+qemu_io('-f', iotests.imgfmt, '-U', '-c', 'map', 
self.backing[0]),
 'image file map matches backing file before 
streaming')
 
 self.assert_no_active_block_jobs()
@@ -436,8 +436,8 @@ class TestQuorum(iotests.QMPTestCase):
 self.assert_no_active_block_jobs()
 self.vm.shutdown()
 
-self.assertEqual(qemu_io('-f', iotests.imgfmt, '-c', 'map', 
self.children[0]),
- qemu_io('-f', iotests.imgfmt, '-c', 'map', 
self.backing[0]),
+self.assertEqual(qemu_io('-f', iotests.imgfmt, '-U', '-c', 'map', 
self.children[0]),
+ qemu_io('-f', iotests.imgfmt, '-U', '-c', 'map', 
self.backing[0]),
  'image file map does not match backing file after 
streaming')
 
 class TestSmallerBackingFile(iotests.QMPTestCase):
-- 
2.9.3




[Qemu-devel] [PATCH v14 08/20] iotests: 046: Prepare for image locking

2017-04-20 Thread Fam Zheng
The qemu-img info command is executed while VM is running, add -U option
to avoid the image locking error.

Signed-off-by: Fam Zheng 
---
 tests/qemu-iotests/046 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/qemu-iotests/046 b/tests/qemu-iotests/046
index e528b67..f2ebecf 100755
--- a/tests/qemu-iotests/046
+++ b/tests/qemu-iotests/046
@@ -192,7 +192,7 @@ echo "== Verify image content =="
 
 function verify_io()
 {
-if ($QEMU_IMG info -f "$IMGFMT" "$TEST_IMG" | grep "compat: 0.10" > 
/dev/null); then
+if ($QEMU_IMG info -U -f "$IMGFMT" "$TEST_IMG" | grep "compat: 0.10" > 
/dev/null); then
 # For v2 images, discarded clusters are read from the backing file
 # Keep the variable empty so that the backing file value can be used as
 # the default below
-- 
2.9.3




[Qemu-devel] [PATCH v14 03/20] block: Respect "force-shared-write" in perm propagating

2017-04-20 Thread Fam Zheng
Signed-off-by: Fam Zheng 
---
 block.c | 31 +++
 1 file changed, 23 insertions(+), 8 deletions(-)

diff --git a/block.c b/block.c
index f5c4e97..6acf618 100644
--- a/block.c
+++ b/block.c
@@ -1422,6 +1422,21 @@ static int bdrv_child_check_perm(BdrvChild *c, uint64_t 
perm, uint64_t shared,
 static void bdrv_child_abort_perm_update(BdrvChild *c);
 static void bdrv_child_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared);
 
+static void bdrv_child_perm(BlockDriverState *bs, BdrvChild *c,
+const BdrvChildRole *role,
+uint64_t parent_perm, uint64_t parent_shared,
+uint64_t *nperm, uint64_t *nshared)
+{
+if (bs->drv && bs->drv->bdrv_child_perm) {
+bs->drv->bdrv_child_perm(bs, c, role,
+ parent_perm, parent_shared,
+ nperm, nshared);
+}
+if (bs->force_shared_write) {
+*nshared |= BLK_PERM_WRITE;
+}
+}
+
 /*
  * Check whether permissions on this node can be changed in a way that
  * @cumulative_perms and @cumulative_shared_perms are the new cumulative
@@ -1466,9 +1481,9 @@ static int bdrv_check_perm(BlockDriverState *bs, uint64_t 
cumulative_perms,
 /* Check all children */
 QLIST_FOREACH(c, &bs->children, next) {
 uint64_t cur_perm, cur_shared;
-drv->bdrv_child_perm(bs, c, c->role,
- cumulative_perms, cumulative_shared_perms,
- &cur_perm, &cur_shared);
+bdrv_child_perm(bs, c, c->role,
+cumulative_perms, cumulative_shared_perms,
+&cur_perm, &cur_shared);
 ret = bdrv_child_check_perm(c, cur_perm, cur_shared, ignore_children,
 errp);
 if (ret < 0) {
@@ -1528,9 +1543,9 @@ static void bdrv_set_perm(BlockDriverState *bs, uint64_t 
cumulative_perms,
 /* Update all children */
 QLIST_FOREACH(c, &bs->children, next) {
 uint64_t cur_perm, cur_shared;
-drv->bdrv_child_perm(bs, c, c->role,
- cumulative_perms, cumulative_shared_perms,
- &cur_perm, &cur_shared);
+bdrv_child_perm(bs, c, c->role,
+cumulative_perms, cumulative_shared_perms,
+&cur_perm, &cur_shared);
 bdrv_child_set_perm(c, cur_perm, cur_shared);
 }
 }
@@ -1865,8 +1880,8 @@ BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
 
 assert(parent_bs->drv);
 assert(bdrv_get_aio_context(parent_bs) == bdrv_get_aio_context(child_bs));
-parent_bs->drv->bdrv_child_perm(parent_bs, NULL, child_role,
-perm, shared_perm, &perm, &shared_perm);
+bdrv_child_perm(parent_bs, NULL, child_role,
+perm, shared_perm, &perm, &shared_perm);
 
 child = bdrv_root_attach_child(child_bs, child_name, child_role,
perm, shared_perm, parent_bs, errp);
-- 
2.9.3




[Qemu-devel] [PATCH v14 06/20] qemu-io: Add --share-rw option

2017-04-20 Thread Fam Zheng
Add --share-rw/-U to program options and -U to open subcommand.

Signed-off-by: Fam Zheng 
---
 qemu-io.c | 35 +++
 1 file changed, 27 insertions(+), 8 deletions(-)

diff --git a/qemu-io.c b/qemu-io.c
index 427cbae..c4d824f 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -20,6 +20,7 @@
 #include "qemu/readline.h"
 #include "qemu/log.h"
 #include "qapi/qmp/qstring.h"
+#include "qapi/qmp/qbool.h"
 #include "qom/object_interfaces.h"
 #include "sysemu/block-backend.h"
 #include "block/block_int.h"
@@ -53,7 +54,8 @@ static const cmdinfo_t close_cmd = {
 .oneline= "close the current open file",
 };
 
-static int openfile(char *name, int flags, bool writethrough, QDict *opts)
+static int openfile(char *name, int flags, bool writethrough, bool share_rw,
+QDict *opts)
 {
 Error *local_err = NULL;
 BlockDriverState *bs;
@@ -64,6 +66,12 @@ static int openfile(char *name, int flags, bool 
writethrough, QDict *opts)
 return 1;
 }
 
+if (share_rw) {
+if (!opts) {
+opts = qdict_new();
+}
+qdict_put(opts, BDRV_OPT_FORCE_SHARED_WRITE, qbool_from_bool(true));
+}
 qemuio_blk = blk_new_open(name, NULL, opts, flags, &local_err);
 if (!qemuio_blk) {
 error_reportf_err(local_err, "can't open%s%s: ",
@@ -108,6 +116,7 @@ static void open_help(void)
 " -r, -- open file read-only\n"
 " -s, -- use snapshot file\n"
 " -n, -- disable host cache, short for -t none\n"
+" -U, -- allow shared write, don't lock image\n"
 " -k, -- use kernel AIO implementation (on Linux only)\n"
 " -t, -- use the given cache mode for the image\n"
 " -d, -- use the given discard mode for the image\n"
@@ -124,7 +133,7 @@ static const cmdinfo_t open_cmd = {
 .argmin = 1,
 .argmax = -1,
 .flags  = CMD_NOFILE_OK,
-.args   = "[-rsnk] [-t cache] [-d discard] [-o options] [path]",
+.args   = "[-rsnkU] [-t cache] [-d discard] [-o options] [path]",
 .oneline= "open the file specified by path",
 .help   = open_help,
 };
@@ -147,8 +156,9 @@ static int open_f(BlockBackend *blk, int argc, char **argv)
 int c;
 QemuOpts *qopts;
 QDict *opts;
+bool share_rw = false;
 
-while ((c = getopt(argc, argv, "snro:kt:d:")) != -1) {
+while ((c = getopt(argc, argv, "snro:kt:d:U")) != -1) {
 switch (c) {
 case 's':
 flags |= BDRV_O_SNAPSHOT;
@@ -188,6 +198,9 @@ static int open_f(BlockBackend *blk, int argc, char **argv)
 return 0;
 }
 break;
+case 'U':
+share_rw = true;
+break;
 default:
 qemu_opts_reset(&empty_opts);
 return qemuio_command_usage(&open_cmd);
@@ -211,9 +224,9 @@ static int open_f(BlockBackend *blk, int argc, char **argv)
 qemu_opts_reset(&empty_opts);
 
 if (optind == argc - 1) {
-return openfile(argv[optind], flags, writethrough, opts);
+return openfile(argv[optind], flags, writethrough, share_rw, opts);
 } else if (optind == argc) {
-return openfile(NULL, flags, writethrough, opts);
+return openfile(NULL, flags, writethrough, share_rw, opts);
 } else {
 QDECREF(opts);
 return qemuio_command_usage(&open_cmd);
@@ -257,6 +270,7 @@ static void usage(const char *name)
 "  -T, --trace [[enable=]][,events=][,file=]\n"
 "   specify tracing options\n"
 "   see qemu-img(1) man page for full description\n"
+"  -U, --share-rw   allow shared write\n"
 "  -h, --help   display this help and exit\n"
 "  -V, --versionoutput version information and exit\n"
 "\n"
@@ -436,7 +450,7 @@ static QemuOptsList file_opts = {
 int main(int argc, char **argv)
 {
 int readonly = 0;
-const char *sopt = "hVc:d:f:rsnmkt:T:";
+const char *sopt = "hVc:d:f:rsnmkt:T:U";
 const struct option lopt[] = {
 { "help", no_argument, NULL, 'h' },
 { "version", no_argument, NULL, 'V' },
@@ -452,6 +466,7 @@ int main(int argc, char **argv)
 { "trace", required_argument, NULL, 'T' },
 { "object", required_argument, NULL, OPTION_OBJECT },
 { "image-opts", no_argument, NULL, OPTION_IMAGE_OPTS },
+{ "share-rw", no_argument, 0, 'U'},
 { NULL, 0, NULL, 0 }
 };
 int c;
@@ -462,6 +477,7 @@ int main(int argc, char **argv)
 QDict *opts = NULL;
 const char *format = NULL;
 char *trace_file = NULL;
+bool share_rw = false;
 
 #ifdef CONFIG_POSIX
 signal(SIGPIPE, SIG_IGN);
@@ -524,6 +540,9 @@ int main(int argc, char **argv)
 case 'h':
 usage(progname);
 exit(0);
+case 'U':
+share_rw = true;
+break;
 case OPTION_OBJECT: {
 QemuOpts *qopts;
 qopts = qemu_opts_parse_noisily(&qemu_object_opts,
@@ -595,7 +614,7 @@ int main(int argc, char **argv)
 exit(1);
   

[Qemu-devel] [PATCH v14 02/20] qapi: Add 'force-shared-write' to blockdev-add arguments

2017-04-20 Thread Fam Zheng
Signed-off-by: Fam Zheng 
---
 qapi/block-core.json | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/qapi/block-core.json b/qapi/block-core.json
index 033457c..b9b8002 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -2880,6 +2880,8 @@
 # (default: false)
 # @detect-zeroes: detect and optimize zero writes (Since 2.1)
 # (default: off)
+# @force-shared-write: enforce shared write permission on added nodes
+#  (Since 2.10)
 #
 # Remaining options are determined by the block driver.
 #
@@ -2891,6 +2893,7 @@
 '*discard': 'BlockdevDiscardOptions',
 '*cache': 'BlockdevCacheOptions',
 '*read-only': 'bool',
+'*force-shared-write': 'bool',
 '*detect-zeroes': 'BlockdevDetectZeroesOptions' },
   'discriminator': 'driver',
   'data': {
-- 
2.9.3




[Qemu-devel] [PATCH v14 01/20] block: Add, parse and store "force-shared-write" option

2017-04-20 Thread Fam Zheng
Signed-off-by: Fam Zheng 
---
 block.c   | 9 +
 include/block/block.h | 2 ++
 include/block/block_int.h | 1 +
 3 files changed, 12 insertions(+)

diff --git a/block.c b/block.c
index 1e668fb..f5c4e97 100644
--- a/block.c
+++ b/block.c
@@ -763,6 +763,7 @@ static void bdrv_inherited_options(int *child_flags, QDict 
*child_options,
  * the parent. */
 qdict_copy_default(child_options, parent_options, BDRV_OPT_CACHE_DIRECT);
 qdict_copy_default(child_options, parent_options, BDRV_OPT_CACHE_NO_FLUSH);
+qdict_copy_default(child_options, parent_options, 
BDRV_OPT_FORCE_SHARED_WRITE);
 
 /* Inherit the read-only option from the parent if it's not set */
 qdict_copy_default(child_options, parent_options, BDRV_OPT_READ_ONLY);
@@ -871,6 +872,7 @@ static void bdrv_backing_options(int *child_flags, QDict 
*child_options,
  * which is only applied on the top level (BlockBackend) */
 qdict_copy_default(child_options, parent_options, BDRV_OPT_CACHE_DIRECT);
 qdict_copy_default(child_options, parent_options, BDRV_OPT_CACHE_NO_FLUSH);
+qdict_copy_default(child_options, parent_options, 
BDRV_OPT_FORCE_SHARED_WRITE);
 
 /* backing files always opened read-only */
 qdict_set_default_str(child_options, BDRV_OPT_READ_ONLY, "on");
@@ -1115,6 +1117,11 @@ QemuOptsList bdrv_runtime_opts = {
 .type = QEMU_OPT_STRING,
 .help = "discard operation (ignore/off, unmap/on)",
 },
+{
+.name = BDRV_OPT_FORCE_SHARED_WRITE,
+.type = QEMU_OPT_BOOL,
+.help = "always accept other writers (default: off)",
+},
 { /* end of list */ }
 },
 };
@@ -1154,6 +1161,8 @@ static int bdrv_open_common(BlockDriverState *bs, 
BlockBackend *file,
 drv = bdrv_find_format(driver_name);
 assert(drv != NULL);
 
+bs->force_shared_write = qemu_opt_get_bool(opts, 
BDRV_OPT_FORCE_SHARED_WRITE, false);
+
 if (file != NULL) {
 filename = blk_bs(file)->filename;
 } else {
diff --git a/include/block/block.h b/include/block/block.h
index 5ddc0cf..d3afb75 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -109,6 +109,8 @@ typedef struct HDGeometry {
 #define BDRV_OPT_CACHE_NO_FLUSH "cache.no-flush"
 #define BDRV_OPT_READ_ONLY  "read-only"
 #define BDRV_OPT_DISCARD"discard"
+#define BDRV_OPT_FORCE_SHARED_WRITE \
+"force-shared-write"
 
 
 #define BDRV_SECTOR_BITS   9
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 59400bd..fb81692 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -518,6 +518,7 @@ struct BlockDriverState {
 bool valid_key; /* if true, a valid encryption key has been set */
 bool sg;/* if true, the device is a /dev/sg* */
 bool probed;/* if true, format was probed rather than specified */
+bool force_shared_write; /* if true, always allow shared write perm. */
 
 BlockDriver *drv; /* NULL means no media */
 void *opaque;
-- 
2.9.3




[Qemu-devel] [PATCH v14 00/20] block: Image locking series

2017-04-20 Thread Fam Zheng
v14: - Replace BDRV_ flag with the "force-shared-write" block option. [Kevin]
 - Add bs->force_shared_write.
 - Update test case accordingly, back to bash again. :)
 - A few fixes in the locking code spotted by patchew and the new test,
   though the long line error is still there for readability.
 - Replace the workaround to drive-backup with a real fix in patch 17.

v13: - Address Max's comments.
 - Add reviewed-by from Max and Eric.
 - Rebase for 2.10:
   * Use op blocker API
   * Add --unsafe-read for qemu-img and qemu-io

Fam Zheng (20):
  block: Add, parse and store "force-shared-write" option
  qapi: Add 'force-shared-write' to blockdev-add arguments
  block: Respect "force-shared-write" in perm propagating
  qemu-img: Add --share-rw option to subcommands
  qemu-img: Update documentation for --share-rw
  qemu-io: Add --share-rw option
  iotests: 030: Prepare for image locking
  iotests: 046: Prepare for image locking
  iotests: 055: Don't attach the target image already for drive-backup
  iotests: 085: Avoid image locking conflict
  iotests: 087: Don't attach test image twice
  iotests: 091: Quit QEMU before checking image
  iotests: 172: Use separate images for multiple devices
  tests: Use null-co:// instead of /dev/null as the dummy image
  file-posix: Add 'locking' option
  tests: Disable image lock in test-replication
  block: Reuse bs as backing hd for drive-backup sync=none
  osdep: Add qemu_lock_fd and qemu_unlock_fd
  file-posix: Add image locking in perm operations
  qemu-iotests: Add test case 153 for image locking

 block.c|  40 ++-
 block/file-posix.c | 744 -
 blockdev.c |  15 +-
 include/block/block.h  |   2 +
 include/block/block_int.h  |   1 +
 include/qemu/osdep.h   |   3 +
 qapi/block-core.json   |   3 +
 qemu-img-cmds.hx   |  48 +--
 qemu-img.c | 155 +++---
 qemu-io.c  |  35 ++-
 tests/drive_del-test.c |   2 +-
 tests/nvme-test.c  |   2 +-
 tests/qemu-iotests/030 |  24 +-
 tests/qemu-iotests/046 |   2 +-
 tests/qemu-iotests/055 |  32 +-
 tests/qemu-iotests/085 |  34 ++-
 tests/qemu-iotests/085.out |   3 +-
 tests/qemu-iotests/087 |   6 +-
 tests/qemu-iotests/091 |   2 +
 tests/qemu-iotests/153 | 219 +
 tests/qemu-iotests/153.out | 627 ++
 tests/qemu-iotests/172 |  55 ++--
 tests/qemu-iotests/172.out |  50 +--
 tests/qemu-iotests/group   |   1 +
 tests/test-replication.c   |   9 +-
 tests/usb-hcd-uhci-test.c  |   2 +-
 tests/usb-hcd-xhci-test.c  |   2 +-
 tests/virtio-blk-test.c|   2 +-
 tests/virtio-scsi-test.c   |   4 +-
 util/osdep.c   |  48 +++
 30 files changed, 1988 insertions(+), 184 deletions(-)
 create mode 100755 tests/qemu-iotests/153
 create mode 100644 tests/qemu-iotests/153.out

-- 
2.9.3




Re: [Qemu-devel] [PATCH V2 1/2] COLO-compare: Optimize tcp compare for option field

2017-04-20 Thread Zhang Chen



On 04/20/2017 02:43 PM, Jason Wang wrote:



On 2017年04月18日 10:20, Zhang Chen wrote:

In this patch we support packet that have tcp options field.
Add tcp options field check, If the packet have options
field we just skip it and compare tcp payload,
Avoid unnecessary checkpoint, optimize performance.

Signed-off-by: Zhang Chen 
---
  net/colo-compare.c | 27 ++-
  1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/net/colo-compare.c b/net/colo-compare.c
index aada04e..049f6f8 100644
--- a/net/colo-compare.c
+++ b/net/colo-compare.c
@@ -248,7 +248,32 @@ static int colo_packet_compare_tcp(Packet *spkt, 
Packet *ppkt)

  spkt->ip->ip_sum = ppkt->ip->ip_sum;
  }
  -if (ptcp->th_sum == stcp->th_sum) {
+/*
+ * Check tcp header length for tcp option field.
+ * th_off > 5 means this tcp packet have options field.
+ * The tcp options maybe always different.
+ * for example:
+ * From RFC 7323.
+ * TCP Timestamps option (TSopt):
+ * Kind: 8
+ *
+ * Length: 10 bytes
+ *
+ * +---+---+-+-+
+ *|Kind=8 |  10   |   TS Value (TSval)  |TS Echo Reply (TSecr)|
+ * +---+---+-+-+
+ *   1   1  4 4
+ *
+ * In this case the primary guest's timestamp always different with
+ * the secondary guest's timestamp. COLO just focus on payload,
+ * so we just need skip this field.h


Probably a good explanation why we can skip this kind of header. But 
it does not explain why we can skip all the rest?


I found tcp options have many kind number to express different meaning,
Here I just give an example for the different options situation,
and this field not the COLO-proxy focus on, COLO just concern the payload.
Maybe we will optimize in the feature. Currently we want to make COLO 
full-function

running in qemu upstream.

Thanks
Zhang Chen



Thanks


+ */
+if (ptcp->th_off > 5) {
+ptrdiff_t tcp_offset;
+tcp_offset = ppkt->transport_header - (uint8_t *)ppkt->data
+ + (ptcp->th_off * 4);
+res = colo_packet_compare_common(ppkt, spkt, tcp_offset);
+} else if (ptcp->th_sum == stcp->th_sum) {
  res = colo_packet_compare_common(ppkt, spkt, ETH_HLEN);
  } else {
  res = -1;




.



--
Thanks
Zhang Chen






[Qemu-devel] [RESEND PATCH] MAINTAINERS: Remove myself from e500

2017-04-20 Thread Scott Wood
I recently left Freescale/NXP, and even before that it'd been a few years
since I was actively involved in KVM/QEMU work.

Signed-off-by: Scott Wood 
---
Sorry for the resend -- fixed mailing list address.

 MAINTAINERS | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index c60235eaf6..dcb9be1c6c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -645,7 +645,6 @@ F: hw/ppc/ppc440_bamboo.c
 
 e500
 M: Alexander Graf 
-M: Scott Wood 
 L: qemu-...@nongnu.org
 S: Supported
 F: hw/ppc/e500.[hc]
@@ -656,7 +655,6 @@ F: pc-bios/u-boot.e500
 
 mpc8544ds
 M: Alexander Graf 
-M: Scott Wood 
 L: qemu-...@nongnu.org
 S: Supported
 F: hw/ppc/mpc8544ds.c
@@ -933,7 +931,6 @@ F: include/hw/ppc/ppc4xx.h
 
 ppce500
 M: Alexander Graf 
-M: Scott Wood 
 L: qemu-...@nongnu.org
 S: Supported
 F: hw/ppc/e500*
-- 
2.11.0




[Qemu-devel] AccelClass initialization order question

2017-04-20 Thread Chuck Tuffli
While debugging an issue, I ran across something in the initialization
sequence of hardware accelerators. Being a noobie qemu developer, it's
hard to tell if I simply don't understand how AccelClass works or if
this is a bug.

The init_machine function for hardware accelerators is passed a
MachineState pointer via configure_accelerator(), but several elements
of the structure (e.g. ram_size, maxram_size, etc.) are not
initialized until well after this call. Should hardware accelerator
modules not look at MachineState and instead grab the global versions
of variables like ram_size? TIA.

--chuck



Re: [Qemu-devel] [PATCH] qemu-img: use blk_co_pwrite_zeroes for zero sectors when compressed

2017-04-20 Thread 858585 jemmy
On Thu, Apr 20, 2017 at 6:00 PM, Kevin Wolf  wrote:
> Am 20.04.2017 um 10:38 hat jemmy858...@gmail.com geschrieben:
>> From: Lidong Chen 
>>
>> when the buffer is zero, blk_co_pwrite_zeroes is more effectively than
>> blk_co_pwritev with BDRV_REQ_WRITE_COMPRESSED. this patch can reduces
>> the time when converts the qcow2 image with lots of zero.
>>
>> Signed-off-by: Lidong Chen 
>
> Good catch, using blk_co_pwrite_zeroes() makes sense even for compressed
> images.
>
>> diff --git a/qemu-img.c b/qemu-img.c
>> index b220cf7..0256539 100644
>> --- a/qemu-img.c
>> +++ b/qemu-img.c
>> @@ -1675,13 +1675,20 @@ static int coroutine_fn 
>> convert_co_write(ImgConvertState *s, int64_t sector_num,
>>   * write if the buffer is completely zeroed and we're allowed to
>>   * keep the target sparse. */
>>  if (s->compressed) {
>> -if (s->has_zero_init && s->min_sparse &&
>> -buffer_is_zero(buf, n * BDRV_SECTOR_SIZE))
>> -{
>> -assert(!s->target_has_backing);
>> -break;
>> +if (buffer_is_zero(buf, n * BDRV_SECTOR_SIZE)) {
>> +if (s->has_zero_init && s->min_sparse) {
>> +assert(!s->target_has_backing);
>> +break;
>> +} else {
>> +ret = blk_co_pwrite_zeroes(s->target,
>> +   sector_num << BDRV_SECTOR_BITS,
>> +   n << BDRV_SECTOR_BITS, 0);
>> +if (ret < 0) {
>> +return ret;
>> +}
>> +break;
>> +}
>>  }
>
> If s->min_sparse == 0, we may neither skip the write not use
> blk_co_pwrite_zeroes(), because this requires actual full allocation
> with explicit zero sectors.
>
> Of course, if you fix this, what you end up with here is a duplicate of
> the code path for non-compressed images. The remaining difference seems
> to be the BDRV_REQ_WRITE_COMPRESSED flag and buffer_is_zero() vs.
> is_allocated_sectors_min() (because uncompressed clusters can be written
> partially, but compressed clusters can't).

I have a try to unify the code.

I don't understand why use  is_allocated_sectors_min when don't compressed.
the s->min_sparse is 8 default, which is smaller than cluster_sectors.

if a cluster which data is  8 sector zero and 8 sector non-zero
repeated, it will call
blk_co_pwritev and blk_co_pwrite_zeroes many times for a cluster.

why not compare the zero by cluster_sectors size?

>
> So I suppose that instead of just fixing the above bug, we could actually
> mostly unify the two code paths, if you want to have a try at it.
>
> Kevin



Re: [Qemu-devel] [PATCH] Fix wrong length in IP header in tcp_respond.

2017-04-20 Thread no-reply
Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 20170420202745.149601-1-lep...@google.com
Subject: [Qemu-devel] [PATCH] Fix wrong length in IP header in tcp_respond.

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

# Useful git options
git config --local diff.renamelimit 0
git config --local diff.renames True

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
failed=1
echo
fi
n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 - [tag update]  patchew/20170414083717.13641-1-lviv...@redhat.com -> 
patchew/20170414083717.13641-1-lviv...@redhat.com
Switched to a new branch 'test'
b3105be Fix wrong length in IP header in tcp_respond.

=== OUTPUT BEGIN ===
Checking PATCH 1/1: Fix wrong length in IP header in tcp_respond
ERROR: code indent should never use tabs
#24: FILE: slirp/tcp_subr.c:207:
+^Iip->ip_len = m->m_len;$

ERROR: code indent should never use tabs
#33: FILE: slirp/tcp_subr.c:227:
+^Iip6->ip_pl = tcpiph_save.ti_len;$

total: 2 errors, 0 warnings, 16 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-de...@freelists.org

Re: [Qemu-devel] [Qemu-ppc] [PATCH v2 2/4] ppc: remove cannot_destroy_with_object_finalize_yet

2017-04-20 Thread David Gibson
On Tue, Apr 18, 2017 at 01:09:50PM +1000, David Gibson wrote:
> On Fri, Apr 14, 2017 at 10:37:15AM +0200, Laurent Vivier wrote:
> > This removes the assert(kvm_enabled()) from kvmppc_host_cpu_initfn()
> > 
> > This assert can never be triggered as the function is only registered
> > when KVM is available (see also 4c315c2
> > "qdev: Protect device-list-properties against broken devices").
> > 
> > So we can remove the cannot_destroy_with_object_finalize_yet from
> > kvmppc_host_cpu_class_init() without fear and beyond reproach.
> > (as it has already be done for i386 with 771a13e "i386: Unset
> > cannot_destroy_with_object_finalize_yet on "host" model" and
> > e435601 "target-i386: Remove assert(kvm_enabled()) from
> > host_x86_cpu_initfn()")
> > 
> > Signed-off-by: Laurent Vivier 
> 
> Applied to ppc-for-2.10 (fixing a contextual conflict on the way).

Looks like this will go through Markus' tree instead, so:

Acked-by: David Gibson 

> 
> 
> > ---
> >  target/ppc/kvm.c | 10 --
> >  1 file changed, 10 deletions(-)
> > 
> > diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
> > index 9f1f132..64017ac 100644
> > --- a/target/ppc/kvm.c
> > +++ b/target/ppc/kvm.c
> > @@ -2245,14 +2245,8 @@ static void alter_insns(uint64_t *word, uint64_t 
> > flags, bool on)
> >  }
> >  }
> >  
> > -static void kvmppc_host_cpu_initfn(Object *obj)
> > -{
> > -assert(kvm_enabled());
> > -}
> > -
> >  static void kvmppc_host_cpu_class_init(ObjectClass *oc, void *data)
> >  {
> > -DeviceClass *dc = DEVICE_CLASS(oc);
> >  PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
> >  uint32_t vmx = kvmppc_get_vmx();
> >  uint32_t dfp = kvmppc_get_dfp();
> > @@ -2279,9 +2273,6 @@ static void kvmppc_host_cpu_class_init(ObjectClass 
> > *oc, void *data)
> >  if (icache_size != -1) {
> >  pcc->l1_icache_size = icache_size;
> >  }
> > -
> > -/* Reason: kvmppc_host_cpu_initfn() dies when !kvm_enabled() */
> > -dc->cannot_destroy_with_object_finalize_yet = true;
> >  }
> >  
> >  bool kvmppc_has_cap_epr(void)
> > @@ -2333,7 +2324,6 @@ static int kvm_ppc_register_host_cpu_type(void)
> >  {
> >  TypeInfo type_info = {
> >  .name = TYPE_HOST_POWERPC_CPU,
> > -.instance_init = kvmppc_host_cpu_initfn,
> >  .class_init = kvmppc_host_cpu_class_init,
> >  };
> >  PowerPCCPUClass *pvr_pcc;
> 



-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH v2 0/4] qdev: remove all remaining cannot_destroy_with_object_finalize_yet

2017-04-20 Thread David Gibson
On Thu, Apr 20, 2017 at 05:59:27PM +0200, Markus Armbruster wrote:
> Peter Maydell  writes:
> 
> > On 14 April 2017 at 09:37, Laurent Vivier  wrote:
> >> This series removes all the remaining uses of
> >> cannot_destroy_with_object_finalize_yet to finally remove
> >> the flag itself.
> >>
> >> The ARM patch has already been sent alone and reviewed by Markus.
> >> I have tested the ppc one on ppc64 machine with KVM and using
> >> QDM device-list-properties command.
> >>
> >> For the versatile one, the flag allowed to workaround a problem
> >> in the bus unparent function: the bus unparent is trying to
> >> unparent all the children of the bus. To do that, it has a list
> >> of the children of the bus, and calls object_unparent() for each
> >> child, and object_unparent() calls object_property_del_child() if
> >> obj->parent is not NULL.  As qdev_set_parent_bus() set only
> >> parent_bus and the list of children, parent is NULL and the child
> >> is never deleted.  We can avoid the problem by moving the
> >> qdev_set_parent_bus() to the realize part.
> >>
> >> I've tested all the changes with "make check" (including
> >> device-introspect-test). I've booted a versatilepb machine
> >> with a 3.16.0-4 debian installer kernel.
> >>
> >> Laurent Vivier (4):
> >>   arm: remove remaining cannot_destroy_with_object_finalize_yet
> >>   ppc: remove cannot_destroy_with_object_finalize_yet
> >>   versatile: remove cannot_destroy_with_object_finalize_yet
> >>   qdev: remove cannot_destroy_with_object_finalize_yet
> >
> > Markus -- are you planning to take this whole series through
> > your tree? I'm happy with the ARM patches but I guess we
> > should keep the whole series together since patch 4 depends
> > on the other 3...
> 
> We have no qdev maintainer.  David, you wrote you applied PATCH 2.  Are
> you okay with me taking all four?  If yes, would you like me to add your
> Acked-by or Reviewed-by to PATCH 2?

That's fine by me.  I've sent an Acked-by for that patch.

> 
> > I guess that means
> > Acked-by: Peter Maydell 
> 
> Noted.
> 

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


[Qemu-devel] [PATCH 1/1] slirp: don't zero ti_i since we acccess it later.

2017-04-20 Thread Tao Wu
The current code looks buggy, we zero ti_i while we access
ti_dst/ti_src later.

Signed-off-by: Tao Wu 
---
 slirp/tcp_subr.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index dc8b4bbb50..398d6b30d3 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -148,7 +148,6 @@ tcp_respond(struct tcpcb *tp, struct tcpiphdr *ti, struct 
mbuf *m,
m->m_data += IF_MAXLINKHDR;
*mtod(m, struct tcpiphdr *) = *ti;
ti = mtod(m, struct tcpiphdr *);
-   memset(&ti->ti, 0, sizeof(ti->ti));
flags = TH_ACK;
} else {
/*
-- 
2.12.2.816.g281164-goog




[Qemu-devel] [PATCH] Fix wrong length in IP header in tcp_respond.

2017-04-20 Thread Tao Wu
This bug was introduced by https://github.com/qemu/qemu/commit/98c6305
And then we 'fix' it in
https://github.com/qemu/qemu/commit/27d92e
Actually I believe the root cause was that we sent out a RST packet with
wrong length and then get ignored by OS.

Signed-off-by: Tao Wu 
---
 slirp/tcp_subr.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index ed16e1807f..dc8b4bbb50 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -204,7 +204,7 @@ tcp_respond(struct tcpcb *tp, struct tcpiphdr *ti, struct 
mbuf *m,
m->m_len  -= sizeof(struct tcpiphdr) - sizeof(struct tcphdr)
 - sizeof(struct ip);
ip = mtod(m, struct ip *);
-   ip->ip_len = tlen;
+   ip->ip_len = m->m_len;
ip->ip_dst = tcpiph_save.ti_dst;
ip->ip_src = tcpiph_save.ti_src;
ip->ip_p = tcpiph_save.ti_pr;
@@ -224,7 +224,7 @@ tcp_respond(struct tcpcb *tp, struct tcpiphdr *ti, struct 
mbuf *m,
m->m_len  -= sizeof(struct tcpiphdr) - sizeof(struct tcphdr)
 - sizeof(struct ip6);
ip6 = mtod(m, struct ip6 *);
-   ip6->ip_pl = tlen;
+   ip6->ip_pl = tcpiph_save.ti_len;
ip6->ip_dst = tcpiph_save.ti_dst6;
ip6->ip_src = tcpiph_save.ti_src6;
ip6->ip_nh = tcpiph_save.ti_nh6;
-- 
2.12.2.816.g281164-goog




[Qemu-devel] I sent out some patch this afternoon it seems it doesn't show here.

2017-04-20 Thread lepton
I sent it several hours ago and they don't show at
http://lists.gnu.org/archive/html/qemu-devel/2017-04/index.html

Is there some kind of spam filter in this list?  I sent those patches with
git send-email



[Qemu-devel] [PATCH 1/1] Fix wrong mss bug.

2017-04-20 Thread Tao Wu
This bug was introduced by https://github.com/qemu/qemu/commit/98c6305

Signed-off-by: Tao Wu 
---
 slirp/tcp_input.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c
index edb98f06f3..07bcbdb2dd 100644
--- a/slirp/tcp_input.c
+++ b/slirp/tcp_input.c
@@ -1587,11 +1587,11 @@ tcp_mss(struct tcpcb *tp, u_int offer)
switch (so->so_ffamily) {
case AF_INET:
 mss = MIN(IF_MTU, IF_MRU) - sizeof(struct tcphdr)
- + sizeof(struct ip);
+ - sizeof(struct ip);
break;
case AF_INET6:
 mss = MIN(IF_MTU, IF_MRU) - sizeof(struct tcphdr)
- + sizeof(struct ip6);
+ - sizeof(struct ip6);
break;
default:
g_assert_not_reached();
-- 
2.12.2.816.g281164-goog




Re: [Qemu-devel] [PATCH v2 for-2.10 00/18] crypto: add afalg-backend support

2017-04-20 Thread Longpeng (Mike)
Hi Daniel,

2.9 was released, so...ping

Thanks.

On 2017/4/17 9:33, Longpeng(Mike) wrote:

> The AF_ALG socket family is the userspace interface for linux
> crypto API, users can use it to access hardware accelerators.
> 
> This patchset adds a afalg-backend for qemu crypto subsystem. Currently
> when performs encrypt/decrypt, we'll try afalg-backend first and will
> back to libiary-backend if it failed.
> 
> In the next step, It would support a command parameter to specifies
> which backends prefer to and some other improvements.
> 
> I measured the performance about the afalg-backend impls, I tested
> how many data could be encrypted in 5 seconds.
> 
> NOTE: If we use specific hardware crypto cards, I think afalg-backend
>   would even faster.
> 
> test-environment: Intel(R) Core(TM) i5-6500 CPU @ 3.20GHz
> 
> *sha256*
> chunk_size(bytes)   MB/sec(afalg:sha256-ssse3)  MB/sec(nettle)
> 512 93.03   185.87
> 1024146.32  201.78
> 2048213.32  210.93
> 4096275.48  215.26
> 8192321.77  217.49
> 16384   349.60  219.26
> 32768   363.59  219.73
> 65536   375.79  219.99
> 
> *hmac(sha256)*
> chunk_size(bytes)   MB/sec(afalg:sha256-ssse3)  MB/sec(nettle)
> 512 71.26   165.55
> 1024117.43  189.15
> 2048180.96  203.24
> 4096247.60  211.38
> 8192301.99  215.65
> 16384   340.79  218.22
> 32768   365.51  219.49
> 65536   377.92  220.24
> 
> *cbc(aes128)*
> chunk_size(bytes)   MB/sec(afalg:cbc-aes-aesni)  MB/sec(nettle)
> 512 371.76   188.41
> 1024559.86   189.64
> 2048768.66   192.11
> 4096939.15   192.40
> 81921029.48  192.49
> 16384   1072.79  190.52
> 32768   1109.38  190.41
> 65536   1102.38  190.40
> 
> ---
> Changes since v1:
>   - use "make check-speed" to testing the performance. [Daniel]
>   - put private definations into crypto/***priv.h. [Daniel]
>   - remove afalg socket from qapi-schema, put them into crypto/. [Daniel]
>   - some Error report change. [Daniel]
>   - s/QCryptoAfalg/QCryptoAFAlg. [Daniel]
>   - use snprintf with bounds checking instead of sprintf. [Daniel]
>   - use "qcrypto_afalg_" prefix and 
> "qcrypto_nettle(gcrypt,glib,builtin)_" prefix. [Daniel]
>   - add testing results in cover-letter. [Gonglei]
> 
> ---
> Longpeng(Mike) (18):
>   crypto: cipher: introduce context free function
>   crypto: cipher: introduce qcrypto_cipher_ctx_new for gcrypt-backend
>   crypto: cipher: introduce qcrypto_cipher_ctx_new for nettle-backend
>   crypto: cipher: introduce qcrypto_cipher_ctx_new for builtin-backend
>   crypto: cipher: add cipher driver framework
>   crypto: hash: add hash driver framework
>   crypto: hmac: move crypto/hmac.h into include/crypto/
>   crypto: hmac: introduce qcrypto_hmac_ctx_new for gcrypt-backend
>   crypto: hmac: introduce qcrypto_hmac_ctx_new for nettle-backend
>   crypto: hmac: introduce qcrypto_hmac_ctx_new for glib-backend
>   crypto: hmac: add hmac driver framework
>   crypto: introduce some common functions for af_alg backend
>   crypto: cipher: add afalg-backend cipher support
>   crypto: hash: add afalg-backend hash support
>   crypto: hmac: add af_alg hmac support
>   tests: crypto: add cipher speed benchmark support
>   tests: crypto: add hash speed benchmark support
>   tests: crypto: add hmac speed benchmark support
> 
>  configure   |  21 
>  crypto/Makefile.objs|   3 +
>  crypto/afalg.c  | 115 
>  crypto/afalgpriv.h  |  64 +++
>  crypto/cipher-afalg.c   | 225 +++
>  crypto/cipher-builtin.c | 125 +++---
>  crypto/cipher-gcrypt.c  | 105 +-
>  crypto/cipher-nettle.c  |  84 +--
>  crypto/cipher.c |  91 
>  crypto/cipherpriv.h |  51 +
>  crypto/hash-afalg.c | 229 
> 
>  crypto/hash-gcrypt.c|  19 ++--
>  crypto/hash-glib.c  |  19 ++--
>  crypto/hash-nettle.c|  19 ++--
>  crypto/hash.c   |  24 +
>  crypto/hashpriv.h   |  35 ++
>  crypto/hmac-gcrypt.c

Re: [Qemu-devel] [PATCH v5 13/13] ppc: Add SM501 device in ppc softmmu targets default configs

2017-04-20 Thread David Gibson
On Thu, Apr 20, 2017 at 10:43:46PM +0200, BALATON Zoltan wrote:
> This is not used by default on any emulated machine yet but it is
> still useful to have it compiled so it can be added from the command
> line for clients that can use it (e.g. MorphOS has no driver for any
> other emulated video cards but can output via SM501)
> 
> Signed-off-by: BALATON Zoltan 

Sure, if you like.

Acked-by: David Gibson 

> ---
> 
> v5: Added sm501 also to ppc64-softmmu default config
> 
>  default-configs/ppc-softmmu.mak| 1 +
>  default-configs/ppc64-softmmu.mak  | 1 +
>  default-configs/ppcemb-softmmu.mak | 1 +
>  3 files changed, 3 insertions(+)
> 
> diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu.mak
> index 09c1d45..1f1cd85 100644
> --- a/default-configs/ppc-softmmu.mak
> +++ b/default-configs/ppc-softmmu.mak
> @@ -45,6 +45,7 @@ CONFIG_OPENPIC_KVM=$(and $(CONFIG_E500),$(CONFIG_KVM))
>  CONFIG_PLATFORM_BUS=y
>  CONFIG_ETSEC=y
>  CONFIG_LIBDECNUMBER=y
> +CONFIG_SM501=y
>  # For PReP
>  CONFIG_SERIAL_ISA=y
>  CONFIG_MC146818RTC=y
> diff --git a/default-configs/ppc64-softmmu.mak 
> b/default-configs/ppc64-softmmu.mak
> index 05c8335..f6ccb1b 100644
> --- a/default-configs/ppc64-softmmu.mak
> +++ b/default-configs/ppc64-softmmu.mak
> @@ -47,6 +47,7 @@ CONFIG_OPENPIC_KVM=$(and $(CONFIG_E500),$(CONFIG_KVM))
>  CONFIG_PLATFORM_BUS=y
>  CONFIG_ETSEC=y
>  CONFIG_LIBDECNUMBER=y
> +CONFIG_SM501=y
>  # For pSeries
>  CONFIG_XICS=$(CONFIG_PSERIES)
>  CONFIG_XICS_SPAPR=$(CONFIG_PSERIES)
> diff --git a/default-configs/ppcemb-softmmu.mak 
> b/default-configs/ppcemb-softmmu.mak
> index 7f56004..94340de 100644
> --- a/default-configs/ppcemb-softmmu.mak
> +++ b/default-configs/ppcemb-softmmu.mak
> @@ -15,3 +15,4 @@ CONFIG_I8259=y
>  CONFIG_XILINX=y
>  CONFIG_XILINX_ETHLITE=y
>  CONFIG_LIBDECNUMBER=y
> +CONFIG_SM501=y

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH] qemu-iotests: Remove PERL_PROG and BC_PROG

2017-04-20 Thread Fam Zheng
On Thu, 04/20 22:15, Kevin Wolf wrote:
> We test for the presence of perl and bc and save their path in the
> variables PERL_PROG and BC_PROG, but never actually make use of them.
> Remove the checks and assignments so qemu-iotests can run even when
> bc isn't installed.
> 
> Reported-by: Yash Mankad 
> Signed-off-by: Kevin Wolf 
> ---
>  tests/qemu-iotests/common.config | 6 --
>  1 file changed, 6 deletions(-)
> 
> diff --git a/tests/qemu-iotests/common.config 
> b/tests/qemu-iotests/common.config
> index 55527aa..1222e43 100644
> --- a/tests/qemu-iotests/common.config
> +++ b/tests/qemu-iotests/common.config
> @@ -75,18 +75,12 @@ _fatal()
>  exit 1
>  }
>  
> -export PERL_PROG="`set_prog_path perl`"
> -[ "$PERL_PROG" = "" ] && _fatal "perl not found"
> -

Then we should drop _readlink which is unused and uses perl too. Whether in this
patch together or in a separate patch doesn't matter much, so:

>  export AWK_PROG="`set_prog_path awk`"
>  [ "$AWK_PROG" = "" ] && _fatal "awk not found"
>  
>  export SED_PROG="`set_prog_path sed`"
>  [ "$SED_PROG" = "" ] && _fatal "sed not found"
>  
> -export BC_PROG="`set_prog_path bc`"
> -[ "$BC_PROG" = "" ] && _fatal "bc not found"
> -

The bc part is nice!

>  export PS_ALL_FLAGS="-ef"
>  
>  if [ -z "$QEMU_PROG" ]; then
> -- 
> 1.8.3.1
> 
> 

Reviewed-by: Fam Zheng 



Re: [Qemu-devel] [PATCH] sheepdog: Set error when connection fails

2017-04-20 Thread Fam Zheng
On Thu, 04/20 22:32, Kevin Wolf wrote:
> Am 20.04.2017 um 17:30 hat Daniel P. Berrange geschrieben:
> > On Thu, Apr 20, 2017 at 12:00:03PM +0800, Fam Zheng wrote:
> > > Signed-off-by: Fam Zheng 
> > > ---
> > >  block/sheepdog.c | 1 +
> > >  1 file changed, 1 insertion(+)
> > > 
> > > diff --git a/block/sheepdog.c b/block/sheepdog.c
> > > index fb9203e..7e889ee 100644
> > > --- a/block/sheepdog.c
> > > +++ b/block/sheepdog.c
> > > @@ -608,6 +608,7 @@ static int connect_to_sdog(BDRVSheepdogState *s, 
> > > Error **errp)
> > >  qemu_set_nonblock(fd);
> > >  } else {
> > >  fd = -EIO;
> > > +error_setg(errp, "Failed to connect to sheepdog server");
> > >  }
> > 
> > This doesn't make much sense to me. The lines just above the
> > diff context have this:
> > 
> > fd = socket_connect(s->addr, errp, NULL, NULL);

Oops! :(

> > 
> > socket_connect should have already reported an error on "errp"
> > in the scenario that 'fd == -1'.
> 
> By the way, am I the only one who thinks that having errp anywhere else
> than as the last argument is bad style? I can easily see myself missing
> that this functions sets it because the last argument is NULL.

Hmm, exactly.. Socket code does this here and there, and it's hard to read.

Fam



[Qemu-devel] [ANNOUNCE] QEMU 2.8.1.1 CVE update released

2017-04-20 Thread Michael Roth
Hi everyone,

A security update to the QEMU 2.8 series is now available at:

  http://wiki.qemu.org/download/qemu-2.8.1.1.tar.xz
  http://wiki.qemu.org/download/qemu-2.8.1.1.tar.xz.sig

v2.8.1.1 is now tagged in the official qemu.git repository,
and the stable-2.8 branch has been updated accordingly:

  http://git.qemu.org/?p=qemu.git;a=shortlog;h=refs/heads/stable-2.8

This release includes security fixes for:

  virtfs/virtio-9p shared directories (CVE-2017-7471)  

Please see the changelogs and relevant CVEs for more information, and
update accordingly.

Thank you to everyone involved!

CHANGELOG:

d1b725e: Update version for 2.8.1.1 release (Michael Roth)
96bae14: 9pfs: local: set the path of the export root to "." (Greg Kurz)




Re: [Qemu-devel] [PATCH v2] event: Add source information to SHUTDOWN

2017-04-20 Thread Alistair Francis
On Thu, Apr 20, 2017 at 12:05 PM, Eric Blake  wrote:
> On 04/20/2017 11:18 AM, Markus Armbruster wrote:
>> Eric Blake  writes:
>>
>>> On 04/20/2017 06:59 AM, Markus Armbruster wrote:
>>>

 No objection to Alistair's idea to turn this into an enumeration.
>>>
>>> Question - should the enum be more than just 'guest' and 'host'?  For
>>> example, my patch proves that we have a lot of places that handle
>>> complimentary machine commands to reset and shutdown, and that whether
>>> 'reset' triggers a reset (and the guest keeps running as if rebooted) or
>>> a shutdown is then based on the command-line arguments given to qemu.
>>> So having the enum differentiate between 'guest-reset' and
>>> 'guest-shutdown' would be a possibility, if we want the enum to have
>>> additional states.
>>
>> I don't know.  What I do know is that we better get the enum right:
>> while adding members is backwards-compatible, changing the member sent
>> for a specific trigger is not.  If we want to reserve the option to do
>> that anyway, we need suitable documentation.
>
> Or even this idea:
>
> { 'enum': 'ShutdownCause', 'data': [ 'shutdown', 'reset', 'panic' ] }
> { 'event': 'SHUTDOWN',
>   'data': { 'guest': 'bool', '*cause': 'ShutdownCause' } }
>
> where the enum can grow as we come up with ever more reasons worth
> exposing (maybe even 'qmp', 'gui' and 'interrupt' are reasonable causes
> for a host shutdown).  Our promise would be that 'guest' never changes
> for an existing shutdown reason, but that 'cause' may become more
> refined over time if someone expresses a need for having the distinction.
>
> Thoughts?

I'm not a fan of the 'guest' bool. I do see that it helps with
maintaining backwards compatibility but I think we would be better off
just getting the reasons right in the first place.

What about something that can grow in the future? We start with a
general guest shutdown that is always there and then as we add new
reasons things can be moved to use the new method or continue to use
the general one.

SHUTDOWN_HOST
SHUTDOWN_HOST_GUI
/* This is always a backwards compatible fall-back
 * Maybe this could be SHUTDOWN_GUEST_UNKNOWN instead?
 */
SHUTDOWN_GUEST_GENERAL
SHUTDOWN_GUEST_HALT
SHUTDOWN_GUEST_RESET
...

That way we can guarantee the base coverage but still expand more
specific reasons in the future.

I guess the only problem is that then the reasons aren't always
reliable then as we could introduce a new reason and something gets
stuck using the general fall back.

Thanks,

Alistair

>
> --
> Eric Blake, Principal Software Engineer
> Red Hat, Inc.   +1-919-301-3266
> Virtualization:  qemu.org | libvirt.org
>



Re: [Qemu-devel] [PATCH v5 07/13] sm501: Fix device endianness

2017-04-20 Thread Peter Maydell
On 20 April 2017 at 21:43, BALATON Zoltan  wrote:
> We only emulate the sysbus device in its default LE mode and PCI is LE
> as well so specify this for registers and framebuffer memory.
>
> Signed-off-by: BALATON Zoltan 
> ---

I think it's worth a comment to the effect of:

Note that though the Linux kernel driver has code which
claims to handle both big and little endian, it is obviously
bogus for 16 bit and cannot be trusted as a source of
information on the framebuffer pixel format. This is
our best guess about device behaviour based on the specs.

(so if we find ourselves wondering about this mismatch
in a couple of years time at least we'll know why this
end is the way it is.)

Reviewed-by: Peter Maydell 

thanks
-- PMM



Re: [Qemu-devel] question about block size and virtual disks

2017-04-20 Thread Eric Blake
On 04/20/2017 04:03 PM, Chris Friesen wrote:
> Hi,
> 
> Suppose the host has a physical disk that only supports 4KB access, with
> no 512B fallback.
> 
> If we boot a guest with "cache=none", does the guest need to be able to
> handle disks with 4KB blocks or is qemu able to handle guests trying to
> access the disk with 512B granularity?

qemu should be able to handle the fallback automatically (that is, the
block layer is smart enough to honor bs->bl.request_alignment=4096 such
that it will never submit a request smaller than 4096 to the underlying
host storage, regardless of what size request the guest uses).

In fact, the blkdebug driver can be used to test this setup on top of
any real driver constraints, so we have some pretty good assurance that
our minimum-size code works even when tested on a platform that still
has 512B granularity.

> 
> Also, does the 4KB block size get "passed-through" to the guest somehow
> so that the guest knows it needs to use 4KB blocks, or does that need to
> be explicitly specified via virtio-blk-pci.logical_block_size and/or
> virtio-blk-pci.physical_block_size parameters?  (Assuming I'm using
> virtio-blk-pci.)

Again, qemu should be passing the advertisement of host properties down
to the guest insofar as possible (so a good guest will see that the
hardware is 4k only and will not try to make 512-byte requests), but at
the same time, qemu should handle guests that are so old that they are
blissfully unaware of the hardware advertisements and send 512-byte
requests anyway.  Of course, such guests are penalized with
read-modify-write delays when submitting 512-byte IO.  But explicitly
stating available parameters is always the wisest course of action, if
you don't want to rely on defaults changing underneath you.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] question about block size and virtual disks

2017-04-20 Thread Chris Friesen

Hi,

Suppose the host has a physical disk that only supports 4KB access, with no 512B 
fallback.


If we boot a guest with "cache=none", does the guest need to be able to handle 
disks with 4KB blocks or is qemu able to handle guests trying to access the disk 
with 512B granularity?


Also, does the 4KB block size get "passed-through" to the guest somehow so that 
the guest knows it needs to use 4KB blocks, or does that need to be explicitly 
specified via virtio-blk-pci.logical_block_size and/or 
virtio-blk-pci.physical_block_size parameters?  (Assuming I'm using virtio-blk-pci.)


Thanks,
Chris



[Qemu-devel] [PATCH v5 08/13] sm501: Fix hardware cursor

2017-04-20 Thread BALATON Zoltan
Rework HWC handling to simplify it and fix cursor not updating on
screen as needed. Previously cursor was not updated because checking
for changes in a line overrode the update flag set for the cursor but
fixing this is not enough because the cursor should also be updated if
its shape or location changes. Introduce hwc_invalidate() function to
handle that similar to other display controller models.

Signed-off-by: BALATON Zoltan 
Reviewed-by: Peter Maydell 
---

v3: simplify return expression in get_bpp

 hw/display/sm501.c  | 169 +---
 hw/display/sm501_template.h |  25 +++
 2 files changed, 107 insertions(+), 87 deletions(-)

diff --git a/hw/display/sm501.c b/hw/display/sm501.c
index a628ef1..dc806a3 100644
--- a/hw/display/sm501.c
+++ b/hw/display/sm501.c
@@ -554,6 +554,24 @@ static uint32_t get_local_mem_size_index(uint32_t size)
 return index;
 }
 
+static inline int get_width(SM501State *s, int crt)
+{
+int width = crt ? s->dc_crt_h_total : s->dc_panel_h_total;
+return (width & 0x0FFF) + 1;
+}
+
+static inline int get_height(SM501State *s, int crt)
+{
+int height = crt ? s->dc_crt_v_total : s->dc_panel_v_total;
+return (height & 0x0FFF) + 1;
+}
+
+static inline int get_bpp(SM501State *s, int crt)
+{
+int bpp = crt ? s->dc_crt_control : s->dc_panel_control;
+return 1 << (bpp & 3);
+}
+
 /**
  * Check the availability of hardware cursor.
  * @param crt  0 for PANEL, 1 for CRT.
@@ -568,10 +586,10 @@ static inline int is_hwc_enabled(SM501State *state, int 
crt)
  * Get the address which holds cursor pattern data.
  * @param crt  0 for PANEL, 1 for CRT.
  */
-static inline uint32_t get_hwc_address(SM501State *state, int crt)
+static inline uint8_t *get_hwc_address(SM501State *state, int crt)
 {
 uint32_t addr = crt ? state->dc_crt_hwc_addr : state->dc_panel_hwc_addr;
-return (addr & 0x03F0)/* >> 4*/;
+return state->local_mem + (addr & 0x03F0);
 }
 
 /**
@@ -597,50 +615,48 @@ static inline uint32_t get_hwc_x(SM501State *state, int 
crt)
 }
 
 /**
- * Get the cursor position in x coordinate.
+ * Get the hardware cursor palette.
  * @param crt  0 for PANEL, 1 for CRT.
- * @param index  0, 1, 2 or 3 which specifies color of corsor dot.
+ * @param palette  pointer to a [3 * 3] array to store color values in
  */
-static inline uint16_t get_hwc_color(SM501State *state, int crt, int index)
+static inline void get_hwc_palette(SM501State *state, int crt, uint8_t 
*palette)
 {
-uint32_t color_reg = 0;
-uint16_t color_565 = 0;
-
-if (index == 0) {
-return 0;
-}
-
-switch (index) {
-case 1:
-case 2:
-color_reg = crt ? state->dc_crt_hwc_color_1_2
-: state->dc_panel_hwc_color_1_2;
-break;
-case 3:
-color_reg = crt ? state->dc_crt_hwc_color_3
-: state->dc_panel_hwc_color_3;
-break;
-default:
-printf("invalid hw cursor color.\n");
-abort();
-}
+int i;
+uint32_t color_reg;
+uint16_t rgb565;
+
+for (i = 0; i < 3; i++) {
+if (i + 1 == 3) {
+color_reg = crt ? state->dc_crt_hwc_color_3
+: state->dc_panel_hwc_color_3;
+} else {
+color_reg = crt ? state->dc_crt_hwc_color_1_2
+: state->dc_panel_hwc_color_1_2;
+}
 
-switch (index) {
-case 1:
-case 3:
-color_565 = (uint16_t)(color_reg & 0x);
-break;
-case 2:
-color_565 = (uint16_t)((color_reg >> 16) & 0x);
-break;
+if (i + 1 == 2) {
+rgb565 = (color_reg >> 16) & 0x;
+} else {
+rgb565 = color_reg & 0x;
+}
+palette[i * 3 + 0] = (rgb565 << 3) & 0xf8; /* red */
+palette[i * 3 + 1] = (rgb565 >> 3) & 0xfc; /* green */
+palette[i * 3 + 2] = (rgb565 >> 8) & 0xf8; /* blue */
 }
-return color_565;
 }
 
-static int within_hwc_y_range(SM501State *state, int y, int crt)
+static inline void hwc_invalidate(SM501State *s, int crt)
 {
-int hwc_y = get_hwc_y(state, crt);
-return (hwc_y <= y && y < hwc_y + SM501_HWC_HEIGHT);
+int w = get_width(s, crt);
+int h = get_height(s, crt);
+int bpp = get_bpp(s, crt);
+int start = get_hwc_y(s, crt);
+int end = MIN(h, start + SM501_HWC_HEIGHT) + 1;
+
+start *= w * bpp;
+end *= w * bpp;
+
+memory_region_set_dirty(&s->local_mem_region, start, end - start);
 }
 
 static void sm501_2d_operation(SM501State *s)
@@ -1021,10 +1037,18 @@ static void sm501_disp_ctrl_write(void *opaque, hwaddr 
addr,
 break;
 
 case SM501_DC_PANEL_HWC_ADDR:
-s->dc_panel_hwc_addr = value & 0x8FF0;
+value &= 0x8FF0;
+if (value != s->dc_panel_hwc_addr) {
+hwc_invalidate(s, 0);
+s->dc_panel_hwc_addr = value;
+}
 break;
 case SM501_DC_PANEL_HWC_LOC:
-s->

[Qemu-devel] [PATCH v5 01/13] sm501: Fixed code style and a few typos in comments

2017-04-20 Thread BALATON Zoltan
Signed-off-by: BALATON Zoltan 
Reviewed-by: Peter Maydell 
---
 hw/display/sm501.c  | 1132 ++-
 hw/display/sm501_template.h |   52 +-
 2 files changed, 594 insertions(+), 590 deletions(-)

diff --git a/hw/display/sm501.c b/hw/display/sm501.c
index 040a0b9..4f40dee 100644
--- a/hw/display/sm501.c
+++ b/hw/display/sm501.c
@@ -38,7 +38,7 @@
 /*
  * Status: 2010/05/07
  *   - Minimum implementation for Linux console : mmio regs and CRT layer.
- *   - 2D grapihcs acceleration partially supported : only fill rectangle.
+ *   - 2D graphics acceleration partially supported : only fill rectangle.
  *
  * TODO:
  *   - Panel support
@@ -49,13 +49,13 @@
  *   - Performance tuning
  */
 
-//#define DEBUG_SM501
-//#define DEBUG_BITBLT
+/*#define DEBUG_SM501*/
+/*#define DEBUG_BITBLT*/
 
 #ifdef DEBUG_SM501
 #define SM501_DPRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
 #else
-#define SM501_DPRINTF(fmt, ...) do {} while(0)
+#define SM501_DPRINTF(fmt, ...) do {} while (0)
 #endif
 
 
@@ -65,379 +65,379 @@
 
 /* System Configuration area */
 /* System config base */
-#define SM501_SYS_CONFIG   (0x00)
+#define SM501_SYS_CONFIG(0x00)
 
 /* config 1 */
-#define SM501_SYSTEM_CONTROL   (0x00)
+#define SM501_SYSTEM_CONTROL(0x00)
 
-#define SM501_SYSCTRL_PANEL_TRISTATE   (1<<0)
-#define SM501_SYSCTRL_MEM_TRISTATE (1<<1)
-#define SM501_SYSCTRL_CRT_TRISTATE (1<<2)
+#define SM501_SYSCTRL_PANEL_TRISTATE(1 << 0)
+#define SM501_SYSCTRL_MEM_TRISTATE  (1 << 1)
+#define SM501_SYSCTRL_CRT_TRISTATE  (1 << 2)
 
-#define SM501_SYSCTRL_PCI_SLAVE_BURST_MASK (3<<4)
-#define SM501_SYSCTRL_PCI_SLAVE_BURST_1(0<<4)
-#define SM501_SYSCTRL_PCI_SLAVE_BURST_2(1<<4)
-#define SM501_SYSCTRL_PCI_SLAVE_BURST_4(2<<4)
-#define SM501_SYSCTRL_PCI_SLAVE_BURST_8(3<<4)
+#define SM501_SYSCTRL_PCI_SLAVE_BURST_MASK (3 << 4)
+#define SM501_SYSCTRL_PCI_SLAVE_BURST_1 (0 << 4)
+#define SM501_SYSCTRL_PCI_SLAVE_BURST_2 (1 << 4)
+#define SM501_SYSCTRL_PCI_SLAVE_BURST_4 (2 << 4)
+#define SM501_SYSCTRL_PCI_SLAVE_BURST_8 (3 << 4)
 
-#define SM501_SYSCTRL_PCI_CLOCK_RUN_EN (1<<6)
-#define SM501_SYSCTRL_PCI_RETRY_DISABLE(1<<7)
-#define SM501_SYSCTRL_PCI_SUBSYS_LOCK  (1<<11)
-#define SM501_SYSCTRL_PCI_BURST_READ_EN(1<<15)
+#define SM501_SYSCTRL_PCI_CLOCK_RUN_EN  (1 << 6)
+#define SM501_SYSCTRL_PCI_RETRY_DISABLE (1 << 7)
+#define SM501_SYSCTRL_PCI_SUBSYS_LOCK   (1 << 11)
+#define SM501_SYSCTRL_PCI_BURST_READ_EN (1 << 15)
 
 /* miscellaneous control */
 
-#define SM501_MISC_CONTROL (0x04)
+#define SM501_MISC_CONTROL  (0x04)
 
-#define SM501_MISC_BUS_SH  (0x0)
-#define SM501_MISC_BUS_PCI (0x1)
-#define SM501_MISC_BUS_XSCALE  (0x2)
-#define SM501_MISC_BUS_NEC (0x6)
-#define SM501_MISC_BUS_MASK(0x7)
+#define SM501_MISC_BUS_SH   (0x0)
+#define SM501_MISC_BUS_PCI  (0x1)
+#define SM501_MISC_BUS_XSCALE   (0x2)
+#define SM501_MISC_BUS_NEC  (0x6)
+#define SM501_MISC_BUS_MASK (0x7)
 
-#define SM501_MISC_VR_62MB (1<<3)
-#define SM501_MISC_CDR_RESET   (1<<7)
-#define SM501_MISC_USB_LB  (1<<8)
-#define SM501_MISC_USB_SLAVE   (1<<9)
-#define SM501_MISC_BL_1(1<<10)
-#define SM501_MISC_MC  (1<<11)
-#define SM501_MISC_DAC_POWER   (1<<12)
-#define SM501_MISC_IRQ_INVERT  (1<<16)
-#define SM501_MISC_SH  (1<<17)
+#define SM501_MISC_VR_62MB  (1 << 3)
+#define SM501_MISC_CDR_RESET(1 << 7)
+#define SM501_MISC_USB_LB   (1 << 8)
+#define SM501_MISC_USB_SLAVE(1 << 9)
+#define SM501_MISC_BL_1 (1 << 10)
+#define SM501_MISC_MC   (1 << 11)
+#define SM501_MISC_DAC_POWER(1 << 12)
+#define SM501_MISC_IRQ_INVERT   (1 << 16)
+#define SM501_MISC_SH   (1 << 17)
 
-#define SM501_MISC_HOLD_EMPTY  (0<<18)
-#define SM501_MISC_HOLD_8  (1<<18)
-#define SM501_MISC_HOLD_16 (2<<18)
-#define SM501_MISC_HOLD_24 (3<<18)
-#define SM501_MISC_HOLD_32 (4<<18)
-#define SM501_MISC_HOLD_MASK   (7<<18)
+#define SM501_MISC_HOLD_EMPTY   (0 << 18)
+#define SM501_MISC_HOLD_8   (1 << 18)
+#define SM501_MISC_HOLD_16  (2 << 18)
+#define SM501_MISC_HOLD_24  (3 << 18)
+#define SM501_MISC_HOLD_32  (4 << 18)
+#define SM501_MISC_HOLD_MASK(7 << 18)
 
-#define SM501_MISC_FREQ_12 (1<<24)
-#define SM501_MISC_PNL_24BIT   (1<<25)
-#define SM501_MISC_8051_LE (1<<26)
+#define SM501_MISC_FREQ_12  (1 << 24)
+#define SM501_MISC_PNL_24BIT(1 << 25)
+#define SM501_MISC_8051_LE  (1 << 26)
 
 
 
-#define SM501_GPIO31_0_CONTROL 

[Qemu-devel] [PATCH v5 11/13] sm501: Add some more missing registers

2017-04-20 Thread BALATON Zoltan
This is to allow clients to initialise these without failing as long
as no 2D engine function is called that would use the written value.
Saved values are not used yet (may get used when more of 2D engine is
added sometimes) and clients normally only write to most of these
registers, nothing is known to ever read them but they are documented
as read/write so also implement read for these.

Signed-off-by: BALATON Zoltan 
Reviewed-by: Peter Maydell 
---

v2: Fixed mask of video_control register for a read only bit
Changed IRQ status register to write ignored as IRQ is not implemented
v3: Squashed read implementation into this patch
v4: Add reset for all 2D engine registers (although these are
documented to be 0 on reset, a comment in U-Boot source suggests that
they are really undefined so the previous version might have been enough)

 hw/display/sm501.c | 126 -
 1 file changed, 125 insertions(+), 1 deletion(-)

diff --git a/hw/display/sm501.c b/hw/display/sm501.c
index 8abac8f..851c7c8 100644
--- a/hw/display/sm501.c
+++ b/hw/display/sm501.c
@@ -512,6 +512,8 @@ typedef struct SM501State {
 uint32_t dc_panel_hwc_color_1_2;
 uint32_t dc_panel_hwc_color_3;
 
+uint32_t dc_video_control;
+
 uint32_t dc_crt_control;
 uint32_t dc_crt_fb_addr;
 uint32_t dc_crt_fb_offset;
@@ -531,13 +533,20 @@ typedef struct SM501State {
 uint32_t twoD_control;
 uint32_t twoD_pitch;
 uint32_t twoD_foreground;
+uint32_t twoD_background;
 uint32_t twoD_stretch;
+uint32_t twoD_color_compare;
 uint32_t twoD_color_compare_mask;
 uint32_t twoD_mask;
+uint32_t twoD_clip_tl;
+uint32_t twoD_clip_br;
+uint32_t twoD_mono_pattern_low;
+uint32_t twoD_mono_pattern_high;
 uint32_t twoD_window_width;
 uint32_t twoD_source_base;
 uint32_t twoD_destination_base;
-
+uint32_t twoD_alpha;
+uint32_t twoD_wrap;
 } SM501State;
 
 static uint32_t get_local_mem_size_index(uint32_t size)
@@ -946,6 +955,10 @@ static uint64_t sm501_disp_ctrl_read(void *opaque, hwaddr 
addr,
 ret = s->dc_panel_v_sync;
 break;
 
+case SM501_DC_VIDEO_CONTROL:
+ret = s->dc_video_control;
+break;
+
 case SM501_DC_CRT_CONTROL:
 ret = s->dc_crt_control;
 break;
@@ -1061,6 +1074,10 @@ static void sm501_disp_ctrl_write(void *opaque, hwaddr 
addr,
 s->dc_panel_hwc_color_3 = value & 0x;
 break;
 
+case SM501_DC_VIDEO_CONTROL:
+s->dc_video_control = value & 0x00037FFF;
+break;
+
 case SM501_DC_CRT_CONTROL:
 s->dc_crt_control = value & 0x0003;
 break;
@@ -1133,9 +1150,69 @@ static uint64_t sm501_2d_engine_read(void *opaque, 
hwaddr addr,
 SM501_DPRINTF("sm501 2d engine regs : read addr=%x\n", (int)addr);
 
 switch (addr) {
+case SM501_2D_SOURCE:
+ret = s->twoD_source;
+break;
+case SM501_2D_DESTINATION:
+ret = s->twoD_destination;
+break;
+case SM501_2D_DIMENSION:
+ret = s->twoD_dimension;
+break;
+case SM501_2D_CONTROL:
+ret = s->twoD_control;
+break;
+case SM501_2D_PITCH:
+ret = s->twoD_pitch;
+break;
+case SM501_2D_FOREGROUND:
+ret = s->twoD_foreground;
+break;
+case SM501_2D_BACKGROUND:
+ret = s->twoD_background;
+break;
+case SM501_2D_STRETCH:
+ret = s->twoD_stretch;
+break;
+case SM501_2D_COLOR_COMPARE:
+ret = s->twoD_color_compare;
+break;
+case SM501_2D_COLOR_COMPARE_MASK:
+ret = s->twoD_color_compare_mask;
+break;
+case SM501_2D_MASK:
+ret = s->twoD_mask;
+break;
+case SM501_2D_CLIP_TL:
+ret = s->twoD_clip_tl;
+break;
+case SM501_2D_CLIP_BR:
+ret = s->twoD_clip_br;
+break;
+case SM501_2D_MONO_PATTERN_LOW:
+ret = s->twoD_mono_pattern_low;
+break;
+case SM501_2D_MONO_PATTERN_HIGH:
+ret = s->twoD_mono_pattern_high;
+break;
+case SM501_2D_WINDOW_WIDTH:
+ret = s->twoD_window_width;
+break;
 case SM501_2D_SOURCE_BASE:
 ret = s->twoD_source_base;
 break;
+case SM501_2D_DESTINATION_BASE:
+ret = s->twoD_destination_base;
+break;
+case SM501_2D_ALPHA:
+ret = s->twoD_alpha;
+break;
+case SM501_2D_WRAP:
+ret = s->twoD_wrap;
+break;
+case SM501_2D_STATUS:
+ret = 0; /* Should return interrupt status */
+break;
 default:
 printf("sm501 disp ctrl : not implemented register read."
" addr=%x\n", (int)addr);
@@ -1178,15 +1255,33 @@ static void sm501_2d_engine_write(void *opaque, hwaddr 
addr,
 case SM501_2D_FOREGROUND:
 s->twoD_foreground = value;
 break;
+case SM501_2D_BACKGROUND:
+s->twoD_background = value;
+break;
 case SM501_2D_ST

[Qemu-devel] [PATCH v5 12/13] sm501: Add vmstate descriptor

2017-04-20 Thread BALATON Zoltan
Signed-off-by: BALATON Zoltan 
Reviewed-by: Peter Maydell 
---

v3: Added local_mem_size_index to vmstate, add vmstate for sysbus version too

 hw/display/sm501.c | 100 -
 1 file changed, 99 insertions(+), 1 deletion(-)

diff --git a/hw/display/sm501.c b/hw/display/sm501.c
index 851c7c8..00722b0 100644
--- a/hw/display/sm501.c
+++ b/hw/display/sm501.c
@@ -66,6 +66,7 @@
 
 #define MMIO_BASE_OFFSET 0x3e0
 #define MMIO_SIZE 0x20
+#define DC_PALETTE_ENTRIES (0x400 * 3)
 
 /* SM501 register definitions taken from "linux/include/linux/sm501-regs.h" */
 
@@ -492,7 +493,7 @@ typedef struct SM501State {
 uint32_t uart0_mcr;
 uint32_t uart0_scr;
 
-uint8_t dc_palette[0x400 * 3];
+uint8_t dc_palette[DC_PALETTE_ENTRIES];
 
 uint32_t dc_panel_control;
 uint32_t dc_panel_panning_control;
@@ -1618,6 +1619,78 @@ static void sm501_init(SM501State *s, DeviceState *dev,
 s->con = graphic_console_init(DEVICE(dev), 0, &sm501_ops, s);
 }
 
+static const VMStateDescription vmstate_sm501_state = {
+.name = "sm501-state",
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32(local_mem_size_index, SM501State),
+VMSTATE_UINT32(system_control, SM501State),
+VMSTATE_UINT32(misc_control, SM501State),
+VMSTATE_UINT32(gpio_31_0_control, SM501State),
+VMSTATE_UINT32(gpio_63_32_control, SM501State),
+VMSTATE_UINT32(dram_control, SM501State),
+VMSTATE_UINT32(arbitration_control, SM501State),
+VMSTATE_UINT32(irq_mask, SM501State),
+VMSTATE_UINT32(misc_timing, SM501State),
+VMSTATE_UINT32(power_mode_control, SM501State),
+VMSTATE_UINT32(uart0_ier, SM501State),
+VMSTATE_UINT32(uart0_lcr, SM501State),
+VMSTATE_UINT32(uart0_mcr, SM501State),
+VMSTATE_UINT32(uart0_scr, SM501State),
+VMSTATE_UINT8_ARRAY(dc_palette, SM501State, DC_PALETTE_ENTRIES),
+VMSTATE_UINT32(dc_panel_control, SM501State),
+VMSTATE_UINT32(dc_panel_panning_control, SM501State),
+VMSTATE_UINT32(dc_panel_fb_addr, SM501State),
+VMSTATE_UINT32(dc_panel_fb_offset, SM501State),
+VMSTATE_UINT32(dc_panel_fb_width, SM501State),
+VMSTATE_UINT32(dc_panel_fb_height, SM501State),
+VMSTATE_UINT32(dc_panel_tl_location, SM501State),
+VMSTATE_UINT32(dc_panel_br_location, SM501State),
+VMSTATE_UINT32(dc_panel_h_total, SM501State),
+VMSTATE_UINT32(dc_panel_h_sync, SM501State),
+VMSTATE_UINT32(dc_panel_v_total, SM501State),
+VMSTATE_UINT32(dc_panel_v_sync, SM501State),
+VMSTATE_UINT32(dc_panel_hwc_addr, SM501State),
+VMSTATE_UINT32(dc_panel_hwc_location, SM501State),
+VMSTATE_UINT32(dc_panel_hwc_color_1_2, SM501State),
+VMSTATE_UINT32(dc_panel_hwc_color_3, SM501State),
+VMSTATE_UINT32(dc_video_control, SM501State),
+VMSTATE_UINT32(dc_crt_control, SM501State),
+VMSTATE_UINT32(dc_crt_fb_addr, SM501State),
+VMSTATE_UINT32(dc_crt_fb_offset, SM501State),
+VMSTATE_UINT32(dc_crt_h_total, SM501State),
+VMSTATE_UINT32(dc_crt_h_sync, SM501State),
+VMSTATE_UINT32(dc_crt_v_total, SM501State),
+VMSTATE_UINT32(dc_crt_v_sync, SM501State),
+VMSTATE_UINT32(dc_crt_hwc_addr, SM501State),
+VMSTATE_UINT32(dc_crt_hwc_location, SM501State),
+VMSTATE_UINT32(dc_crt_hwc_color_1_2, SM501State),
+VMSTATE_UINT32(dc_crt_hwc_color_3, SM501State),
+VMSTATE_UINT32(twoD_source, SM501State),
+VMSTATE_UINT32(twoD_destination, SM501State),
+VMSTATE_UINT32(twoD_dimension, SM501State),
+VMSTATE_UINT32(twoD_control, SM501State),
+VMSTATE_UINT32(twoD_pitch, SM501State),
+VMSTATE_UINT32(twoD_foreground, SM501State),
+VMSTATE_UINT32(twoD_background, SM501State),
+VMSTATE_UINT32(twoD_stretch, SM501State),
+VMSTATE_UINT32(twoD_color_compare, SM501State),
+VMSTATE_UINT32(twoD_color_compare_mask, SM501State),
+VMSTATE_UINT32(twoD_mask, SM501State),
+VMSTATE_UINT32(twoD_clip_tl, SM501State),
+VMSTATE_UINT32(twoD_clip_br, SM501State),
+VMSTATE_UINT32(twoD_mono_pattern_low, SM501State),
+VMSTATE_UINT32(twoD_mono_pattern_high, SM501State),
+VMSTATE_UINT32(twoD_window_width, SM501State),
+VMSTATE_UINT32(twoD_source_base, SM501State),
+VMSTATE_UINT32(twoD_destination_base, SM501State),
+VMSTATE_UINT32(twoD_alpha, SM501State),
+VMSTATE_UINT32(twoD_wrap, SM501State),
+VMSTATE_END_OF_LIST()
+ }
+};
+
 #define TYPE_SYSBUS_SM501 "sysbus-sm501"
 #define SYSBUS_SM501(obj) \
 OBJECT_CHECK(SM501SysBusState, (obj), TYPE_SYSBUS_SM501)
@@ -1677,6 +1750,17 @@ static void sm501_reset_sysbus(DeviceState *dev)
 sm501_reset(&s->state);
 }
 
+static const VMStateDescription vmstate_sm501_sysbus = {
+.name = TYPE

[Qemu-devel] [PATCH v5 06/13] sm501: Add emulation of chip connected via PCI

2017-04-20 Thread BALATON Zoltan
Only the display controller part is created automatically on PCI

Signed-off-by: BALATON Zoltan 
Reviewed-by: Peter Maydell 
---

v2: Split off removing dependency on base address to separate patch
v3: Added reset function and PCI ID constant definitions in pci_ids.h
v4: Return error for invalid VRAM size, set bit in misc_control for PCI bus

 hw/display/sm501.c   | 65 
 include/hw/pci/pci_ids.h |  3 +++
 2 files changed, 68 insertions(+)

diff --git a/hw/display/sm501.c b/hw/display/sm501.c
index 09c023d..c92a5fa 100644
--- a/hw/display/sm501.c
+++ b/hw/display/sm501.c
@@ -32,6 +32,7 @@
 #include "ui/console.h"
 #include "hw/devices.h"
 #include "hw/sysbus.h"
+#include "hw/pci/pci.h"
 #include "qemu/range.h"
 #include "ui/pixel_ops.h"
 #include "exec/address-spaces.h"
@@ -1547,9 +1548,73 @@ static const TypeInfo sm501_sysbus_info = {
 .class_init= sm501_sysbus_class_init,
 };
 
+#define TYPE_PCI_SM501 "sm501"
+#define PCI_SM501(obj) OBJECT_CHECK(SM501PCIState, (obj), TYPE_PCI_SM501)
+
+typedef struct {
+/*< private >*/
+PCIDevice parent_obj;
+/*< public >*/
+SM501State state;
+uint32_t vram_size;
+} SM501PCIState;
+
+static void sm501_realize_pci(PCIDevice *dev, Error **errp)
+{
+SM501PCIState *s = PCI_SM501(dev);
+
+sm501_init(&s->state, DEVICE(dev), s->vram_size);
+if (get_local_mem_size(&s->state) != s->vram_size) {
+error_setg(errp, "Invalid VRAM size, nearest valid size is %" PRIu32,
+   get_local_mem_size(&s->state));
+return;
+}
+pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY,
+ &s->state.local_mem_region);
+pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY,
+ &s->state.mmio_region);
+}
+
+static Property sm501_pci_properties[] = {
+DEFINE_PROP_UINT32("vram-size", SM501PCIState, vram_size, 64 * M_BYTE),
+DEFINE_PROP_END_OF_LIST(),
+};
+
+static void sm501_reset_pci(DeviceState *dev)
+{
+SM501PCIState *s = PCI_SM501(dev);
+sm501_reset(&s->state);
+/* Bits 2:0 of misc_control register is 001 for PCI */
+s->state.misc_control |= 1;
+}
+
+static void sm501_pci_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+k->realize = sm501_realize_pci;
+k->vendor_id = PCI_VENDOR_ID_SILICON_MOTION;
+k->device_id = PCI_DEVICE_ID_SM501;
+k->class_id = PCI_CLASS_DISPLAY_OTHER;
+set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
+dc->desc = "SM501 Display Controller";
+dc->props = sm501_pci_properties;
+dc->reset = sm501_reset_pci;
+dc->hotpluggable = false;
+}
+
+static const TypeInfo sm501_pci_info = {
+.name  = TYPE_PCI_SM501,
+.parent= TYPE_PCI_DEVICE,
+.instance_size = sizeof(SM501PCIState),
+.class_init= sm501_pci_class_init,
+};
+
 static void sm501_register_types(void)
 {
 type_register_static(&sm501_sysbus_info);
+type_register_static(&sm501_pci_info);
 }
 
 type_init(sm501_register_types)
diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h
index d22ad8d..3752ddc 100644
--- a/include/hw/pci/pci_ids.h
+++ b/include/hw/pci/pci_ids.h
@@ -207,6 +207,9 @@
 
 #define PCI_VENDOR_ID_MARVELL0x11ab
 
+#define PCI_VENDOR_ID_SILICON_MOTION 0x126f
+#define PCI_DEVICE_ID_SM501  0x0501
+
 #define PCI_VENDOR_ID_ENSONIQ0x1274
 #define PCI_DEVICE_ID_ENSONIQ_ES1370 0x5000
 
-- 
2.7.4




[Qemu-devel] [PATCH v5 03/13] sm501: Add missing arbitration control register

2017-04-20 Thread BALATON Zoltan
Signed-off-by: BALATON Zoltan 
Reviewed-by: Peter Maydell 
---
 hw/display/sm501.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/hw/display/sm501.c b/hw/display/sm501.c
index 6b72964..6e74200 100644
--- a/hw/display/sm501.c
+++ b/hw/display/sm501.c
@@ -474,6 +474,7 @@ typedef struct SM501State {
 uint32_t gpio_31_0_control;
 uint32_t gpio_63_32_control;
 uint32_t dram_control;
+uint32_t arbitration_control;
 uint32_t irq_mask;
 uint32_t misc_timing;
 uint32_t power_mode_control;
@@ -757,6 +758,9 @@ static uint64_t sm501_system_config_read(void *opaque, 
hwaddr addr,
 case SM501_DRAM_CONTROL:
 ret = (s->dram_control & 0x07F107C0) | s->local_mem_size_index << 13;
 break;
+case SM501_ARBTRTN_CONTROL:
+ret = s->arbitration_control;
+break;
 case SM501_IRQ_MASK:
 ret = s->irq_mask;
 break;
@@ -809,6 +813,9 @@ static void sm501_system_config_write(void *opaque, hwaddr 
addr,
 /* TODO : check validity of size change */
 s->dram_control |=  value & 0x7FC3;
 break;
+case SM501_ARBTRTN_CONTROL:
+s->arbitration_control =  value & 0x3777;
+break;
 case SM501_IRQ_MASK:
 s->irq_mask = value;
 break;
@@ -1422,6 +1429,7 @@ void sm501_init(MemoryRegion *address_space_mem, uint32_t 
base,
  *  BUS = 0 : Hitachi SH3/SH4
  */
 s->misc_control = SM501_MISC_DAC_POWER;
+s->arbitration_control = 0x05146732;
 s->dc_panel_control = 0x0001; /* FIFO level 3 */
 s->dc_crt_control = 0x0001;
 
-- 
2.7.4




[Qemu-devel] [PATCH v5 05/13] sm501: Get rid of base address in draw_hwc_line

2017-04-20 Thread BALATON Zoltan
Do not use the base address to access data in local memory. This is in
preparation to allow chip connected via PCI where base address depends
on where the BAR is mapped so it will be unknown.

Signed-off-by: BALATON Zoltan 
Reviewed-by: Peter Maydell 
---
 hw/display/sm501.c  | 6 ++
 hw/display/sm501_template.h | 8 
 2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/hw/display/sm501.c b/hw/display/sm501.c
index 571a7e6..09c023d 100644
--- a/hw/display/sm501.c
+++ b/hw/display/sm501.c
@@ -461,7 +461,6 @@ typedef struct SM501State {
 QemuConsole *con;
 
 /* status & internal resources */
-hwaddr base;
 uint32_t local_mem_size_index;
 uint8_t *local_mem;
 MemoryRegion local_mem_region;
@@ -1432,10 +1431,9 @@ static void sm501_reset(SM501State *s)
 s->twoD_control = 0;
 }
 
-static void sm501_init(SM501State *s, DeviceState *dev, uint32_t base,
+static void sm501_init(SM501State *s, DeviceState *dev,
uint32_t local_mem_bytes)
 {
-s->base = base;
 s->local_mem_size_index = get_local_mem_size_index(local_mem_bytes);
 SM501_DPRINTF("sm501 local mem size=%x. index=%d\n", get_local_mem_size(s),
   s->local_mem_size_index);
@@ -1489,7 +1487,7 @@ static void sm501_realize_sysbus(DeviceState *dev, Error 
**errp)
 SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
 DeviceState *usb_dev;
 
-sm501_init(&s->state, dev, s->base, s->vram_size);
+sm501_init(&s->state, dev, s->vram_size);
 if (get_local_mem_size(&s->state) != s->vram_size) {
 error_setg(errp, "Invalid VRAM size, nearest valid size is %" PRIu32,
get_local_mem_size(&s->state));
diff --git a/hw/display/sm501_template.h b/hw/display/sm501_template.h
index 16e500b..832ee61 100644
--- a/hw/display/sm501_template.h
+++ b/hw/display/sm501_template.h
@@ -103,13 +103,13 @@ static void glue(draw_hwc_line_, PIXEL_NAME)(SM501State 
*s, int crt,
  uint8_t *palette, int c_y, uint8_t *d, int width)
 {
 int x, i;
-uint8_t bitset = 0;
+uint8_t *pixval, bitset = 0;
 
 /* get hardware cursor pattern */
 uint32_t cursor_addr = get_hwc_address(s, crt);
 assert(0 <= c_y && c_y < SM501_HWC_HEIGHT);
 cursor_addr += SM501_HWC_WIDTH * c_y / 4;  /* 4 pixels per byte */
-cursor_addr += s->base;
+pixval = s->local_mem + cursor_addr;
 
 /* get cursor position */
 x = get_hwc_x(s, crt);
@@ -120,8 +120,8 @@ static void glue(draw_hwc_line_, PIXEL_NAME)(SM501State *s, 
int crt,
 
 /* get pixel value */
 if (i % 4 == 0) {
-bitset = ldub_phys(&address_space_memory, cursor_addr);
-cursor_addr++;
+bitset = ldub_p(pixval);
+pixval++;
 }
 v = bitset & 3;
 bitset >>= 2;
-- 
2.7.4




[Qemu-devel] [PATCH v5 04/13] sm501: QOMify

2017-04-20 Thread BALATON Zoltan
Adding vmstate saving is not in this patch because the state structure
will be changed in further patches, then another patch will add
vmstate descriptor after those changes.

Signed-off-by: BALATON Zoltan 
Reviewed-by: Peter Maydell 
---

v2: Add memory regions to device state instead of allocating them
v3: Added reset function and make sure to use adjusted mem size when
creating local mem region (also print a warning when mem size was
adjusted)
v4: Replace warning for corrected memory size with a hard error

 hw/display/sm501.c   | 170 +--
 hw/sh4/r2d.c |  11 +++-
 include/hw/devices.h |   5 --
 3 files changed, 133 insertions(+), 53 deletions(-)

diff --git a/hw/display/sm501.c b/hw/display/sm501.c
index 6e74200..571a7e6 100644
--- a/hw/display/sm501.c
+++ b/hw/display/sm501.c
@@ -59,8 +59,8 @@
 #define SM501_DPRINTF(fmt, ...) do {} while (0)
 #endif
 
-
 #define MMIO_BASE_OFFSET 0x3e0
+#define MMIO_SIZE 0x20
 
 /* SM501 register definitions taken from "linux/include/linux/sm501-regs.h" */
 
@@ -465,6 +465,10 @@ typedef struct SM501State {
 uint32_t local_mem_size_index;
 uint8_t *local_mem;
 MemoryRegion local_mem_region;
+MemoryRegion mmio_region;
+MemoryRegion system_config_region;
+MemoryRegion disp_ctrl_region;
+MemoryRegion twoD_engine_region;
 uint32_t last_width;
 uint32_t last_height;
 
@@ -1404,21 +1408,8 @@ static const GraphicHwOps sm501_ops = {
 .gfx_update  = sm501_update_display,
 };
 
-void sm501_init(MemoryRegion *address_space_mem, uint32_t base,
-uint32_t local_mem_bytes, qemu_irq irq, Chardev *chr)
+static void sm501_reset(SM501State *s)
 {
-SM501State *s;
-DeviceState *dev;
-MemoryRegion *sm501_system_config = g_new(MemoryRegion, 1);
-MemoryRegion *sm501_disp_ctrl = g_new(MemoryRegion, 1);
-MemoryRegion *sm501_2d_engine = g_new(MemoryRegion, 1);
-
-/* allocate management data region */
-s = g_new0(SM501State, 1);
-s->base = base;
-s->local_mem_size_index = get_local_mem_size_index(local_mem_bytes);
-SM501_DPRINTF("local mem size=%x. index=%d\n", get_local_mem_size(s),
-  s->local_mem_size_index);
 s->system_control = 0x0010; /* 2D engine FIFO empty */
 /* Bits 17 (SH), 7 (CDR), 6:5 (Test), 2:0 (Bus) are all supposed
  * to be determined at reset by GPIO lines which set config bits.
@@ -1429,51 +1420,138 @@ void sm501_init(MemoryRegion *address_space_mem, 
uint32_t base,
  *  BUS = 0 : Hitachi SH3/SH4
  */
 s->misc_control = SM501_MISC_DAC_POWER;
+s->gpio_31_0_control = 0;
+s->gpio_63_32_control = 0;
+s->dram_control = 0;
 s->arbitration_control = 0x05146732;
+s->irq_mask = 0;
+s->misc_timing = 0;
+s->power_mode_control = 0;
 s->dc_panel_control = 0x0001; /* FIFO level 3 */
 s->dc_crt_control = 0x0001;
+s->twoD_control = 0;
+}
 
-/* allocate local memory */
-memory_region_init_ram(&s->local_mem_region, NULL, "sm501.local",
-   local_mem_bytes, &error_fatal);
+static void sm501_init(SM501State *s, DeviceState *dev, uint32_t base,
+   uint32_t local_mem_bytes)
+{
+s->base = base;
+s->local_mem_size_index = get_local_mem_size_index(local_mem_bytes);
+SM501_DPRINTF("sm501 local mem size=%x. index=%d\n", get_local_mem_size(s),
+  s->local_mem_size_index);
+
+/* local memory */
+memory_region_init_ram(&s->local_mem_region, OBJECT(dev), "sm501.local",
+   get_local_mem_size(s), &error_fatal);
 vmstate_register_ram_global(&s->local_mem_region);
 memory_region_set_log(&s->local_mem_region, true, DIRTY_MEMORY_VGA);
 s->local_mem = memory_region_get_ram_ptr(&s->local_mem_region);
-memory_region_add_subregion(address_space_mem, base, &s->local_mem_region);
-
-/* map mmio */
-memory_region_init_io(sm501_system_config, NULL, &sm501_system_config_ops,
-  s, "sm501-system-config", 0x6c);
-memory_region_add_subregion(address_space_mem, base + MMIO_BASE_OFFSET,
-sm501_system_config);
-memory_region_init_io(sm501_disp_ctrl, NULL, &sm501_disp_ctrl_ops, s,
+
+/* mmio */
+memory_region_init(&s->mmio_region, OBJECT(dev), "sm501.mmio", MMIO_SIZE);
+memory_region_init_io(&s->system_config_region, OBJECT(dev),
+  &sm501_system_config_ops, s,
+  "sm501-system-config", 0x6c);
+memory_region_add_subregion(&s->mmio_region, SM501_SYS_CONFIG,
+&s->system_config_region);
+memory_region_init_io(&s->disp_ctrl_region, OBJECT(dev),
+  &sm501_disp_ctrl_ops, s,
   "sm501-disp-ctrl", 0x1000);
-memory_region_add_subregion(address_space_mem,
-base + MMIO_BASE_OFFSET + SM501_DC,
-  

[Qemu-devel] [PATCH v5 09/13] sm501: Misc clean ups

2017-04-20 Thread BALATON Zoltan
- Rename a variable
- Move variable declarations out of loop to the beginning in draw_hwc_line

Signed-off-by: BALATON Zoltan 
Reviewed-by: Peter Maydell 
---
 hw/display/sm501.c  | 10 +-
 hw/display/sm501_template.h | 10 --
 2 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/hw/display/sm501.c b/hw/display/sm501.c
index dc806a3..2385f59 100644
--- a/hw/display/sm501.c
+++ b/hw/display/sm501.c
@@ -1313,7 +1313,7 @@ static void sm501_draw_crt(SM501State *s)
 uint32_t *palette = (uint32_t *)&s->dc_palette[SM501_DC_CRT_PALETTE -
SM501_DC_PANEL_PALETTE];
 uint8_t hwc_palette[3 * 3];
-int ds_depth_index = get_depth_index(surface);
+int dst_depth_index = get_depth_index(surface);
 draw_line_func *draw_line = NULL;
 draw_hwc_line_func *draw_hwc_line = NULL;
 int full_update = 0;
@@ -1325,13 +1325,13 @@ static void sm501_draw_crt(SM501State *s)
 /* choose draw_line function */
 switch (src_bpp) {
 case 1:
-draw_line = draw_line8_funcs[ds_depth_index];
+draw_line = draw_line8_funcs[dst_depth_index];
 break;
 case 2:
-draw_line = draw_line16_funcs[ds_depth_index];
+draw_line = draw_line16_funcs[dst_depth_index];
 break;
 case 4:
-draw_line = draw_line32_funcs[ds_depth_index];
+draw_line = draw_line32_funcs[dst_depth_index];
 break;
 default:
 printf("sm501 draw crt : invalid DC_CRT_CONTROL=%x.\n",
@@ -1343,7 +1343,7 @@ static void sm501_draw_crt(SM501State *s)
 /* set up to draw hardware cursor */
 if (is_hwc_enabled(s, 1)) {
 /* choose cursor draw line function */
-draw_hwc_line = draw_hwc_line_funcs[ds_depth_index];
+draw_hwc_line = draw_hwc_line_funcs[dst_depth_index];
 hwc_src = get_hwc_address(s, 1);
 c_x = get_hwc_x(s, 1);
 c_y = get_hwc_y(s, 1);
diff --git a/hw/display/sm501_template.h b/hw/display/sm501_template.h
index fa0d6a9..a60abad 100644
--- a/hw/display/sm501_template.h
+++ b/hw/display/sm501_template.h
@@ -96,7 +96,7 @@ static void glue(draw_hwc_line_, PIXEL_NAME)(uint8_t *d, 
const uint8_t *s,
  int width, const uint8_t *palette, int c_x, int c_y)
 {
 int i;
-uint8_t bitset = 0;
+uint8_t r, g, b, v, bitset = 0;
 
 /* get cursor position */
 assert(0 <= c_y && c_y < SM501_HWC_HEIGHT);
@@ -104,8 +104,6 @@ static void glue(draw_hwc_line_, PIXEL_NAME)(uint8_t *d, 
const uint8_t *s,
 d += c_x * BPP;
 
 for (i = 0; i < SM501_HWC_WIDTH && c_x + i < width; i++) {
-uint8_t v;
-
 /* get pixel value */
 if (i % 4 == 0) {
 bitset = ldub_p(s);
@@ -117,9 +115,9 @@ static void glue(draw_hwc_line_, PIXEL_NAME)(uint8_t *d, 
const uint8_t *s,
 /* write pixel */
 if (v) {
 v--;
-uint8_t r = palette[v * 3 + 0];
-uint8_t g = palette[v * 3 + 1];
-uint8_t b = palette[v * 3 + 2];
+r = palette[v * 3 + 0];
+g = palette[v * 3 + 1];
+b = palette[v * 3 + 2];
 *(PIXEL_TYPE *)d = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
 }
 d += BPP;
-- 
2.7.4




[Qemu-devel] [PATCH v5 10/13] sm501: Add support for panel layer

2017-04-20 Thread BALATON Zoltan
Signed-off-by: BALATON Zoltan 
Reviewed-by: Peter Maydell 
---

v2: Split off renaming a variable to separate clean up patch

 hw/display/sm501.c | 63 +++---
 1 file changed, 32 insertions(+), 31 deletions(-)

diff --git a/hw/display/sm501.c b/hw/display/sm501.c
index 2385f59..8abac8f 100644
--- a/hw/display/sm501.c
+++ b/hw/display/sm501.c
@@ -2,6 +2,7 @@
  * QEMU SM501 Device
  *
  * Copyright (c) 2008 Shin-ichiro KAWASAKI
+ * Copyright (c) 2016 BALATON Zoltan
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to 
deal
@@ -42,8 +43,11 @@
  *   - Minimum implementation for Linux console : mmio regs and CRT layer.
  *   - 2D graphics acceleration partially supported : only fill rectangle.
  *
- * TODO:
+ * Status: 2016/12/04
+ *   - Misc fixes: endianness, hardware cursor
  *   - Panel support
+ *
+ * TODO:
  *   - Touch panel support
  *   - USB support
  *   - UART support
@@ -1301,18 +1305,16 @@ static inline int get_depth_index(DisplaySurface 
*surface)
 }
 }
 
-static void sm501_draw_crt(SM501State *s)
+static void sm501_update_display(void *opaque)
 {
+SM501State *s = (SM501State *)opaque;
 DisplaySurface *surface = qemu_console_surface(s->con);
 int y, c_x, c_y;
-uint8_t *hwc_src, *src = s->local_mem;
-int width = get_width(s, 1);
-int height = get_height(s, 1);
-int src_bpp = get_bpp(s, 1);
+int crt = (s->dc_crt_control & SM501_DC_CRT_CONTROL_SEL) ? 1 : 0;
+int width = get_width(s, crt);
+int height = get_height(s, crt);
+int src_bpp = get_bpp(s, crt);
 int dst_bpp = surface_bytes_per_pixel(surface);
-uint32_t *palette = (uint32_t *)&s->dc_palette[SM501_DC_CRT_PALETTE -
-   SM501_DC_PANEL_PALETTE];
-uint8_t hwc_palette[3 * 3];
 int dst_depth_index = get_depth_index(surface);
 draw_line_func *draw_line = NULL;
 draw_hwc_line_func *draw_hwc_line = NULL;
@@ -1320,7 +1322,19 @@ static void sm501_draw_crt(SM501State *s)
 int y_start = -1;
 ram_addr_t page_min = ~0l;
 ram_addr_t page_max = 0l;
-ram_addr_t offset = 0;
+ram_addr_t offset;
+uint32_t *palette;
+uint8_t hwc_palette[3 * 3];
+uint8_t *hwc_src;
+
+if (!((crt ? s->dc_crt_control : s->dc_panel_control)
+  & SM501_DC_CRT_CONTROL_ENABLE)) {
+return;
+}
+
+palette = (uint32_t *)(crt ? &s->dc_palette[SM501_DC_CRT_PALETTE -
+SM501_DC_PANEL_PALETTE]
+   : &s->dc_palette[0]);
 
 /* choose draw_line function */
 switch (src_bpp) {
@@ -1334,20 +1348,19 @@ static void sm501_draw_crt(SM501State *s)
 draw_line = draw_line32_funcs[dst_depth_index];
 break;
 default:
-printf("sm501 draw crt : invalid DC_CRT_CONTROL=%x.\n",
-   s->dc_crt_control);
+printf("sm501 update display : invalid control register value.\n");
 abort();
 break;
 }
 
 /* set up to draw hardware cursor */
-if (is_hwc_enabled(s, 1)) {
+if (is_hwc_enabled(s, crt)) {
 /* choose cursor draw line function */
 draw_hwc_line = draw_hwc_line_funcs[dst_depth_index];
-hwc_src = get_hwc_address(s, 1);
-c_x = get_hwc_x(s, 1);
-c_y = get_hwc_y(s, 1);
-get_hwc_palette(s, 1, hwc_palette);
+hwc_src = get_hwc_address(s, crt);
+c_x = get_hwc_x(s, crt);
+c_y = get_hwc_y(s, crt);
+get_hwc_palette(s, crt, hwc_palette);
 }
 
 /* adjust console size */
@@ -1361,7 +1374,7 @@ static void sm501_draw_crt(SM501State *s)
 
 /* draw each line according to conditions */
 memory_region_sync_dirty_bitmap(&s->local_mem_region);
-for (y = 0; y < height; y++) {
+for (y = 0, offset = 0; y < height; y++, offset += width * src_bpp) {
 int update, update_hwc;
 ram_addr_t page0 = offset;
 ram_addr_t page1 = offset + width * src_bpp - 1;
@@ -1379,7 +1392,7 @@ static void sm501_draw_crt(SM501State *s)
 d +=  y * width * dst_bpp;
 
 /* draw graphics layer */
-draw_line(d, src, width, palette);
+draw_line(d, s->local_mem + offset, width, palette);
 
 /* draw hardware cursor */
 if (update_hwc) {
@@ -1402,9 +1415,6 @@ static void sm501_draw_crt(SM501State *s)
 y_start = -1;
 }
 }
-
-src += width * src_bpp;
-offset += width * src_bpp;
 }
 
 /* complete flush to display */
@@ -1420,15 +1430,6 @@ static void sm501_draw_crt(SM501State *s)
 }
 }
 
-static void sm501_update_display(void *opaque)
-{
-SM501State *s = (SM501State *)opaque;
-
-if (s->dc_crt_control & SM501_DC_CRT_CONTROL_ENABLE) {
-sm501_draw_crt(s);
-}
-}
-
 static const GraphicHwOps sm501_ops = {
 .gfx_upd

[Qemu-devel] [PATCH v5 02/13] sm501: Use defined constants instead of literal values where available

2017-04-20 Thread BALATON Zoltan
Signed-off-by: BALATON Zoltan 
Reviewed-by: Peter Maydell 
---

v3: Fix initial value of misc_control register as Peter Maydell suggested
Also use M_BYTE constant from cutils.h

 hw/display/sm501.c  | 29 +++--
 hw/display/sm501_template.h |  2 +-
 2 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/hw/display/sm501.c b/hw/display/sm501.c
index 4f40dee..6b72964 100644
--- a/hw/display/sm501.c
+++ b/hw/display/sm501.c
@@ -23,6 +23,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/cutils.h"
 #include "qapi/error.h"
 #include "qemu-common.h"
 #include "cpu.h"
@@ -446,12 +447,12 @@
 
 /* SM501 local memory size taken from "linux/drivers/mfd/sm501.c" */
 static const uint32_t sm501_mem_local_size[] = {
-[0] = 4 * 1024 * 1024,
-[1] = 8 * 1024 * 1024,
-[2] = 16 * 1024 * 1024,
-[3] = 32 * 1024 * 1024,
-[4] = 64 * 1024 * 1024,
-[5] = 2 * 1024 * 1024,
+[0] = 4 * M_BYTE,
+[1] = 8 * M_BYTE,
+[2] = 16 * M_BYTE,
+[3] = 32 * M_BYTE,
+[4] = 64 * M_BYTE,
+[5] = 2 * M_BYTE,
 };
 #define get_local_mem_size(s) sm501_mem_local_size[(s)->local_mem_size_index]
 
@@ -555,7 +556,7 @@ static uint32_t get_local_mem_size_index(uint32_t size)
 static inline int is_hwc_enabled(SM501State *state, int crt)
 {
 uint32_t addr = crt ? state->dc_crt_hwc_addr : state->dc_panel_hwc_addr;
-return addr & 0x8000;
+return addr & SM501_HWC_EN;
 }
 
 /**
@@ -1411,9 +1412,17 @@ void sm501_init(MemoryRegion *address_space_mem, 
uint32_t base,
 s->local_mem_size_index = get_local_mem_size_index(local_mem_bytes);
 SM501_DPRINTF("local mem size=%x. index=%d\n", get_local_mem_size(s),
   s->local_mem_size_index);
-s->system_control = 0x0010;
-s->misc_control = 0x1000; /* assumes SH, active=low */
-s->dc_panel_control = 0x0001;
+s->system_control = 0x0010; /* 2D engine FIFO empty */
+/* Bits 17 (SH), 7 (CDR), 6:5 (Test), 2:0 (Bus) are all supposed
+ * to be determined at reset by GPIO lines which set config bits.
+ * We hardwire them:
+ *  SH = 0 : Hitachi Ready Polarity == Active Low
+ *  CDR = 0 : do not reset clock divider
+ *  TEST = 0 : Normal mode (not testing the silicon)
+ *  BUS = 0 : Hitachi SH3/SH4
+ */
+s->misc_control = SM501_MISC_DAC_POWER;
+s->dc_panel_control = 0x0001; /* FIFO level 3 */
 s->dc_crt_control = 0x0001;
 
 /* allocate local memory */
diff --git a/hw/display/sm501_template.h b/hw/display/sm501_template.h
index aeeac5d..16e500b 100644
--- a/hw/display/sm501_template.h
+++ b/hw/display/sm501_template.h
@@ -108,7 +108,7 @@ static void glue(draw_hwc_line_, PIXEL_NAME)(SM501State *s, 
int crt,
 /* get hardware cursor pattern */
 uint32_t cursor_addr = get_hwc_address(s, crt);
 assert(0 <= c_y && c_y < SM501_HWC_HEIGHT);
-cursor_addr += 64 * c_y / 4;  /* 4 pixels per byte */
+cursor_addr += SM501_HWC_WIDTH * c_y / 4;  /* 4 pixels per byte */
 cursor_addr += s->base;
 
 /* get cursor position */
-- 
2.7.4




[Qemu-devel] [PATCH v5 00/13] Improvements for SM501 display controller emulation

2017-04-20 Thread BALATON Zoltan
Addressing all last review comments so hopefully this can get merged
now that tree is thawed.

BALATON Zoltan (13):
  sm501: Fixed code style and a few typos in comments
  sm501: Use defined constants instead of literal values where available
  sm501: Add missing arbitration control register
  sm501: QOMify
  sm501: Get rid of base address in draw_hwc_line
  sm501: Add emulation of chip connected via PCI
  sm501: Fix device endianness
  sm501: Fix hardware cursor
  sm501: Misc clean ups
  sm501: Add support for panel layer
  sm501: Add some more missing registers
  sm501: Add vmstate descriptor
  ppc: Add SM501 device in ppc softmmu targets default configs

 default-configs/ppc-softmmu.mak|1 +
 default-configs/ppc64-softmmu.mak  |1 +
 default-configs/ppcemb-softmmu.mak |1 +
 hw/display/sm501.c | 1784 ++--
 hw/display/sm501_template.h|   90 +-
 hw/sh4/r2d.c   |   11 +-
 include/hw/devices.h   |5 -
 include/hw/pci/pci_ids.h   |3 +
 8 files changed, 1150 insertions(+), 746 deletions(-)

-- 
2.7.4




[Qemu-devel] [PATCH v5 07/13] sm501: Fix device endianness

2017-04-20 Thread BALATON Zoltan
We only emulate the sysbus device in its default LE mode and PCI is LE
as well so specify this for registers and framebuffer memory.

Signed-off-by: BALATON Zoltan 
---

v2: Split off small clean up to other patch
v4: Set serial part to little endian as well
v5: Make framebuffer always LE as suggested by Peter Maydell

 hw/display/sm501.c  |  8 
 hw/display/sm501_template.h | 19 ++-
 2 files changed, 10 insertions(+), 17 deletions(-)

diff --git a/hw/display/sm501.c b/hw/display/sm501.c
index c92a5fa..a628ef1 100644
--- a/hw/display/sm501.c
+++ b/hw/display/sm501.c
@@ -850,7 +850,7 @@ static const MemoryRegionOps sm501_system_config_ops = {
 .min_access_size = 4,
 .max_access_size = 4,
 },
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static uint32_t sm501_palette_read(void *opaque, hwaddr addr)
@@ -1086,7 +1086,7 @@ static const MemoryRegionOps sm501_disp_ctrl_ops = {
 .min_access_size = 4,
 .max_access_size = 4,
 },
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static uint64_t sm501_2d_engine_read(void *opaque, hwaddr addr,
@@ -1174,7 +1174,7 @@ static const MemoryRegionOps sm501_2d_engine_ops = {
 .min_access_size = 4,
 .max_access_size = 4,
 },
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 /* draw line functions for all console modes */
@@ -1510,7 +1510,7 @@ static void sm501_realize_sysbus(DeviceState *dev, Error 
**errp)
 if (s->chr_state) {
 serial_mm_init(&s->state.mmio_region, SM501_UART0, 2,
NULL, /* TODO : chain irq to IRL */
-   115200, s->chr_state, DEVICE_NATIVE_ENDIAN);
+   115200, s->chr_state, DEVICE_LITTLE_ENDIAN);
 }
 }
 
diff --git a/hw/display/sm501_template.h b/hw/display/sm501_template.h
index 832ee61..54807bd 100644
--- a/hw/display/sm501_template.h
+++ b/hw/display/sm501_template.h
@@ -64,10 +64,10 @@ static void glue(draw_line16_, PIXEL_NAME)(
 uint8_t r, g, b;
 
 do {
-rgb565 = lduw_p(s);
-r = ((rgb565 >> 11) & 0x1f) << 3;
-g = ((rgb565 >>  5) & 0x3f) << 2;
-b = ((rgb565 >>  0) & 0x1f) << 3;
+rgb565 = lduw_le_p(s);
+r = (rgb565 >> 8) & 0xf8;
+g = (rgb565 >> 3) & 0xfc;
+b = (rgb565 << 3) & 0xf8;
 *(PIXEL_TYPE *)d = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
 s += 2;
 d += BPP;
@@ -80,16 +80,9 @@ static void glue(draw_line32_, PIXEL_NAME)(
 uint8_t r, g, b;
 
 do {
-ldub_p(s);
-#if defined(TARGET_WORDS_BIGENDIAN)
-r = s[1];
-g = s[2];
-b = s[3];
-#else
-b = s[0];
-g = s[1];
 r = s[2];
-#endif
+g = s[1];
+b = s[0];
 *(PIXEL_TYPE *)d = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
 s += 4;
 d += BPP;
-- 
2.7.4




[Qemu-devel] [PATCH v5 13/13] ppc: Add SM501 device in ppc softmmu targets default configs

2017-04-20 Thread BALATON Zoltan
This is not used by default on any emulated machine yet but it is
still useful to have it compiled so it can be added from the command
line for clients that can use it (e.g. MorphOS has no driver for any
other emulated video cards but can output via SM501)

Signed-off-by: BALATON Zoltan 
---

v5: Added sm501 also to ppc64-softmmu default config

 default-configs/ppc-softmmu.mak| 1 +
 default-configs/ppc64-softmmu.mak  | 1 +
 default-configs/ppcemb-softmmu.mak | 1 +
 3 files changed, 3 insertions(+)

diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu.mak
index 09c1d45..1f1cd85 100644
--- a/default-configs/ppc-softmmu.mak
+++ b/default-configs/ppc-softmmu.mak
@@ -45,6 +45,7 @@ CONFIG_OPENPIC_KVM=$(and $(CONFIG_E500),$(CONFIG_KVM))
 CONFIG_PLATFORM_BUS=y
 CONFIG_ETSEC=y
 CONFIG_LIBDECNUMBER=y
+CONFIG_SM501=y
 # For PReP
 CONFIG_SERIAL_ISA=y
 CONFIG_MC146818RTC=y
diff --git a/default-configs/ppc64-softmmu.mak 
b/default-configs/ppc64-softmmu.mak
index 05c8335..f6ccb1b 100644
--- a/default-configs/ppc64-softmmu.mak
+++ b/default-configs/ppc64-softmmu.mak
@@ -47,6 +47,7 @@ CONFIG_OPENPIC_KVM=$(and $(CONFIG_E500),$(CONFIG_KVM))
 CONFIG_PLATFORM_BUS=y
 CONFIG_ETSEC=y
 CONFIG_LIBDECNUMBER=y
+CONFIG_SM501=y
 # For pSeries
 CONFIG_XICS=$(CONFIG_PSERIES)
 CONFIG_XICS_SPAPR=$(CONFIG_PSERIES)
diff --git a/default-configs/ppcemb-softmmu.mak 
b/default-configs/ppcemb-softmmu.mak
index 7f56004..94340de 100644
--- a/default-configs/ppcemb-softmmu.mak
+++ b/default-configs/ppcemb-softmmu.mak
@@ -15,3 +15,4 @@ CONFIG_I8259=y
 CONFIG_XILINX=y
 CONFIG_XILINX_ETHLITE=y
 CONFIG_LIBDECNUMBER=y
+CONFIG_SM501=y
-- 
2.7.4




Re: [Qemu-devel] [PATCH] sheepdog: Set error when connection fails

2017-04-20 Thread Jeff Cody
On Thu, Apr 20, 2017 at 10:32:50PM +0200, Kevin Wolf wrote:
> Am 20.04.2017 um 17:30 hat Daniel P. Berrange geschrieben:
> > On Thu, Apr 20, 2017 at 12:00:03PM +0800, Fam Zheng wrote:
> > > Signed-off-by: Fam Zheng 
> > > ---
> > >  block/sheepdog.c | 1 +
> > >  1 file changed, 1 insertion(+)
> > > 
> > > diff --git a/block/sheepdog.c b/block/sheepdog.c
> > > index fb9203e..7e889ee 100644
> > > --- a/block/sheepdog.c
> > > +++ b/block/sheepdog.c
> > > @@ -608,6 +608,7 @@ static int connect_to_sdog(BDRVSheepdogState *s, 
> > > Error **errp)
> > >  qemu_set_nonblock(fd);
> > >  } else {
> > >  fd = -EIO;
> > > +error_setg(errp, "Failed to connect to sheepdog server");
> > >  }
> > 
> > This doesn't make much sense to me. The lines just above the
> > diff context have this:
> > 
> > fd = socket_connect(s->addr, errp, NULL, NULL);
> > 
> > socket_connect should have already reported an error on "errp"
> > in the scenario that 'fd == -1'.
> 
> By the way, am I the only one who thinks that having errp anywhere else
> than as the last argument is bad style? I can easily see myself missing
> that this functions sets it because the last argument is NULL.
>

No, you are not - that is precisely why I missed it in my review.


-Jeff



Re: [Qemu-devel] [PATCH] sheepdog: Set error when connection fails

2017-04-20 Thread Kevin Wolf
Am 20.04.2017 um 17:30 hat Daniel P. Berrange geschrieben:
> On Thu, Apr 20, 2017 at 12:00:03PM +0800, Fam Zheng wrote:
> > Signed-off-by: Fam Zheng 
> > ---
> >  block/sheepdog.c | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/block/sheepdog.c b/block/sheepdog.c
> > index fb9203e..7e889ee 100644
> > --- a/block/sheepdog.c
> > +++ b/block/sheepdog.c
> > @@ -608,6 +608,7 @@ static int connect_to_sdog(BDRVSheepdogState *s, Error 
> > **errp)
> >  qemu_set_nonblock(fd);
> >  } else {
> >  fd = -EIO;
> > +error_setg(errp, "Failed to connect to sheepdog server");
> >  }
> 
> This doesn't make much sense to me. The lines just above the
> diff context have this:
> 
> fd = socket_connect(s->addr, errp, NULL, NULL);
> 
> socket_connect should have already reported an error on "errp"
> in the scenario that 'fd == -1'.

By the way, am I the only one who thinks that having errp anywhere else
than as the last argument is bad style? I can easily see myself missing
that this functions sets it because the last argument is NULL.

Kevin



Re: [Qemu-devel] [PATCH v2] event: Add source information to SHUTDOWN

2017-04-20 Thread Eric Blake
On 04/19/2017 05:22 PM, Eric Blake wrote:
> Libvirt would like to be able to distinguish between a SHUTDOWN
> event triggered solely by guest request and one triggered by a
> SIGTERM or other action on the host.  qemu_kill_report() is
> already able to tell whether a shutdown was triggered by a host
> signal (but NOT by a host UI event, such as clicking the X on
> the window), but that information was then lost after being
> printed to stderr.
> 
> Enhance the shutdown request path to take a parameter of which
> way it is being triggered, and update ALL callers.  It would have
> been less churn to keep the common case with no arguments as
> meaning guest-triggered, and only modified the host-triggered
> code paths, via a wrapper function, but then we'd still have to
> audit that I didn't miss any host-triggered spots; changing the
> signature forces us to double-check that I correctly categorized
> all callers.
> 
> Here is output from 'virsh qemu-monitor-event --loop' with the
> patch installed:
> 
> event SHUTDOWN at 1492639680.731251 for domain fedora_13: {"guest":true}
> event STOP at 1492639680.732116 for domain fedora_13: 
> event SHUTDOWN at 1492639680.732830 for domain fedora_13: {"guest":false}

Another reason I'll need a v3: at least qemu-iotests 87 has to be
updated for new expected output.


-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [Qemu-block] [PATCH] qemu-iotests: Remove PERL_PROG and BC_PROG

2017-04-20 Thread Eric Blake
On 04/20/2017 03:15 PM, Kevin Wolf wrote:
> We test for the presence of perl and bc and save their path in the
> variables PERL_PROG and BC_PROG, but never actually make use of them.
> Remove the checks and assignments so qemu-iotests can run even when
> bc isn't installed.
> 
> Reported-by: Yash Mankad 
> Signed-off-by: Kevin Wolf 
> ---
>  tests/qemu-iotests/common.config | 6 --
>  1 file changed, 6 deletions(-)

Reviewed-by: Eric Blake 

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PATCH] qemu-iotests: Remove PERL_PROG and BC_PROG

2017-04-20 Thread Kevin Wolf
We test for the presence of perl and bc and save their path in the
variables PERL_PROG and BC_PROG, but never actually make use of them.
Remove the checks and assignments so qemu-iotests can run even when
bc isn't installed.

Reported-by: Yash Mankad 
Signed-off-by: Kevin Wolf 
---
 tests/qemu-iotests/common.config | 6 --
 1 file changed, 6 deletions(-)

diff --git a/tests/qemu-iotests/common.config b/tests/qemu-iotests/common.config
index 55527aa..1222e43 100644
--- a/tests/qemu-iotests/common.config
+++ b/tests/qemu-iotests/common.config
@@ -75,18 +75,12 @@ _fatal()
 exit 1
 }
 
-export PERL_PROG="`set_prog_path perl`"
-[ "$PERL_PROG" = "" ] && _fatal "perl not found"
-
 export AWK_PROG="`set_prog_path awk`"
 [ "$AWK_PROG" = "" ] && _fatal "awk not found"
 
 export SED_PROG="`set_prog_path sed`"
 [ "$SED_PROG" = "" ] && _fatal "sed not found"
 
-export BC_PROG="`set_prog_path bc`"
-[ "$BC_PROG" = "" ] && _fatal "bc not found"
-
 export PS_ALL_FLAGS="-ef"
 
 if [ -z "$QEMU_PROG" ]; then
-- 
1.8.3.1




Re: [Qemu-devel] [PATCH] qemu-img: simplify img_convert

2017-04-20 Thread Kevin Wolf
Am 20.04.2017 um 16:08 hat Peter Lieven geschrieben:
> Am 20.04.2017 um 16:05 schrieb Fam Zheng:
> >On Tue, 02/28 14:35, Peter Lieven wrote:
> >>img_convert has been around before there was an ImgConvertState or
> >>a block backend, but it has never been modified to directly use
> >>these structs. Change this by parsing parameters directly into
> >>the ImgConvertState and directly use BlockBackend where possible.
> >>Futhermore variable initalization has been reworked and sorted.
> >>
> >>Signed-off-by: Peter Lieven 
> >I see an iotest failure with this patch, in Kevin's block-next tree:
> >
> >019 1s ... - output mismatch (see 019.out.bad)
> >--- /stor/work/qemu/tests/qemu-iotests/019.out   2017-04-17 
> >16:19:56.523968474 +0800
> >+++ 019.out.bad  2017-04-20 22:03:29.868216955 +0800
> >@@ -1086,8 +1086,8 @@
> >  Checking if backing clusters are allocated when they shouldn't
> >-0/128 sectors allocated at offset 1 MiB
> >-0/128 sectors allocated at offset 4.001 GiB
> >+128/128 sectors allocated at offset 1 MiB
> >+128/128 sectors allocated at offset 4.001 GiB
> >  Reading
> >  === IO: pattern 42
> >Failures: 019
> >Failed 1 of 1 tests
> 
> Thanks for notifying, Fam.
> 
> @Kevin: Can you drop the patch again? I will send a V2 addressing this
> issue and the other comments I have got.

I could, but if it doesn't take too long, I'd prefer to only do so when
v2 is there. There are already a few conflicting patches and I asked
their authors to rebase onto yours, so it wouldn't be nice if they
wouldn't apply again because I removed your patch...

Kevin



Re: [Qemu-devel] [RFC PATCH 0/4] nvdimm: enable flush hint address structure

2017-04-20 Thread Dan Williams
On Tue, Apr 11, 2017 at 7:56 AM, Dan Williams  wrote:
> [ adding Christoph ]
>
> On Tue, Apr 11, 2017 at 1:41 AM, Haozhong Zhang
>  wrote:
>> On 04/06/17 20:02 +0800, Xiao Guangrong wrote:
>>>
>>>
>>> On 04/06/2017 05:43 PM, Stefan Hajnoczi wrote:
>>> > On Fri, Mar 31, 2017 at 04:41:43PM +0800, Haozhong Zhang wrote:
>>> > > This patch series constructs the flush hint address structures for
>>> > > nvdimm devices in QEMU.
>>> > >
>>> > > It's of course not for 2.9. I send it out early in order to get
>>> > > comments on one point I'm uncertain (see the detailed explanation
>>> > > below). Thanks for any comments in advance!
>>> > > Background
>>> > > ---
>>> >
>>> > Extra background:
>>> >
>>> > Flush Hint Addresses are necessary because:
>>> >
>>> > 1. Some hardware configurations may require them.  In other words, a
>>> >cache flush instruction is not enough to persist data.
>>> >
>>> > 2. The host file system may need fsync(2) calls (e.g. to persist
>>> >metadata changes).
>>> >
>>> > Without Flush Hint Addresses only some NVDIMM configurations actually
>>> > guarantee data persistence.
>>> >
>>> > > Flush hint address structure is a substructure of NFIT and specifies
>>> > > one or more addresses, namely Flush Hint Addresses. Software can write
>>> > > to any one of these flush hint addresses to cause any preceding writes
>>> > > to the NVDIMM region to be flushed out of the intervening platform
>>> > > buffers to the targeted NVDIMM. More details can be found in ACPI Spec
>>> > > 6.1, Section 5.2.25.8 "Flush Hint Address Structure".
>>> >
>>> > Do you have performance data?  I'm concerned that Flush Hint Address
>>> > hardware interface is not virtualization-friendly.
>>> >
>>> > In Linux drivers/nvdimm/region_devs.c:nvdimm_flush() does:
>>> >
>>> >   wmb();
>>> >   for (i = 0; i < nd_region->ndr_mappings; i++)
>>> >   if (ndrd_get_flush_wpq(ndrd, i, 0))
>>> >   writeq(1, ndrd_get_flush_wpq(ndrd, i, idx));
>>> >   wmb();
>>> >
>>> > That looks pretty lightweight - it's an MMIO write between write
>>> > barriers.
>>> >
>>> > This patch implements the MMIO write like this:
>>> >
>>> >   void nvdimm_flush(NVDIMMDevice *nvdimm)
>>> >   {
>>> >   if (nvdimm->backend_fd != -1) {
>>> >   /*
>>> >* If the backend store is a physical NVDIMM device, fsync()
>>> >* will trigger the flush via the flush hint on the host device.
>>> >*/
>>> >   fsync(nvdimm->backend_fd);
>>> >   }
>>> >   }
>>> >
>>> > The MMIO store instruction turned into a synchronous fsync(2) system
>>> > call plus vmexit/vmenter and QEMU userspace context switch:
>>> >
>>> > 1. The vcpu blocks during the fsync(2) system call.  The MMIO write
>>> >instruction has an unexpected and huge latency.
>>> >
>>> > 2. The vcpu thread holds the QEMU global mutex so all other threads
>>> >(including the monitor) are blocked during fsync(2).  Other vcpu
>>> >threads may block if they vmexit.
>>> >
>>> > It is hard to implement this efficiently in QEMU.  This is why I said
>>> > the hardware interface is not virtualization-friendly.  It's cheap on
>>> > real hardware but expensive under virtualization.
>>> >
>>> > We should think about the optimal way of implementing Flush Hint
>>> > Addresses in QEMU.  But if there is no reasonable way to implement them
>>> > then I think it's better *not* to implement them, just like the Block
>>> > Window feature which is also not virtualization-friendly.  Users who
>>> > want a block device can use virtio-blk.  I don't think NVDIMM Block
>>> > Window can achieve better performance than virtio-blk under
>>> > virtualization (although I'm happy to be proven wrong).
>>> >
>>> > Some ideas for a faster implementation:
>>> >
>>> > 1. Use memory_region_clear_global_locking() to avoid taking the QEMU
>>> >global mutex.  Little synchronization is necessary as long as the
>>> >NVDIMM device isn't hot unplugged (not yet supported anyway).
>>> >
>>> > 2. Can the host kernel provide a way to mmap Address Flush Hints from
>>> >the physical NVDIMM in cases where the configuration does not require
>>> >host kernel interception?  That way QEMU can map the physical
>>> >NVDIMM's Address Flush Hints directly into the guest.  The hypervisor
>>> >is bypassed and performance would be good.
>>> >
>>> > I'm not sure there is anything we can do to make the case where the host
>>> > kernel wants an fsync(2) fast :(.
>>>
>>> Good point.
>>>
>>> We can assume flush-CPU-cache-to-make-persistence is always
>>> available on Intel's hardware so that flush-hint-table is not
>>> needed if the vNVDIMM is based on a real Intel's NVDIMM device.
>>>
>>
>> We can let users of qemu (e.g. libvirt) detect whether the backend
>> device supports ADR, and pass 'flush-hint' option to qemu only if ADR
>> is not supported.
>>
>
> There currently is no ACPI mechanism to detect the presence of ADR.
> Also, you still need the flush for fs metad

Re: [Qemu-devel] [PATCH v2] event: Add source information to SHUTDOWN

2017-04-20 Thread Eric Blake
On 04/20/2017 11:18 AM, Markus Armbruster wrote:
> Eric Blake  writes:
> 
>> On 04/20/2017 06:59 AM, Markus Armbruster wrote:
>>
>>>
>>> No objection to Alistair's idea to turn this into an enumeration.
>>
>> Question - should the enum be more than just 'guest' and 'host'?  For
>> example, my patch proves that we have a lot of places that handle
>> complimentary machine commands to reset and shutdown, and that whether
>> 'reset' triggers a reset (and the guest keeps running as if rebooted) or
>> a shutdown is then based on the command-line arguments given to qemu.
>> So having the enum differentiate between 'guest-reset' and
>> 'guest-shutdown' would be a possibility, if we want the enum to have
>> additional states.
> 
> I don't know.  What I do know is that we better get the enum right:
> while adding members is backwards-compatible, changing the member sent
> for a specific trigger is not.  If we want to reserve the option to do
> that anyway, we need suitable documentation.

Or even this idea:

{ 'enum': 'ShutdownCause', 'data': [ 'shutdown', 'reset', 'panic' ] }
{ 'event': 'SHUTDOWN',
  'data': { 'guest': 'bool', '*cause': 'ShutdownCause' } }

where the enum can grow as we come up with ever more reasons worth
exposing (maybe even 'qmp', 'gui' and 'interrupt' are reasonable causes
for a host shutdown).  Our promise would be that 'guest' never changes
for an existing shutdown reason, but that 'cause' may become more
refined over time if someone expresses a need for having the distinction.

Thoughts?

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PULL 15/15] qdev: Constify local variable returned by blk_bs

2017-04-20 Thread Eduardo Habkost
From: Krzysztof Kozlowski 

Inside qdev_prop_set_drive() the value returned by blk_bs() is passed
only as pointer to const to bdrv_get_node_name() and pointed values is
not modified in other places so this can be made const for code
safeness.

Signed-off-by: Krzysztof Kozlowski 
Message-Id: <20170310200550.13313-3-k...@kernel.org>
Signed-off-by: Eduardo Habkost 
---
 hw/core/qdev-properties-system.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index e885e650fb..79c2014135 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -409,7 +409,7 @@ void qdev_prop_set_drive(DeviceState *dev, const char *name,
 if (value) {
 ref = blk_name(value);
 if (!*ref) {
-BlockDriverState *bs = blk_bs(value);
+const BlockDriverState *bs = blk_bs(value);
 if (bs) {
 ref = bdrv_get_node_name(bs);
 }
-- 
2.11.0.259.g40922b1




[Qemu-devel] [PULL 13/15] hostmem: use host_memory_backend_mr_inited() where proper

2017-04-20 Thread Eduardo Habkost
From: Peter Xu 

Use the new interface to boost readability.

Signed-off-by: Peter Xu 
Message-Id: <1489151370-15453-3-git-send-email-pet...@redhat.com>
Reviewed-by: Eduardo Habkost 
Signed-off-by: Eduardo Habkost 
---
 backends/hostmem-file.c |  6 +++---
 backends/hostmem.c  | 10 +-
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c
index 42efb2f28a..fc4ef46d11 100644
--- a/backends/hostmem-file.c
+++ b/backends/hostmem-file.c
@@ -51,7 +51,7 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error 
**errp)
 #ifndef CONFIG_LINUX
 error_setg(errp, "-mem-path not supported on this host");
 #else
-if (!memory_region_size(&backend->mr)) {
+if (!host_memory_backend_mr_inited(backend)) {
 gchar *path;
 backend->force_prealloc = mem_prealloc;
 path = object_get_canonical_path(OBJECT(backend));
@@ -76,7 +76,7 @@ static void set_mem_path(Object *o, const char *str, Error 
**errp)
 HostMemoryBackend *backend = MEMORY_BACKEND(o);
 HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
 
-if (memory_region_size(&backend->mr)) {
+if (host_memory_backend_mr_inited(backend)) {
 error_setg(errp, "cannot change property value");
 return;
 }
@@ -96,7 +96,7 @@ static void file_memory_backend_set_share(Object *o, bool 
value, Error **errp)
 HostMemoryBackend *backend = MEMORY_BACKEND(o);
 HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
 
-if (memory_region_size(&backend->mr)) {
+if (host_memory_backend_mr_inited(backend)) {
 error_setg(errp, "cannot change property value");
 return;
 }
diff --git a/backends/hostmem.c b/backends/hostmem.c
index d8faab4bed..4606b73849 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -45,7 +45,7 @@ host_memory_backend_set_size(Object *obj, Visitor *v, const 
char *name,
 Error *local_err = NULL;
 uint64_t value;
 
-if (memory_region_size(&backend->mr)) {
+if (host_memory_backend_mr_inited(backend)) {
 error_setg(&local_err, "cannot change property value");
 goto out;
 }
@@ -146,7 +146,7 @@ static void host_memory_backend_set_merge(Object *obj, bool 
value, Error **errp)
 {
 HostMemoryBackend *backend = MEMORY_BACKEND(obj);
 
-if (!memory_region_size(&backend->mr)) {
+if (!host_memory_backend_mr_inited(backend)) {
 backend->merge = value;
 return;
 }
@@ -172,7 +172,7 @@ static void host_memory_backend_set_dump(Object *obj, bool 
value, Error **errp)
 {
 HostMemoryBackend *backend = MEMORY_BACKEND(obj);
 
-if (!memory_region_size(&backend->mr)) {
+if (!host_memory_backend_mr_inited(backend)) {
 backend->dump = value;
 return;
 }
@@ -208,7 +208,7 @@ static void host_memory_backend_set_prealloc(Object *obj, 
bool value,
 }
 }
 
-if (!memory_region_size(&backend->mr)) {
+if (!host_memory_backend_mr_inited(backend)) {
 backend->prealloc = value;
 return;
 }
@@ -249,7 +249,7 @@ bool host_memory_backend_mr_inited(HostMemoryBackend 
*backend)
 MemoryRegion *
 host_memory_backend_get_memory(HostMemoryBackend *backend, Error **errp)
 {
-return memory_region_size(&backend->mr) ? &backend->mr : NULL;
+return host_memory_backend_mr_inited(backend) ? &backend->mr : NULL;
 }
 
 void host_memory_backend_set_mapped(HostMemoryBackend *backend, bool mapped)
-- 
2.11.0.259.g40922b1




[Qemu-devel] [PULL 11/15] hw/core/null-machine: Print error message when using the -kernel parameter

2017-04-20 Thread Eduardo Habkost
From: Thomas Huth 

If the user currently tries to use the -kernel parameter, simply nothing
happens, and the user might get confused that there is nothing loaded
to memory, but also no error message has been issued. Since there is no
real generic way to load a kernel on all CPU types (but on some targets,
the generic loader can be used instead), issue an appropriate error
message here now to avoid the possible confusion.

Signed-off-by: Thomas Huth 
Message-Id: <1488271971-12624-1-git-send-email-th...@redhat.com>
Reviewed-by: Marcel Apfelbaum 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Eduardo Habkost 
Signed-off-by: Eduardo Habkost 
---
 hw/core/null-machine.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/hw/core/null-machine.c b/hw/core/null-machine.c
index 27c8369b57..864832db34 100644
--- a/hw/core/null-machine.c
+++ b/hw/core/null-machine.c
@@ -40,6 +40,12 @@ static void machine_none_init(MachineState *mch)
 memory_region_allocate_system_memory(ram, NULL, "ram", mch->ram_size);
 memory_region_add_subregion(get_system_memory(), 0, ram);
 }
+
+if (mch->kernel_filename) {
+error_report("The -kernel parameter is not supported "
+ "(use the generic 'loader' device instead).");
+exit(1);
+}
 }
 
 static void machine_none_machine_init(MachineClass *mc)
-- 
2.11.0.259.g40922b1




[Qemu-devel] [PULL 10/15] qdev: Make "hotplugged" property read-only

2017-04-20 Thread Eduardo Habkost
The "hotplugged" property is user visible, but it was never meant
to be set by the user. There are probably multiple ways to break
or crash device code by overriding the property. For example, we
recently fixed a crash in rtc_set_memory() related to the
property (commit 26ef65beab852caf2b1ef4976e3473f2d525164d).

There has been some discussion about making management software
use "hotplugged=on" on migration, to indicate devices that were
hotplugged in the migration source. There were other suggestions
to address this, like including the "hotplugged" field in the
migration stream instead of requiring it to be set explicitly.

Whatever solution we choose in the future, this patch disables
setting "hotplugged" explicitly in the command-line by now,
because the ability to set the property is unused, untested, and
undocumented.

Signed-off-by: Eduardo Habkost 
Message-Id: <20170222192647.19690-1-ehabk...@redhat.com>
Reviewed-by: Eric Blake 
Reviewed-by: Markus Armbruster 
Signed-off-by: Eduardo Habkost 
---
 hw/core/qdev.c | 9 +
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 1e7fb33246..695d7c4216 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -1037,13 +1037,6 @@ static bool device_get_hotplugged(Object *obj, Error 
**err)
 return dev->hotplugged;
 }
 
-static void device_set_hotplugged(Object *obj, bool value, Error **err)
-{
-DeviceState *dev = DEVICE(obj);
-
-dev->hotplugged = value;
-}
-
 static void device_initfn(Object *obj)
 {
 DeviceState *dev = DEVICE(obj);
@@ -1063,7 +1056,7 @@ static void device_initfn(Object *obj)
 object_property_add_bool(obj, "hotpluggable",
  device_get_hotpluggable, NULL, NULL);
 object_property_add_bool(obj, "hotplugged",
- device_get_hotplugged, device_set_hotplugged,
+ device_get_hotplugged, NULL,
  &error_abort);
 
 class = object_get_class(OBJECT(dev));
-- 
2.11.0.259.g40922b1




Re: [Qemu-devel] [PATCH v2 1/2] migration: don't close a file descriptor while it can be in use

2017-04-20 Thread Dr. David Alan Gilbert
* Laurent Vivier (lviv...@redhat.com) wrote:
> If we close the QEMUFile descriptor in process_incoming_migration_co()
> while it has been stopped by an error, the postcopy_ram_listen_thread()
> can try to continue to use it. And as the memory has been freed
> it is working with an invalid pointer and crashes.
> 
> Fix this by releasing the memory after having managed the error
> case (which, in fact, calls exit())
> 
> Signed-off-by: Laurent Vivier 

Reviewed-by: Dr. David Alan Gilbert 

Yes, this took me some thinking about why it got there.
(I only managed to reproduce this case once, even with 'tc')

'LISTEN' message via loadvm_postcopy_handle_listen,
postcopy state is set to LISTENING
sets mis->have_listen_thread
starts 'listen' thread
Errors while 'loading state of instance...' so fails
   qemu_loadvm_state_main in loadvm_handle_cmd_packaged
   fails loadvm_process_command
   fails qemu_loadvm_state_main
   fails in qemu_loadvm_state
   has mis->have_listen_thread
   process_incoming_migration_co
  since ret < 0 fails now rather than leaving it to the
  'listening thread' - which is probably still alive

Dave


> ---
>  migration/migration.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/migration/migration.c b/migration/migration.c
> index ad4036f..e024e0a 100644
> --- a/migration/migration.c
> +++ b/migration/migration.c
> @@ -436,9 +436,6 @@ static void process_incoming_migration_co(void *opaque)
>  qemu_thread_join(&mis->colo_incoming_thread);
>  }
>  
> -qemu_fclose(f);
> -free_xbzrle_decoded_buf();
> -
>  if (ret < 0) {
>  migrate_set_state(&mis->state, MIGRATION_STATUS_ACTIVE,
>MIGRATION_STATUS_FAILED);
> @@ -447,6 +444,9 @@ static void process_incoming_migration_co(void *opaque)
>  exit(EXIT_FAILURE);
>  }
>  
> +qemu_fclose(f);
> +free_xbzrle_decoded_buf();
> +
>  mis->bh = qemu_bh_new(process_incoming_migration_bh, mis);
>  qemu_bh_schedule(mis->bh);
>  }
> -- 
> 2.9.3
> 
--
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK



[Qemu-devel] [PULL 14/15] qdev: Constify value passed to qdev_prop_set_macaddr

2017-04-20 Thread Eduardo Habkost
From: Krzysztof Kozlowski 

The 'value' argument is not modified so this can be made const for code
safeness.

Signed-off-by: Krzysztof Kozlowski 
Message-Id: <20170310200550.13313-2-k...@kernel.org>
Signed-off-by: Eduardo Habkost 
---
 include/hw/qdev-properties.h | 3 ++-
 hw/core/qdev-properties.c| 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 7ac315331a..1d69fa7a8f 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -188,7 +188,8 @@ void qdev_prop_set_chr(DeviceState *dev, const char *name, 
Chardev *value);
 void qdev_prop_set_netdev(DeviceState *dev, const char *name, NetClientState 
*value);
 void qdev_prop_set_drive(DeviceState *dev, const char *name,
  BlockBackend *value, Error **errp);
-void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value);
+void qdev_prop_set_macaddr(DeviceState *dev, const char *name,
+   const uint8_t *value);
 void qdev_prop_set_enum(DeviceState *dev, const char *name, int value);
 /* FIXME: Remove opaque pointer properties.  */
 void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value);
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 6ab4265eb4..fa3617db2d 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -1010,7 +1010,8 @@ void qdev_prop_set_string(DeviceState *dev, const char 
*name, const char *value)
 object_property_set_str(OBJECT(dev), value, name, &error_abort);
 }
 
-void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
+void qdev_prop_set_macaddr(DeviceState *dev, const char *name,
+   const uint8_t *value)
 {
 char str[2 * 6 + 5 + 1];
 snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
-- 
2.11.0.259.g40922b1




[Qemu-devel] [PULL 09/15] intel_iommu: enable remote IOTLB

2017-04-20 Thread Eduardo Habkost
From: Peter Xu 

This patch is based on Aviv Ben-David ()'s patch
upstream:

  "IOMMU: enable intel_iommu map and unmap notifiers"
  https://lists.gnu.org/archive/html/qemu-devel/2016-11/msg01453.html

However I removed/fixed some content, and added my own codes.

Instead of translate() every page for iotlb invalidations (which is
slower), we walk the pages when needed and notify in a hook function.

This patch enables vfio devices for VT-d emulation.

And, since we already have vhost DMAR support via device-iotlb, a
natural benefit that this patch brings is that vt-d enabled vhost can
live even without ATS capability now. Though more tests are needed.

Signed-off-by: Aviv Ben-David 
Reviewed-by: Jason Wang 
Reviewed-by: David Gibson 
Reviewed-by: \"Michael S. Tsirkin\" 
Signed-off-by: Peter Xu 
Message-Id: <1491562755-23867-10-git-send-email-pet...@redhat.com>
Signed-off-by: Eduardo Habkost 
---
 hw/i386/intel_iommu_internal.h |   1 +
 include/hw/i386/intel_iommu.h  |   8 ++
 hw/i386/intel_iommu.c  | 191 ++---
 hw/i386/trace-events   |   1 +
 4 files changed, 188 insertions(+), 13 deletions(-)

diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h
index 41041219ba..29d67075f4 100644
--- a/hw/i386/intel_iommu_internal.h
+++ b/hw/i386/intel_iommu_internal.h
@@ -197,6 +197,7 @@
 #define VTD_DOMAIN_ID_MASK  ((1UL << VTD_DOMAIN_ID_SHIFT) - 1)
 #define VTD_CAP_ND  (((VTD_DOMAIN_ID_SHIFT - 4) / 2) & 7ULL)
 #define VTD_MGAW39  /* Maximum Guest Address Width */
+#define VTD_ADDRESS_SIZE(1ULL << VTD_MGAW)
 #define VTD_CAP_MGAW(((VTD_MGAW - 1) & 0x3fULL) << 16)
 #define VTD_MAMV18ULL
 #define VTD_CAP_MAMV(VTD_MAMV << 48)
diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h
index 8f212a1198..3e51876b75 100644
--- a/include/hw/i386/intel_iommu.h
+++ b/include/hw/i386/intel_iommu.h
@@ -63,6 +63,7 @@ typedef union VTD_IR_TableEntry VTD_IR_TableEntry;
 typedef union VTD_IR_MSIAddress VTD_IR_MSIAddress;
 typedef struct VTDIrq VTDIrq;
 typedef struct VTD_MSIMessage VTD_MSIMessage;
+typedef struct IntelIOMMUNotifierNode IntelIOMMUNotifierNode;
 
 /* Context-Entry */
 struct VTDContextEntry {
@@ -249,6 +250,11 @@ struct VTD_MSIMessage {
 /* When IR is enabled, all MSI/MSI-X data bits should be zero */
 #define VTD_IR_MSI_DATA  (0)
 
+struct IntelIOMMUNotifierNode {
+VTDAddressSpace *vtd_as;
+QLIST_ENTRY(IntelIOMMUNotifierNode) next;
+};
+
 /* The iommu (DMAR) device state struct */
 struct IntelIOMMUState {
 X86IOMMUState x86_iommu;
@@ -286,6 +292,8 @@ struct IntelIOMMUState {
 MemoryRegionIOMMUOps iommu_ops;
 GHashTable *vtd_as_by_busptr;   /* VTDBus objects indexed by PCIBus* 
reference */
 VTDBus *vtd_as_by_bus_num[VTD_PCI_BUS_MAX]; /* VTDBus objects indexed by 
bus number */
+/* list of registered notifiers */
+QLIST_HEAD(, IntelIOMMUNotifierNode) notifiers_list;
 
 /* interrupt remapping */
 bool intr_enabled;  /* Whether guest enabled IR */
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index f7dec82066..02f047c8e3 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -806,7 +806,8 @@ next:
  * @private: private data for the hook function
  */
 static int vtd_page_walk(VTDContextEntry *ce, uint64_t start, uint64_t end,
- vtd_page_walk_hook hook_fn, void *private)
+ vtd_page_walk_hook hook_fn, void *private,
+ bool notify_unmap)
 {
 dma_addr_t addr = vtd_get_slpt_base_from_context(ce);
 uint32_t level = vtd_get_level_from_context_entry(ce);
@@ -821,7 +822,7 @@ static int vtd_page_walk(VTDContextEntry *ce, uint64_t 
start, uint64_t end,
 }
 
 return vtd_page_walk_level(addr, start, end, hook_fn, private,
-   level, true, true, false);
+   level, true, true, notify_unmap);
 }
 
 /* Map a device to its corresponding domain (context-entry) */
@@ -1038,6 +1039,15 @@ static void 
vtd_interrupt_remap_table_setup(IntelIOMMUState *s)
 s->intr_root, s->intr_size);
 }
 
+static void vtd_iommu_replay_all(IntelIOMMUState *s)
+{
+IntelIOMMUNotifierNode *node;
+
+QLIST_FOREACH(node, &s->notifiers_list, next) {
+memory_region_iommu_replay_all(&node->vtd_as->iommu);
+}
+}
+
 static void vtd_context_global_invalidate(IntelIOMMUState *s)
 {
 trace_vtd_inv_desc_cc_global();
@@ -1045,6 +1055,14 @@ static void 
vtd_context_global_invalidate(IntelIOMMUState *s)
 if (s->context_cache_gen == VTD_CONTEXT_CACHE_GEN_MAX) {
 vtd_reset_context_cache(s);
 }
+/*
+ * From VT-d spec 6.5.2.1, a global context entry invalidation
+ * should be followed by a IOTLB global invalidation, so we should
+ * be safe even without this. Hoewever, let's replay the region 

[Qemu-devel] [PULL 05/15] memory: add MemoryRegionIOMMUOps.replay() callback

2017-04-20 Thread Eduardo Habkost
From: Peter Xu 

Originally we have one memory_region_iommu_replay() function, which is
the default behavior to replay the translations of the whole IOMMU
region. However, on some platform like x86, we may want our own replay
logic for IOMMU regions. This patch adds one more hook for IOMMUOps for
the callback, and it'll override the default if set.

Reviewed-by: David Gibson 
Reviewed-by: Eric Auger 
Reviewed-by: \"Michael S. Tsirkin\" 
Signed-off-by: Peter Xu 
Message-Id: <1491562755-23867-6-git-send-email-pet...@redhat.com>
Signed-off-by: Eduardo Habkost 
---
 include/exec/memory.h | 2 ++
 memory.c  | 6 ++
 2 files changed, 8 insertions(+)

diff --git a/include/exec/memory.h b/include/exec/memory.h
index 055b3a8b23..c0280b7064 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -191,6 +191,8 @@ struct MemoryRegionIOMMUOps {
 void (*notify_flag_changed)(MemoryRegion *iommu,
 IOMMUNotifierFlag old_flags,
 IOMMUNotifierFlag new_flags);
+/* Set this up to provide customized IOMMU replay function */
+void (*replay)(MemoryRegion *iommu, IOMMUNotifier *notifier);
 };
 
 typedef struct CoalescedMemoryRange CoalescedMemoryRange;
diff --git a/memory.c b/memory.c
index ded4bf13d6..b782d5bc5a 100644
--- a/memory.c
+++ b/memory.c
@@ -1626,6 +1626,12 @@ void memory_region_iommu_replay(MemoryRegion *mr, 
IOMMUNotifier *n,
 hwaddr addr, granularity;
 IOMMUTLBEntry iotlb;
 
+/* If the IOMMU has its own replay callback, override */
+if (mr->iommu_ops->replay) {
+mr->iommu_ops->replay(mr, n);
+return;
+}
+
 granularity = memory_region_iommu_get_min_page_size(mr);
 
 for (addr = 0; addr < memory_region_size(mr); addr += granularity) {
-- 
2.11.0.259.g40922b1




[Qemu-devel] [PULL 12/15] hostmem: introduce host_memory_backend_mr_inited()

2017-04-20 Thread Eduardo Habkost
From: Peter Xu 

We were checking this against memory region size of host memory
backend's mr field to see whether the mr has been inited. This is
efficient but less elegant. Let's make a helper for it to avoid
confusions, along with some notes.

Suggested-by: Peter Maydell 
Signed-off-by: Peter Xu 
Message-Id: <1489151370-15453-2-git-send-email-pet...@redhat.com>
Reviewed-by: Eduardo Habkost 
Signed-off-by: Eduardo Habkost 
---
 include/sysemu/hostmem.h | 1 +
 backends/hostmem.c   | 9 +
 2 files changed, 10 insertions(+)

diff --git a/include/sysemu/hostmem.h b/include/sysemu/hostmem.h
index ecae0cff19..ed6a437f4d 100644
--- a/include/sysemu/hostmem.h
+++ b/include/sysemu/hostmem.h
@@ -62,6 +62,7 @@ struct HostMemoryBackend {
 MemoryRegion mr;
 };
 
+bool host_memory_backend_mr_inited(HostMemoryBackend *backend);
 MemoryRegion *host_memory_backend_get_memory(HostMemoryBackend *backend,
  Error **errp);
 
diff --git a/backends/hostmem.c b/backends/hostmem.c
index 89feb9ed75..d8faab4bed 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -237,6 +237,15 @@ static void host_memory_backend_init(Object *obj)
 backend->prealloc = mem_prealloc;
 }
 
+bool host_memory_backend_mr_inited(HostMemoryBackend *backend)
+{
+/*
+ * NOTE: We forbid zero-length memory backend, so here zero means
+ * "we haven't inited the backend memory region yet".
+ */
+return memory_region_size(&backend->mr) != 0;
+}
+
 MemoryRegion *
 host_memory_backend_get_memory(HostMemoryBackend *backend, Error **errp)
 {
-- 
2.11.0.259.g40922b1




[Qemu-devel] [PULL 08/15] intel_iommu: allow dynamic switch of IOMMU region

2017-04-20 Thread Eduardo Habkost
From: Peter Xu 

This is preparation work to finally enabled dynamic switching ON/OFF for
VT-d protection. The old VT-d codes is using static IOMMU address space,
and that won't satisfy vfio-pci device listeners.

Let me explain.

vfio-pci devices depend on the memory region listener and IOMMU replay
mechanism to make sure the device mapping is coherent with the guest
even if there are domain switches. And there are two kinds of domain
switches:

  (1) switch from domain A -> B
  (2) switch from domain A -> no domain (e.g., turn DMAR off)

Case (1) is handled by the context entry invalidation handling by the
VT-d replay logic. What the replay function should do here is to replay
the existing page mappings in domain B.

However for case (2), we don't want to replay any domain mappings - we
just need the default GPA->HPA mappings (the address_space_memory
mapping). And this patch helps on case (2) to build up the mapping
automatically by leveraging the vfio-pci memory listeners.

Another important thing that this patch does is to seperate
IR (Interrupt Remapping) from DMAR (DMA Remapping). IR region should not
depend on the DMAR region (like before this patch). It should be a
standalone region, and it should be able to be activated without
DMAR (which is a common behavior of Linux kernel - by default it enables
IR while disabled DMAR).

Reviewed-by: Jason Wang 
Reviewed-by: David Gibson 
Reviewed-by: \"Michael S. Tsirkin\" 
Signed-off-by: Peter Xu 
Message-Id: <1491562755-23867-9-git-send-email-pet...@redhat.com>
Signed-off-by: Eduardo Habkost 
---
 include/hw/i386/intel_iommu.h |  2 ++
 hw/i386/intel_iommu.c | 81 ---
 hw/i386/trace-events  |  2 +-
 3 files changed, 79 insertions(+), 6 deletions(-)

diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h
index fe645aa93a..8f212a1198 100644
--- a/include/hw/i386/intel_iommu.h
+++ b/include/hw/i386/intel_iommu.h
@@ -83,6 +83,8 @@ struct VTDAddressSpace {
 uint8_t devfn;
 AddressSpace as;
 MemoryRegion iommu;
+MemoryRegion root;
+MemoryRegion sys_alias;
 MemoryRegion iommu_ir;  /* Interrupt region: 0xfeeX */
 IntelIOMMUState *iommu_state;
 VTDContextCacheEntry context_cache_entry;
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 7af4e22958..f7dec82066 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -1291,9 +1291,49 @@ static void vtd_handle_gcmd_sirtp(IntelIOMMUState *s)
 vtd_set_clear_mask_long(s, DMAR_GSTS_REG, 0, VTD_GSTS_IRTPS);
 }
 
+static void vtd_switch_address_space(VTDAddressSpace *as)
+{
+assert(as);
+
+trace_vtd_switch_address_space(pci_bus_num(as->bus),
+   VTD_PCI_SLOT(as->devfn),
+   VTD_PCI_FUNC(as->devfn),
+   as->iommu_state->dmar_enabled);
+
+/* Turn off first then on the other */
+if (as->iommu_state->dmar_enabled) {
+memory_region_set_enabled(&as->sys_alias, false);
+memory_region_set_enabled(&as->iommu, true);
+} else {
+memory_region_set_enabled(&as->iommu, false);
+memory_region_set_enabled(&as->sys_alias, true);
+}
+}
+
+static void vtd_switch_address_space_all(IntelIOMMUState *s)
+{
+GHashTableIter iter;
+VTDBus *vtd_bus;
+int i;
+
+g_hash_table_iter_init(&iter, s->vtd_as_by_busptr);
+while (g_hash_table_iter_next(&iter, NULL, (void **)&vtd_bus)) {
+for (i = 0; i < X86_IOMMU_PCI_DEVFN_MAX; i++) {
+if (!vtd_bus->dev_as[i]) {
+continue;
+}
+vtd_switch_address_space(vtd_bus->dev_as[i]);
+}
+}
+}
+
 /* Handle Translation Enable/Disable */
 static void vtd_handle_gcmd_te(IntelIOMMUState *s, bool en)
 {
+if (s->dmar_enabled == en) {
+return;
+}
+
 VTD_DPRINTF(CSR, "Translation Enable %s", (en ? "on" : "off"));
 
 if (en) {
@@ -1308,6 +1348,8 @@ static void vtd_handle_gcmd_te(IntelIOMMUState *s, bool 
en)
 /* Ok - report back to driver */
 vtd_set_clear_mask_long(s, DMAR_GSTS_REG, VTD_GSTS_TES, 0);
 }
+
+vtd_switch_address_space_all(s);
 }
 
 /* Handle Interrupt Remap Enable/Disable */
@@ -2529,15 +2571,44 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, 
PCIBus *bus, int devfn)
 vtd_dev_as->devfn = (uint8_t)devfn;
 vtd_dev_as->iommu_state = s;
 vtd_dev_as->context_cache_entry.context_cache_gen = 0;
+
+/*
+ * Memory region relationships looks like (Address range shows
+ * only lower 32 bits to make it short in length...):
+ *
+ * |-+---+--|
+ * | Name| Address range | Priority |
+ * |-+---+--+
+ * | vtd_root| - |0 |
+ * |  intel_iommu| - |1 |
+

[Qemu-devel] [PULL 07/15] intel_iommu: provide its own replay() callback

2017-04-20 Thread Eduardo Habkost
From: Peter Xu 

The default replay() don't work for VT-d since vt-d will have a huge
default memory region which covers address range 0-(2^64-1). This will
normally consumes a lot of time (which looks like a dead loop).

The solution is simple - we don't walk over all the regions. Instead, we
jump over the regions when we found that the page directories are empty.
It'll greatly reduce the time to walk the whole region.

To achieve this, we provided a page walk helper to do that, invoking
corresponding hook function when we found an page we are interested in.
vtd_page_walk_level() is the core logic for the page walking. It's
interface is designed to suite further use case, e.g., to invalidate a
range of addresses.

Reviewed-by: Jason Wang 
Reviewed-by: David Gibson 
Reviewed-by: \"Michael S. Tsirkin\" 
Signed-off-by: Peter Xu 
Message-Id: <1491562755-23867-8-git-send-email-pet...@redhat.com>
Signed-off-by: Eduardo Habkost 
---
 include/exec/memory.h |   2 +
 hw/i386/intel_iommu.c | 182 --
 hw/i386/trace-events  |   7 ++
 3 files changed, 186 insertions(+), 5 deletions(-)

diff --git a/include/exec/memory.h b/include/exec/memory.h
index c0280b7064..c4fc94d504 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -55,6 +55,8 @@ typedef enum {
 IOMMU_RW   = 3,
 } IOMMUAccessFlags;
 
+#define IOMMU_ACCESS_FLAG(r, w) (((r) ? IOMMU_RO : 0) | ((w) ? IOMMU_WO : 0))
+
 struct IOMMUTLBEntry {
 AddressSpace*target_as;
 hwaddr   iova;
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 2412df4182..7af4e22958 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -595,6 +595,22 @@ static inline uint32_t 
vtd_get_agaw_from_context_entry(VTDContextEntry *ce)
 return 30 + (ce->hi & VTD_CONTEXT_ENTRY_AW) * 9;
 }
 
+static inline uint64_t vtd_iova_limit(VTDContextEntry *ce)
+{
+uint32_t ce_agaw = vtd_get_agaw_from_context_entry(ce);
+return 1ULL << MIN(ce_agaw, VTD_MGAW);
+}
+
+/* Return true if IOVA passes range check, otherwise false. */
+static inline bool vtd_iova_range_check(uint64_t iova, VTDContextEntry *ce)
+{
+/*
+ * Check if @iova is above 2^X-1, where X is the minimum of MGAW
+ * in CAP_REG and AW in context-entry.
+ */
+return !(iova & ~(vtd_iova_limit(ce) - 1));
+}
+
 static const uint64_t vtd_paging_entry_rsvd_field[] = {
 [0] = ~0ULL,
 /* For not large page */
@@ -630,13 +646,9 @@ static int vtd_iova_to_slpte(VTDContextEntry *ce, uint64_t 
iova, bool is_write,
 uint32_t level = vtd_get_level_from_context_entry(ce);
 uint32_t offset;
 uint64_t slpte;
-uint32_t ce_agaw = vtd_get_agaw_from_context_entry(ce);
 uint64_t access_right_check;
 
-/* Check if @iova is above 2^X-1, where X is the minimum of MGAW
- * in CAP_REG and AW in context-entry.
- */
-if (iova & ~((1ULL << MIN(ce_agaw, VTD_MGAW)) - 1)) {
+if (!vtd_iova_range_check(iova, ce)) {
 VTD_DPRINTF(GENERAL, "error: iova 0x%"PRIx64 " exceeds limits", iova);
 return -VTD_FR_ADDR_BEYOND_MGAW;
 }
@@ -684,6 +696,134 @@ static int vtd_iova_to_slpte(VTDContextEntry *ce, 
uint64_t iova, bool is_write,
 }
 }
 
+typedef int (*vtd_page_walk_hook)(IOMMUTLBEntry *entry, void *private);
+
+/**
+ * vtd_page_walk_level - walk over specific level for IOVA range
+ *
+ * @addr: base GPA addr to start the walk
+ * @start: IOVA range start address
+ * @end: IOVA range end address (start <= addr < end)
+ * @hook_fn: hook func to be called when detected page
+ * @private: private data to be passed into hook func
+ * @read: whether parent level has read permission
+ * @write: whether parent level has write permission
+ * @notify_unmap: whether we should notify invalid entries
+ */
+static int vtd_page_walk_level(dma_addr_t addr, uint64_t start,
+   uint64_t end, vtd_page_walk_hook hook_fn,
+   void *private, uint32_t level,
+   bool read, bool write, bool notify_unmap)
+{
+bool read_cur, write_cur, entry_valid;
+uint32_t offset;
+uint64_t slpte;
+uint64_t subpage_size, subpage_mask;
+IOMMUTLBEntry entry;
+uint64_t iova = start;
+uint64_t iova_next;
+int ret = 0;
+
+trace_vtd_page_walk_level(addr, level, start, end);
+
+subpage_size = 1ULL << vtd_slpt_level_shift(level);
+subpage_mask = vtd_slpt_level_page_mask(level);
+
+while (iova < end) {
+iova_next = (iova & subpage_mask) + subpage_size;
+
+offset = vtd_iova_level_offset(iova, level);
+slpte = vtd_get_slpte(addr, offset);
+
+if (slpte == (uint64_t)-1) {
+trace_vtd_page_walk_skip_read(iova, iova_next);
+goto next;
+}
+
+if (vtd_slpte_nonzero_rsvd(slpte, level)) {
+trace_vtd_page_walk_skip_reserve(iova, iova_next);
+goto next;
+}
+
+/* Permissions are stacked with parents' */
+   

[Qemu-devel] [PULL 02/15] memory: provide IOMMU_NOTIFIER_FOREACH macro

2017-04-20 Thread Eduardo Habkost
From: Peter Xu 

A new macro is provided to iterate all the IOMMU notifiers hooked
under specific IOMMU memory region.

Reviewed-by: David Gibson 
Reviewed-by: Eric Auger 
Reviewed-by: \"Michael S. Tsirkin\" 
Signed-off-by: Peter Xu 
Message-Id: <1491562755-23867-3-git-send-email-pet...@redhat.com>
Signed-off-by: Eduardo Habkost 
---
 include/exec/memory.h | 3 +++
 memory.c  | 4 ++--
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/include/exec/memory.h b/include/exec/memory.h
index 0840c89489..07e43daf20 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -239,6 +239,9 @@ struct MemoryRegion {
 IOMMUNotifierFlag iommu_notify_flags;
 };
 
+#define IOMMU_NOTIFIER_FOREACH(n, mr) \
+QLIST_FOREACH((n), &(mr)->iommu_notify, node)
+
 /**
  * MemoryListener: callbacks structure for updates to the physical memory map
  *
diff --git a/memory.c b/memory.c
index 75ac595073..7496b3d3d5 100644
--- a/memory.c
+++ b/memory.c
@@ -1583,7 +1583,7 @@ static void 
memory_region_update_iommu_notify_flags(MemoryRegion *mr)
 IOMMUNotifierFlag flags = IOMMU_NOTIFIER_NONE;
 IOMMUNotifier *iommu_notifier;
 
-QLIST_FOREACH(iommu_notifier, &mr->iommu_notify, node) {
+IOMMU_NOTIFIER_FOREACH(iommu_notifier, mr) {
 flags |= iommu_notifier->notifier_flags;
 }
 
@@ -1667,7 +1667,7 @@ void memory_region_notify_iommu(MemoryRegion *mr,
 request_flags = IOMMU_NOTIFIER_UNMAP;
 }
 
-QLIST_FOREACH(iommu_notifier, &mr->iommu_notify, node) {
+IOMMU_NOTIFIER_FOREACH(iommu_notifier, mr) {
 /*
  * Skip the notification if the notification does not overlap
  * with registered range.
-- 
2.11.0.259.g40922b1




[Qemu-devel] [PULL 03/15] memory: provide iommu_replay_all()

2017-04-20 Thread Eduardo Habkost
From: Peter Xu 

This is an "global" version of existing memory_region_iommu_replay() -
we announce the translations to all the registered notifiers, instead of
a specific one.

Reviewed-by: David Gibson 
Reviewed-by: \"Michael S. Tsirkin\" 
Signed-off-by: Peter Xu 
Message-Id: <1491562755-23867-4-git-send-email-pet...@redhat.com>
Signed-off-by: Eduardo Habkost 
---
 include/exec/memory.h | 8 
 memory.c  | 9 +
 2 files changed, 17 insertions(+)

diff --git a/include/exec/memory.h b/include/exec/memory.h
index 07e43daf20..fb7dff3405 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -713,6 +713,14 @@ void memory_region_iommu_replay(MemoryRegion *mr, 
IOMMUNotifier *n,
 bool is_write);
 
 /**
+ * memory_region_iommu_replay_all: replay existing IOMMU translations
+ * to all the notifiers registered.
+ *
+ * @mr: the memory region to observe
+ */
+void memory_region_iommu_replay_all(MemoryRegion *mr);
+
+/**
  * memory_region_unregister_iommu_notifier: unregister a notifier for
  * changes to IOMMU translation entries.
  *
diff --git a/memory.c b/memory.c
index 7496b3d3d5..b4ed67b27a 100644
--- a/memory.c
+++ b/memory.c
@@ -1642,6 +1642,15 @@ void memory_region_iommu_replay(MemoryRegion *mr, 
IOMMUNotifier *n,
 }
 }
 
+void memory_region_iommu_replay_all(MemoryRegion *mr)
+{
+IOMMUNotifier *notifier;
+
+IOMMU_NOTIFIER_FOREACH(notifier, mr) {
+memory_region_iommu_replay(mr, notifier, false);
+}
+}
+
 void memory_region_unregister_iommu_notifier(MemoryRegion *mr,
  IOMMUNotifier *n)
 {
-- 
2.11.0.259.g40922b1




[Qemu-devel] [PULL 01/15] memory: add section range info for IOMMU notifier

2017-04-20 Thread Eduardo Habkost
From: Peter Xu 

In this patch, IOMMUNotifier.{start|end} are introduced to store section
information for a specific notifier. When notification occurs, we not
only check the notification type (MAP|UNMAP), but also check whether the
notified iova range overlaps with the range of specific IOMMU notifier,
and skip those notifiers if not in the listened range.

When removing an region, we need to make sure we removed the correct
VFIOGuestIOMMU by checking the IOMMUNotifier.start address as well.

This patch is solving the problem that vfio-pci devices receive
duplicated UNMAP notification on x86 platform when vIOMMU is there. The
issue is that x86 IOMMU has a (0, 2^64-1) IOMMU region, which is
splitted by the (0xfee0, 0xfeef) IRQ region. AFAIK
this (splitted IOMMU region) is only happening on x86.

This patch also helps vhost to leverage the new interface as well, so
that vhost won't get duplicated cache flushes. In that sense, it's an
slight performance improvement.

Suggested-by: David Gibson 
Reviewed-by: Eric Auger 
Reviewed-by: Michael S. Tsirkin 
Acked-by: Alex Williamson 
Signed-off-by: Peter Xu 
Message-Id: <1491562755-23867-2-git-send-email-pet...@redhat.com>
[ehabkost: included extra vhost_iommu_region_del() change from Peter Xu]
Signed-off-by: Eduardo Habkost 
---
 include/exec/memory.h | 19 ++-
 hw/vfio/common.c  | 12 +---
 hw/virtio/vhost.c | 13 ++---
 memory.c  |  9 +
 4 files changed, 46 insertions(+), 7 deletions(-)

diff --git a/include/exec/memory.h b/include/exec/memory.h
index f20b191793..0840c89489 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -77,13 +77,30 @@ typedef enum {
 
 #define IOMMU_NOTIFIER_ALL (IOMMU_NOTIFIER_MAP | IOMMU_NOTIFIER_UNMAP)
 
+struct IOMMUNotifier;
+typedef void (*IOMMUNotify)(struct IOMMUNotifier *notifier,
+IOMMUTLBEntry *data);
+
 struct IOMMUNotifier {
-void (*notify)(struct IOMMUNotifier *notifier, IOMMUTLBEntry *data);
+IOMMUNotify notify;
 IOMMUNotifierFlag notifier_flags;
+/* Notify for address space range start <= addr <= end */
+hwaddr start;
+hwaddr end;
 QLIST_ENTRY(IOMMUNotifier) node;
 };
 typedef struct IOMMUNotifier IOMMUNotifier;
 
+static inline void iommu_notifier_init(IOMMUNotifier *n, IOMMUNotify fn,
+   IOMMUNotifierFlag flags,
+   hwaddr start, hwaddr end)
+{
+n->notify = fn;
+n->notifier_flags = flags;
+n->start = start;
+n->end = end;
+}
+
 /* New-style MMIO accessors can indicate that the transaction failed.
  * A zero (MEMTX_OK) response means success; anything else is a failure
  * of some kind. The memory subsystem will bitwise-OR together results
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index f3ba9b9007..6b33b9f55d 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -478,8 +478,13 @@ static void vfio_listener_region_add(MemoryListener 
*listener,
 giommu->iommu_offset = section->offset_within_address_space -
section->offset_within_region;
 giommu->container = container;
-giommu->n.notify = vfio_iommu_map_notify;
-giommu->n.notifier_flags = IOMMU_NOTIFIER_ALL;
+llend = int128_add(int128_make64(section->offset_within_region),
+   section->size);
+llend = int128_sub(llend, int128_one());
+iommu_notifier_init(&giommu->n, vfio_iommu_map_notify,
+IOMMU_NOTIFIER_ALL,
+section->offset_within_region,
+int128_get64(llend));
 QLIST_INSERT_HEAD(&container->giommu_list, giommu, giommu_next);
 
 memory_region_register_iommu_notifier(giommu->iommu, &giommu->n);
@@ -550,7 +555,8 @@ static void vfio_listener_region_del(MemoryListener 
*listener,
 VFIOGuestIOMMU *giommu;
 
 QLIST_FOREACH(giommu, &container->giommu_list, giommu_next) {
-if (giommu->iommu == section->mr) {
+if (giommu->iommu == section->mr &&
+giommu->n.start == section->offset_within_region) {
 memory_region_unregister_iommu_notifier(giommu->iommu,
 &giommu->n);
 QLIST_REMOVE(giommu, giommu_next);
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 613494dcc2..0001e60b77 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -736,14 +736,20 @@ static void vhost_iommu_region_add(MemoryListener 
*listener,
 struct vhost_dev *dev = container_of(listener, struct vhost_dev,
  iommu_listener);
 struct vhost_iommu *iommu;
+Int128 end;
 
 if (!memory_region_is_iommu(section->mr)) {
 return;
 }
 
 iommu = g_malloc0(sizeof(*iommu));
-iommu->n.notify = vhost_iommu_unmap_notify;
-iommu->n.notifier_flags = IOMMU_NOTIFIER_UNMA

[Qemu-devel] [PULL 04/15] memory: introduce memory_region_notify_one()

2017-04-20 Thread Eduardo Habkost
From: Peter Xu 

Generalizing the notify logic in memory_region_notify_iommu() into a
single function. This can be further used in customized replay()
functions for IOMMUs.

Reviewed-by: David Gibson 
Reviewed-by: Eric Auger 
Reviewed-by: \"Michael S. Tsirkin\" 
Signed-off-by: Peter Xu 
Message-Id: <1491562755-23867-5-git-send-email-pet...@redhat.com>
Signed-off-by: Eduardo Habkost 
---
 include/exec/memory.h | 15 +++
 memory.c  | 40 
 2 files changed, 39 insertions(+), 16 deletions(-)

diff --git a/include/exec/memory.h b/include/exec/memory.h
index fb7dff3405..055b3a8b23 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -688,6 +688,21 @@ void memory_region_notify_iommu(MemoryRegion *mr,
 IOMMUTLBEntry entry);
 
 /**
+ * memory_region_notify_one: notify a change in an IOMMU translation
+ *   entry to a single notifier
+ *
+ * This works just like memory_region_notify_iommu(), but it only
+ * notifies a specific notifier, not all of them.
+ *
+ * @notifier: the notifier to be notified
+ * @entry: the new entry in the IOMMU translation table.  The entry
+ * replaces all old entries for the same virtual I/O address range.
+ * Deleted entries have .@perm == 0.
+ */
+void memory_region_notify_one(IOMMUNotifier *notifier,
+  IOMMUTLBEntry *entry);
+
+/**
  * memory_region_register_iommu_notifier: register a notifier for changes to
  * IOMMU translation entries.
  *
diff --git a/memory.c b/memory.c
index b4ed67b27a..ded4bf13d6 100644
--- a/memory.c
+++ b/memory.c
@@ -1662,32 +1662,40 @@ void 
memory_region_unregister_iommu_notifier(MemoryRegion *mr,
 memory_region_update_iommu_notify_flags(mr);
 }
 
-void memory_region_notify_iommu(MemoryRegion *mr,
-IOMMUTLBEntry entry)
+void memory_region_notify_one(IOMMUNotifier *notifier,
+  IOMMUTLBEntry *entry)
 {
-IOMMUNotifier *iommu_notifier;
 IOMMUNotifierFlag request_flags;
 
-assert(memory_region_is_iommu(mr));
+/*
+ * Skip the notification if the notification does not overlap
+ * with registered range.
+ */
+if (notifier->start > entry->iova + entry->addr_mask + 1 ||
+notifier->end < entry->iova) {
+return;
+}
 
-if (entry.perm & IOMMU_RW) {
+if (entry->perm & IOMMU_RW) {
 request_flags = IOMMU_NOTIFIER_MAP;
 } else {
 request_flags = IOMMU_NOTIFIER_UNMAP;
 }
 
+if (notifier->notifier_flags & request_flags) {
+notifier->notify(notifier, entry);
+}
+}
+
+void memory_region_notify_iommu(MemoryRegion *mr,
+IOMMUTLBEntry entry)
+{
+IOMMUNotifier *iommu_notifier;
+
+assert(memory_region_is_iommu(mr));
+
 IOMMU_NOTIFIER_FOREACH(iommu_notifier, mr) {
-/*
- * Skip the notification if the notification does not overlap
- * with registered range.
- */
-if (iommu_notifier->start > entry.iova + entry.addr_mask + 1 ||
-iommu_notifier->end < entry.iova) {
-continue;
-}
-if (iommu_notifier->notifier_flags & request_flags) {
-iommu_notifier->notify(iommu_notifier, &entry);
-}
+memory_region_notify_one(iommu_notifier, &entry);
 }
 }
 
-- 
2.11.0.259.g40922b1




[Qemu-devel] [PULL 06/15] intel_iommu: use the correct memory region for device IOTLB notification

2017-04-20 Thread Eduardo Habkost
From: Jason Wang 

We have a specific memory region for DMAR now, so it's wrong to
trigger the notifier with the root region.

Cc: Michael S. Tsirkin 
Cc: Paolo Bonzini 
Cc: Richard Henderson 
Cc: Eduardo Habkost 
Signed-off-by: Jason Wang 
Reviewed-by: Peter Xu 
Reviewed-by: \"Michael S. Tsirkin\" 
Signed-off-by: Peter Xu 
Message-Id: <1491562755-23867-7-git-send-email-pet...@redhat.com>
Signed-off-by: Eduardo Habkost 
---
 hw/i386/intel_iommu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 22d8226e43..2412df4182 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -1457,7 +1457,7 @@ static bool vtd_process_device_iotlb_desc(IntelIOMMUState 
*s,
 entry.iova = addr;
 entry.perm = IOMMU_NONE;
 entry.translated_addr = 0;
-memory_region_notify_iommu(entry.target_as->root, entry);
+memory_region_notify_iommu(&vtd_dev_as->iommu, entry);
 
 done:
 return true;
-- 
2.11.0.259.g40922b1




[Qemu-devel] [PULL 00/15] Machine queue for 2.10

2017-04-20 Thread Eduardo Habkost
This includes a few IOMMU fixes because Michael is away this
week.

The following changes since commit da92ada855036c55bd08b0b0c64c7551d56f3586:

  Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20170420' 
into staging (2017-04-20 17:41:34 +0100)

are available in the git repository at:

  git://github.com/ehabkost/qemu.git tags/machine-pull-request

for you to fetch changes up to be9721f400f7e5395bb2a257c291557df8f3f833:

  qdev: Constify local variable returned by blk_bs (2017-04-20 15:22:41 -0300)


Machine queue for 2.10



Eduardo Habkost (1):
  qdev: Make "hotplugged" property read-only

Jason Wang (1):
  intel_iommu: use the correct memory region for device IOTLB
notification

Krzysztof Kozlowski (2):
  qdev: Constify value passed to qdev_prop_set_macaddr
  qdev: Constify local variable returned by blk_bs

Peter Xu (10):
  memory: add section range info for IOMMU notifier
  memory: provide IOMMU_NOTIFIER_FOREACH macro
  memory: provide iommu_replay_all()
  memory: introduce memory_region_notify_one()
  memory: add MemoryRegionIOMMUOps.replay() callback
  intel_iommu: provide its own replay() callback
  intel_iommu: allow dynamic switch of IOMMU region
  intel_iommu: enable remote IOTLB
  hostmem: introduce host_memory_backend_mr_inited()
  hostmem: use host_memory_backend_mr_inited() where proper

Thomas Huth (1):
  hw/core/null-machine: Print error message when using the -kernel
parameter

 hw/i386/intel_iommu_internal.h   |   1 +
 include/exec/memory.h|  49 -
 include/hw/i386/intel_iommu.h|  10 +
 include/hw/qdev-properties.h |   3 +-
 include/sysemu/hostmem.h |   1 +
 backends/hostmem-file.c  |   6 +-
 backends/hostmem.c   |  19 +-
 hw/core/null-machine.c   |   6 +
 hw/core/qdev-properties-system.c |   2 +-
 hw/core/qdev-properties.c|   3 +-
 hw/core/qdev.c   |   9 +-
 hw/i386/intel_iommu.c| 442 +--
 hw/vfio/common.c |  12 +-
 hw/virtio/vhost.c|  13 +-
 memory.c |  52 -
 hw/i386/trace-events |  10 +-
 16 files changed, 584 insertions(+), 54 deletions(-)

-- 
2.11.0.259.g40922b1




Re: [Qemu-devel] [PATCH] tcg/i386: Do not display HT warning for TCG

2017-04-20 Thread Eduardo Habkost
On Thu, Apr 20, 2017 at 12:14:18AM -0400, Pranith Kumar wrote:
> On Wed, Apr 19, 2017 at 10:26 PM, Eduardo Habkost  wrote:
> > On Wed, Apr 19, 2017 at 06:03:01PM -0400, Pranith Kumar wrote:
> >> On Wed, Apr 19, 2017 at 5:33 PM, Eduardo Habkost  
> >> wrote:
> >> > On Wed, Apr 19, 2017 at 05:25:23PM -0400, Pranith Kumar wrote:
> >> >> On Wed, Apr 19, 2017 at 4:57 PM, Eduardo Habkost  
> >> >> wrote:
> >> >> > On Wed, Apr 19, 2017 at 04:16:53PM -0400, Pranith Kumar wrote:
> >> >> >> On Wed, Apr 19, 2017 at 4:13 PM, Eduardo Habkost 
> >> >> >>  wrote:
> >> >> >> > On Wed, Apr 19, 2017 at 04:00:49PM -0400, Pranith Kumar wrote:
> >> >> >> >> On Wed, Apr 19, 2017 at 3:54 PM, Pranith Kumar 
> >> >> >> >>  wrote:
> >> >> >> >> > When we enable hyperthreading (using threads smp argument), we 
> >> >> >> >> > warn
> >> >> >> >> > the user if the cpu is an AMD cpu. This does not make sense on 
> >> >> >> >> > TCG and
> >> >> >> >> > is also obsolete now that AMD Ryzen support hyperthreading.
> >> >> >> >> >
> >> >> >> >> > Fix this by adding CPUID_HT bit to the TCG features and 
> >> >> >> >> > explicitly
> >> >> >> >> > checking this bit in the cpuid.
> >> >> >> >> >
> >> >> >> >> > Signed-off-by: Pranith Kumar 
> >> >> >> >> > ---
> >> >> >> >> >  target/i386/cpu.c | 10 +-
> >> >> >> >> >  1 file changed, 5 insertions(+), 5 deletions(-)
> >> >> >> >> >
> >> >> >> >> > diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> >> >> >> >> > index 13c0985f11..f34bb5ead7 100644
> >> >> >> >> > --- a/target/i386/cpu.c
> >> >> >> >> > +++ b/target/i386/cpu.c
> >> >> >> >> > @@ -202,12 +202,12 @@ static void x86_cpu_vendor_words2str(char 
> >> >> >> >> > *dst, uint32_t vendor1,
> >> >> >> >> >  #define TCG_FEATURES (CPUID_FP87 | CPUID_PSE | CPUID_TSC | 
> >> >> >> >> > CPUID_MSR | \
> >> >> >> >> >CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC | 
> >> >> >> >> > CPUID_SEP | \
> >> >> >> >> >CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | 
> >> >> >> >> > CPUID_PAT | \
> >> >> >> >> > -  CPUID_PSE36 | CPUID_CLFLUSH | CPUID_ACPI | CPUID_MMX 
> >> >> >> >> > | \
> >> >> >> >> > +  CPUID_PSE36 | CPUID_CLFLUSH | CPUID_ACPI | CPUID_MMX 
> >> >> >> >> > | CPUID_HT | \
> >> >> >> >> >CPUID_FXSR | CPUID_SSE | CPUID_SSE2 | CPUID_SS | 
> >> >> >> >> > CPUID_DE)
> >> >> >> >> >/* partly implemented:
> >> >> >> >> >CPUID_MTRR, CPUID_MCA, CPUID_CLFLUSH (needed for 
> >> >> >> >> > Win64) */
> >> >> >> >> >/* missing:
> >> >> >> >> > -  CPUID_VME, CPUID_DTS, CPUID_SS, CPUID_HT, CPUID_TM, 
> >> >> >> >> > CPUID_PBE */
> >> >> >> >> > +  CPUID_VME, CPUID_DTS, CPUID_SS, CPUID_TM, CPUID_PBE 
> >> >> >> >> > */
> >> >> >> >> >  #define TCG_EXT_FEATURES (CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ 
> >> >> >> >> > | \
> >> >> >> >> >CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 | CPUID_EXT_CX16 
> >> >> >> >> > | \
> >> >> >> >> >CPUID_EXT_SSE41 | CPUID_EXT_SSE42 | CPUID_EXT_POPCNT 
> >> >> >> >> > | \
> >> >> >> >> > @@ -3643,7 +3643,7 @@ static void x86_cpu_realizefn(DeviceState 
> >> >> >> >> > *dev, Error **errp)
> >> >> >> >> >
> >> >> >> >> >  qemu_init_vcpu(cs);
> >> >> >> >> >
> >> >> >> >> > -/* Only Intel CPUs support hyperthreading. Even though 
> >> >> >> >> > QEMU fixes this
> >> >> >> >> > +/* Only some CPUs support hyperthreading. Even though QEMU 
> >> >> >> >> > fixes this
> >> >> >> >> >   * issue by adjusting CPUID__0001_EBX and 
> >> >> >> >> > CPUID_8000_0008_ECX
> >> >> >> >> >   * based on inputs (sockets,cores,threads), it is still 
> >> >> >> >> > better to gives
> >> >> >> >> >   * users a warning.
> >> >> >> >> > @@ -3651,8 +3651,8 @@ static void x86_cpu_realizefn(DeviceState 
> >> >> >> >> > *dev, Error **errp)
> >> >> >> >> >   * NOTE: the following code has to follow 
> >> >> >> >> > qemu_init_vcpu(). Otherwise
> >> >> >> >> >   * cs->nr_threads hasn't be populated yet and the checking 
> >> >> >> >> > is incorrect.
> >> >> >> >> >   */
> >> >> >> >> > -if (!IS_INTEL_CPU(env) && cs->nr_threads > 1 && 
> >> >> >> >> > !ht_warned) {
> >> >> >> >> > -error_report("AMD CPU doesn't support hyperthreading. 
> >> >> >> >> > Please configure"
> >> >> >> >> > +if ((env->features[FEAT_1_EDX] & CPUID_HT) && 
> >> >> >> >> > (cs->nr_threads > 1) && !ht_warned) {
> >> >> >> >>
> >> >> >> >> I missed a '!' here. We need to warn if CPUID_HT is not set. But 
> >> >> >> >> I see
> >> >> >> >> that it is not being set even on HT enabled processors (i7-3770). 
> >> >> >> >> How
> >> >> >> >> do I test for it?
> >> >> >> >
> >> >> >> > CPUID_HT is automatically set on the CPU if
> >> >> >> > (nr_threads * nr_cores) > 1. See the "case 1:" block in
> >> >> >> > cpu_x86_cpuid().
> >> >> >> >
> >> >> >> > AFAIK, the point of the warning is to let the user know that the
> >> >> >> > guest OS is likely to ignore thread topology information if CPUID
> >> >> >> > vendor i

Re: [Qemu-devel] [PATCH v2] event: Add source information to SHUTDOWN

2017-04-20 Thread Eric Blake
On 04/20/2017 11:12 AM, Markus Armbruster wrote:

>>> Well technically /usr/sbin/halt just terminates all processes / kernel and
>>> halts CPUs, but the virtual machine is still active (and a 'reset' in the
>>> monitor can start it again. /usr/sbin/poweroff is what actually does the
>>> ACPI poweroff to trigger QEMU to exit[1]
>>
>> I'm thinking of this wording:
>>
>> triggered by a guest request (such as the guest running
>> /usr/sbin/poweroff to trigger an ACPI shutdown or machine halt instruction)
> 
> A quick glance at the patch suggests the instructions in question are
> typically writes to some device register.  I wouldn't call them "halt
> instructions", in particular since there's the x86 "hlt" instruction
> that does something else.

Then maybe: a guest request (such as the guest running
/usr/sbin/poweroff to trigger an ACPI or other hardware-specific
shutdown sequence)

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] QEMU build breakage on ARM against Xen 4.9 caused by libxendevicemodel

2017-04-20 Thread Stefano Stabellini
On Thu, 20 Apr 2017, Paul Durrant wrote:
> > -Original Message-
> > From: Stefano Stabellini [mailto:sstabell...@kernel.org]
> > Sent: 20 April 2017 00:02
> > To: Paul Durrant 
> > Cc: 'Stefano Stabellini' ; qemu-devel@nongnu.org;
> > Anthony Perard ; Wei Liu
> > ; jgr...@suse.com; julien.gr...@arm.com; xen-
> > de...@lists.xenproject.org
> > Subject: RE: QEMU build breakage on ARM against Xen 4.9 caused by
> > libxendevicemodel
> > 
> > On Wed, 19 Apr 2017, Paul Durrant wrote:
> > > > -Original Message-
> > > > From: Stefano Stabellini [mailto:sstabell...@kernel.org]
> > > > Sent: 18 April 2017 18:41
> > > > To: Paul Durrant 
> > > > Cc: 'Stefano Stabellini' ; qemu-
> > de...@nongnu.org;
> > > > Anthony Perard ; Wei Liu
> > > > ; jgr...@suse.com; julien.gr...@arm.com; xen-
> > > > de...@lists.xenproject.org
> > > > Subject: RE: QEMU build breakage on ARM against Xen 4.9 caused by
> > > > libxendevicemodel
> > > >
> > > > On Tue, 18 Apr 2017, Paul Durrant wrote:
> > > > > > -Original Message-
> > > > > > From: Stefano Stabellini [mailto:sstabell...@kernel.org]
> > > > > > Sent: 15 April 2017 01:40
> > > > > > To: Stefano Stabellini 
> > > > > > Cc: Paul Durrant ; qemu-
> > de...@nongnu.org;
> > > > > > Anthony Perard ; Wei Liu
> > > > > > ; jgr...@suse.com; julien.gr...@arm.com; xen-
> > > > > > de...@lists.xenproject.org
> > > > > > Subject: Re: QEMU build breakage on ARM against Xen 4.9 caused by
> > > > > > libxendevicemodel
> > > > > >
> > > > > > On Fri, 14 Apr 2017, Stefano Stabellini wrote:
> > > > > > > Hi Paul,
> > > > > > >
> > > > > > > The following commit in my qemu "next" branch breaks the build on
> > > > arm
> > > > > > > and arm64:
> > > > > > >
> > > > > > > commit 670271647ad15e9d937ced7a72c892349c709216
> > > > > > > Author: Paul Durrant 
> > > > > > > Date:   Tue Mar 7 10:55:34 2017 +
> > > > > > >
> > > > > > > xen: use libxendevicemodel when available
> > > > > > >
> > > > > > > See the appended build log. Sorry for not realizing it sooner.
> > > > > >
> > > > > > As I imagined, this bug is easy to solve. It is reproducible on x86 
> > > > > > too,
> > > > > > if you pass -DXC_WANT_COMPAT_DEVICEMODEL_API=1 to configure
> > > > and
> > > > > > forcefully disable Xen 4.9 detection in the configure script.
> > > > > >
> > > > > > If QEMU detects xen_ctrl_version = 480, the build will fail against 
> > > > > > Xen
> > > > > > 4.9, even when -DXC_WANT_COMPAT_DEVICEMODEL_API=1 is
> > > > specified.
> > > > > >
> > > > > > The appended patch solves the problem. However, Xen 4.9 detection
> > > > and
> > > > > > compilation remain broken.
> > > > >
> > > > > Ok, that fix looks fine to me.
> > > >
> > > > I merged this change into "use libxendevicemodel when available" in my
> > > > next branch.
> > > >
> > > > Are you going to take care of getting the QEMU build on ARM to work
> > > > against Xen 4.9 (properly detecting 4.9, without
> > > > -DXC_WANT_COMPAT_DEVICEMODEL_API=1)?
> > > >
> > >
> > > I can take a look once I get access to some h/w. Since the 4.9 detection
> > should merely be based upon the presence of libxendevicemodel, I can't
> > really imagine why ARM should behave any differently to x86.
> > 
> > I managed to find the time to do some debugging. You are right that is
> > not anything major. The bug is due to a missing -lxencall in the QEMU
> > configure script, I wonder why it works on x86.
> 
> Yes, that's weird. libxendevicemodel does depend on libxencall for the case 
> when the privcmd driver in dom0 does not support the new DM_OP ioctl, but 
> that dependency should be there regardless of architecture.
> 
> > 
> > diff --git a/configure b/configure
> > index 99d6cbc..363a126 100755
> > --- a/configure
> > +++ b/configure
> > @@ -2027,9 +2027,9 @@ int main(void) {
> >return 0;
> >  }
> >  EOF
> > -compile_prog "" "$xen_libs $xen_stable_libs -lxendevicemodel"
> > +compile_prog "" "$xen_libs $xen_stable_libs -lxendevicemodel -
> > lxencall"
> >then
> > -  xen_stable_libs="$xen_stable_libs -lxendevicemodel"
> > +  xen_stable_libs="$xen_stable_libs -lxendevicemodel -lxencall"
> >xen_ctrl_version=40900
> >xen=yes
> >  elif
> 
> I think xencall should be part of the base xen_stable_libs anyway.

Yes, you are right. However I noticed that -lxencall needs to come after
-lxendevicemodel. So, I'll have to move -lxendevicemodel before
$xen_stable_libs, see below. I'll merge this patch into "configure:
detect presence of libxendevicemodel", if that's OK.

diff --git a/configure b/configure
index 99d6cbc..3133ef8 100755
--- a/configure
+++ b/configure
@@ -1992,7 +1992,7 @@ if test "$xen" != "no" ; then
   else
 
 xen_libs="-lxenstore -lxenctrl -lxenguest"
-xen_stable_libs="-lxenforeignmemory -lxengnttab -lxenevtchn"
+xen_stable_libs="-lxencall -lxenforeignmemory -lxengnttab -lxenevtchn"
 
 # First we test whether Xen headers and libraries are available.
 # If no, we are done an

Re: [Qemu-devel] [PULL 00/24] target-arm queue

2017-04-20 Thread Peter Maydell
On 20 April 2017 at 17:40, Peter Maydell  wrote:
> First ARM pullreq of the 2.10 cycle...
>
> thanks
> -- PMM
>
> The following changes since commit 64c8ed97cceabac4fafe17fca8d88ef08183f439:
>
>   Open 2.10 development tree (2017-04-20 15:42:31 +0100)
>
> are available in the git repository at:
>
>   git://git.linaro.org/people/pmaydell/qemu-arm.git 
> tags/pull-target-arm-20170420
>
> for you to fetch changes up to f4e8e4edda875cab9df91dc4ae9767f7cb1f50aa:
>
>   arm: Remove workarounds for old M-profile exception return implementation 
> (2017-04-20 17:39:17 +0100)
>
> 
> target-arm queue:
>  * implement M profile exception return properly
>  * cadence GEM: fix multiqueue handling bugs
>  * pxa2xx.c: QOMify a device
>  * arm/kvm: Remove trailing newlines from error_report()
>  * stellaris: Don't hw_error() on bad register accesses
>  * Add assertion about FSC format for syndrome registers
>  * Move excnames[] array into arm_log_exceptions()
>  * exynos: minor code cleanups
>  * hw/arm/boot: take Linux/arm64 TEXT_OFFSET header field into account
>  * Fix APSR writes via M profile MSR
>
> 
> Alistair Francis (5):
>   cadence_gem: Read the correct queue descriptor
>   cadence_gem: Correct the multi-queue can rx logic
>   cadence_gem: Correct the interupt logic
>   cadence_gem: Make the revision a property
>   xlnx-zynqmp: Set the Cadence GEM revision
>
> Ard Biesheuvel (1):
>   hw/arm/boot: take Linux/arm64 TEXT_OFFSET header field into account
>
> Ishani Chugh (1):
>   arm/kvm: Remove trailing newlines from error_report()
>
> Krzysztof Kozlowski (3):
>   hw/arm/exynos: Convert fprintf to qemu_log_mask/error_report
>   hw/char/exynos4210_uart: Constify static array and few arguments
>   hw/misc/exynos4210_pmu: Reorder local variables for readability
>
> Peter Maydell (13):
>   target/arm: Add missing entries to excnames[] for log strings
>   arm: Move excnames[] array into arm_log_exceptions()
>   target/arm: Add assertion about FSC format for syndrome registers
>   stellaris: Don't hw_error() on bad register accesses
>   arm: Don't implement BXJ on M-profile CPUs
>   arm: Thumb shift operations should not permit interworking branches
>   arm: Factor out "generate right kind of step exception"
>   arm: Move gen_set_condexec() and gen_set_pc_im() up in the file
>   arm: Move condition-failed codepath generation out of if()
>   arm: Abstract out "are we singlestepping" test to utility function
>   arm: Track M profile handler mode state in TB flags
>   arm: Implement M profile exception return properly
>   arm: Remove workarounds for old M-profile exception return 
> implementation
>
> Suramya Shah (1):
>   hw/arm: Qomify pxa2xx.c
>

Applied, thanks.

-- PMM



[Qemu-devel] [PULL 23/24] arm: Implement M profile exception return properly

2017-04-20 Thread Peter Maydell
On M profile, return from exceptions happen when code in Handler mode
executes one of the following function call return instructions:
 * POP or LDM which loads the PC
 * LDR to PC
 * BX register
and the new PC value is 0xFFxx.

QEMU tries to implement this by not treating the instruction
specially but then catching the attempt to execute from the magic
address value.  This is not ideal, because:
 * there are guest visible differences from the architecturally
   specified behaviour (for instance jumping to 0xFFxx via a
   different instruction should not cause an exception return but it
   will in the QEMU implementation)
 * we have to account for it in various places (like refusing to take
   an interrupt if the PC is at a magic value, and making sure that
   the MPU doesn't deny execution at the magic value addresses)

Drop these hacks, and instead implement exception return the way the
architecture specifies -- by having the relevant instructions check
for the magic value and raise the 'do an exception return' QEMU
internal exception immediately.

The effect on the generated code is minor:

 bx lr, old code (and new code for Thread mode):
  TCG:
   mov_i32 tmp5,r14
   movi_i32 tmp6,$0xfffe
   and_i32 pc,tmp5,tmp6
   movi_i32 tmp6,$0x1
   and_i32 tmp5,tmp5,tmp6
   st_i32 tmp5,env,$0x218
   exit_tb $0x0
   set_label $L0
   exit_tb $0x7f2aabd61993
  x86_64 generated code:
   0x7f2aabe87019:  mov%ebx,%ebp
   0x7f2aabe8701b:  and$0xfffe,%ebp
   0x7f2aabe8701e:  mov%ebp,0x3c(%r14)
   0x7f2aabe87022:  and$0x1,%ebx
   0x7f2aabe87025:  mov%ebx,0x218(%r14)
   0x7f2aabe8702c:  xor%eax,%eax
   0x7f2aabe8702e:  jmpq   0x7f2aabe7c016

 bx lr, new code when in Handler mode:
  TCG:
   mov_i32 tmp5,r14
   movi_i32 tmp6,$0xfffe
   and_i32 pc,tmp5,tmp6
   movi_i32 tmp6,$0x1
   and_i32 tmp5,tmp5,tmp6
   st_i32 tmp5,env,$0x218
   movi_i32 tmp5,$0xff00
   brcond_i32 pc,tmp5,geu,$L1
   exit_tb $0x0
   set_label $L1
   movi_i32 tmp5,$0x8
   call exception_internal,$0x0,$0,env,tmp5
  x86_64 generated code:
   0x7fe8fa1264e3:  mov%ebp,%ebx
   0x7fe8fa1264e5:  and$0xfffe,%ebx
   0x7fe8fa1264e8:  mov%ebx,0x3c(%r14)
   0x7fe8fa1264ec:  and$0x1,%ebp
   0x7fe8fa1264ef:  mov%ebp,0x218(%r14)
   0x7fe8fa1264f6:  cmp$0xff00,%ebx
   0x7fe8fa1264fc:  jae0x7fe8fa126509
   0x7fe8fa126502:  xor%eax,%eax
   0x7fe8fa126504:  jmpq   0x7fe8fa122016
   0x7fe8fa126509:  mov%r14,%rdi
   0x7fe8fa12650c:  mov$0x8,%esi
   0x7fe8fa126511:  mov$0x56095dbeccf5,%r10
   0x7fe8fa12651b:  callq  *%r10

which is a difference of one cmp/branch-not-taken. This will
be lost in the noise of having to exit generated code and
look up the next TB anyway.

Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Message-id: 1491844419-12485-9-git-send-email-peter.mayd...@linaro.org
---
 target/arm/translate.h |  4 +++
 target/arm/translate.c | 66 +-
 2 files changed, 64 insertions(+), 6 deletions(-)

diff --git a/target/arm/translate.h b/target/arm/translate.h
index 3d0e8a6..629dab9 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -135,6 +135,10 @@ static void disas_set_insn_syndrome(DisasContext *s, 
uint32_t syn)
 #define DISAS_HVC 8
 #define DISAS_SMC 9
 #define DISAS_YIELD 10
+/* M profile branch which might be an exception return (and so needs
+ * custom end-of-TB code)
+ */
+#define DISAS_BX_EXCRET 11
 
 #ifdef TARGET_AARCH64
 void a64_translate_init(void);
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 4fe7692..da03e153 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -943,6 +943,51 @@ static inline void gen_bx(DisasContext *s, TCGv_i32 var)
 store_cpu_field(var, thumb);
 }
 
+/* Set PC and Thumb state from var. var is marked as dead.
+ * For M-profile CPUs, include logic to detect exception-return
+ * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
+ * and BX reg, and no others, and happens only for code in Handler mode.
+ */
+static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var)
+{
+/* Generate the same code here as for a simple bx, but flag via
+ * s->is_jmp that we need to do the rest of the work later.
+ */
+gen_bx(s, var);
+if (s->v7m_handler_mode && arm_dc_feature(s, ARM_FEATURE_M)) {
+s->is_jmp = DISAS_BX_EXCRET;
+}
+}
+
+static inline void gen_bx_excret_final_code(DisasContext *s)
+{
+/* Generate the code to finish possible exception return and end the TB */
+TCGLabel *excret_label = gen_new_label();
+
+/* Is the new PC value in the magic range indicating exception return? */
+tcg_gen_brcondi_i32(TCG_COND_GEU, cpu_R[15], 0xff00, excret_label);
+/* No: end the TB as we would for a DISAS_JMP */
+if (is_singlestepping(s)) {
+gen_singlestep_exception(s);
+} els

[Qemu-devel] [PULL 24/24] arm: Remove workarounds for old M-profile exception return implementation

2017-04-20 Thread Peter Maydell
Now that we've rewritten M-profile exception return so that the magic
PC values are not visible to other parts of QEMU, we can delete the
special casing of them elsewhere.

Signed-off-by: Peter Maydell 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-id: 1491844419-12485-10-git-send-email-peter.mayd...@linaro.org
---
 target/arm/cpu.c   | 43 ++-
 target/arm/translate.c |  8 
 2 files changed, 2 insertions(+), 49 deletions(-)

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 04b062c..b357aee 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -304,33 +304,6 @@ bool arm_cpu_exec_interrupt(CPUState *cs, int 
interrupt_request)
 }
 
 #if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
-static void arm_v7m_unassigned_access(CPUState *cpu, hwaddr addr,
-  bool is_write, bool is_exec, int opaque,
-  unsigned size)
-{
-ARMCPU *arm = ARM_CPU(cpu);
-CPUARMState *env = &arm->env;
-
-/* 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 by throwing a special exception when when the CPU tries to
- * execute code at the magic address.
- */
-if (env->v7m.exception != 0 && addr >= 0xfff0 && is_exec) {
-cpu->exception_index = EXCP_EXCEPTION_EXIT;
-cpu_loop_exit(cpu);
-}
-
-/* In real hardware an attempt to access parts of the address space
- * with nothing there will usually cause an external abort.
- * However our QEMU board models are often missing device models where
- * the guest can boot anyway with the default read-as-zero/writes-ignored
- * behaviour that you get without a QEMU unassigned_access hook.
- * So just return here to retain that default behaviour.
- */
-}
-
 static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
 CPUClass *cc = CPU_GET_CLASS(cs);
@@ -338,17 +311,7 @@ static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int 
interrupt_request)
 CPUARMState *env = &cpu->env;
 bool ret = false;
 
-/* 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.
- *
- * ARMv7-M interrupt masking works differently than -A or -R.
+/* ARMv7-M interrupt masking works differently than -A or -R.
  * There is no FIQ/IRQ distinction. Instead of I and F bits
  * masking FIQ and IRQ interrupts, an exception is taken only
  * if it is higher priority than the current execution priority
@@ -356,8 +319,7 @@ static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int 
interrupt_request)
  * currently active exception).
  */
 if (interrupt_request & CPU_INTERRUPT_HARD
-&& (armv7m_nvic_can_take_pending_exception(env->nvic))
-&& (env->regs[15] < 0xfff0)) {
+&& (armv7m_nvic_can_take_pending_exception(env->nvic))) {
 cs->exception_index = EXCP_IRQ;
 cc->do_interrupt(cs);
 ret = true;
@@ -1091,7 +1053,6 @@ static void arm_v7m_class_init(ObjectClass *oc, void 
*data)
 cc->do_interrupt = arm_v7m_cpu_do_interrupt;
 #endif
 
-cc->do_unassigned_access = arm_v7m_unassigned_access;
 cc->cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt;
 }
 
diff --git a/target/arm/translate.c b/target/arm/translate.c
index da03e153..0b5a0bc 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -11927,14 +11927,6 @@ void gen_intermediate_code(CPUARMState *env, 
TranslationBlock *tb)
 dc->is_jmp = DISAS_EXC;
 break;
 }
-#else
-if (arm_dc_feature(dc, ARM_FEATURE_M)) {
-/* Branches to the magic exception-return addresses should
- * already have been caught via the arm_v7m_unassigned_access hook,
- * and never get here.
- */
-assert(dc->pc < 0xfff0);
-}
 #endif
 
 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
-- 
2.7.4




  1   2   3   >