Re: [Qemu-devel] [RESEND PATCH v4 6/6] acpi: Add hardware implementation for memory hot unplug

2015-03-24 Thread Zhu Guihua


On 03/24/2015 06:26 PM, Igor Mammedov wrote:

On Tue, 24 Mar 2015 17:34:29 +0800
Zhu Guihua  wrote:


On 03/23/2015 08:47 PM, Igor Mammedov wrote:

On Mon, 23 Mar 2015 18:59:28 +0800
Zhu Guihua  wrote:


On 03/16/2015 10:59 PM, Igor Mammedov wrote:
[...]

diff --git a/hw/i386/acpi-dsdt-mem-hotplug.dsl b/hw/i386/acpi-dsdt-mem-hotplug.dsl

index 1e9ec39..ef847e2 100644
--- a/hw/i386/acpi-dsdt-mem-hotplug.dsl
+++ b/hw/i386/acpi-dsdt-mem-hotplug.dsl
@@ -29,6 +29,7 @@
External(MEMORY_SLOT_PROXIMITY, FieldUnitObj) // read only
External(MEMORY_SLOT_ENABLED, FieldUnitObj) // 1 if enabled, 
read only
External(MEMORY_SLOT_INSERT_EVENT, FieldUnitObj) // (read) 1 if 
has a insert event. (write) 1 to clear event
+External(MEMORY_SLOT_REMOVE_EVENT, FieldUnitObj) // (read) 1 if 
has a remove event. (write) 1 to clear event
External(MEMORY_SLOT_SLECTOR, FieldUnitObj) // DIMM selector, 
write only
External(MEMORY_SLOT_OST_EVENT, FieldUnitObj) // _OST event 
code, write only
External(MEMORY_SLOT_OST_STATUS, FieldUnitObj) // _OST status 
code, write only
@@ -55,6 +56,8 @@
If (LEqual(MEMORY_SLOT_INSERT_EVENT, One)) { // Memory 
device needs check
MEMORY_SLOT_NOTIFY_METHOD(Local0, 1)
Store(1, MEMORY_SLOT_INSERT_EVENT)
+} Elseif (LEqual(MEMORY_SLOT_REMOVE_EVENT, One)) { // 
Ejection request
+MEMORY_SLOT_NOTIFY_METHOD(Local0, 3)
clear removing field here.

You mean clear remove event here?

yes

I tested this method, clear remove event here will lead to guest
kernel panic.

it shouldn't cause panic if it only clears flag in QEMU
(that's what it should do).



}
// TODO: handle memory eject request
Add(Local0, One, Local0) // goto next DIMM
@@ -156,5 +159,12 @@
Store(Arg2, MEMORY_SLOT_OST_STATUS)
Release(MEMORY_SLOT_LOCK)
}
+
+Method(MEMORY_SLOT_EJECT_METHOD, 2) {
+Acquire(MEMORY_SLOT_LOCK, 0x)
+Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
+Store(One, MEMORY_SLOT_REMOVE_EVENT)

redo it using enabled field. Otherwise it could cause guest/QEMU crash:

- if 1st memory was asked to be removed
- then OSPM processes it but has not called _EJ0 yet leaving is_removed set
- then QEMU adds/removes another DIMM triggering slots scan
  which would issue second Notify(remove) since is_removed is still set
- as result it will cause failure in OSPM or in QEMU if OSPM issues double EJ0()


If OSPM processed the ejection request but not called _EJ0, the device
will still be present in qemu,
we must handle this.

There is nothing to handle in this case, if OSPM hasn't called _EJ0 then
nothing happens and device stays in QEMU.


So I think OSPM issues double EJ0 maybe reasonable
in this situation.
What's your opinion?

the first _EJ0 must do ejection, as for the second I think it should be NOP.

So we should judge the enabled field to check whether the device is
present before
issuing Notify(remove)?

I wouldn't check if device is present.
I'd unconditionally clear it and make sure on QEMU side that
operation is NOP if device is not present.


I'm sorry that I have not fully understood your meaning about
'redo it using enabled field'.  How to do it?

MEMORY_SLOT_ENABLED is read only, how can I use it to handle EJ0?

Thanks,
Zhu





Re: [Qemu-devel] [PATCH v2 0/2] e1000: fixes for Phar Lap ETS

2015-03-24 Thread Richard Tollerton
Stefan Hajnoczi  writes:

> On Wed, Dec 10, 2014 at 11:23:45PM -0600, Richard Tollerton wrote:
>> The 8254x driver in certain versions of Phar Lap ETS hasn't been
>> initializing the e1000 device properly in qemu. It looks like the driver
>> is relying on two specific pieces of behavior which (anecdotally) exist
>> in hardware, although I can't cite any datasheets on the matter; in any
>> case, these two patches adjust this behavior. Tested lightly on both ETS
>> and Win7.
>> 
>> This is a resend; there are no changes compared to v1.
>> 
>> Richard Tollerton (2):
>>   e1000: Clear MDIC register when PHY addr is invalid
>>   e1000: decrement RDT if equal to RDH
>> 
>>  hw/net/e1000.c | 8 +++-
>>  1 file changed, 7 insertions(+), 1 deletion(-)
>
> Hi,
> Just working through unread patches in my mailbox.
>
> Has this patch series stalled?

Apologies, yes -- Jason raised some legitimate concerns, and I haven't
found the time to finish investigating our e1000 driver since then; I
have been negligent in not responding sooner. I probably won't have time
to respond properly until (at least) early May.

> Stefan



Re: [Qemu-devel] virtconsole migration regression from 2.2.0

2015-03-24 Thread Michael S. Tsirkin
On Tue, Mar 24, 2015 at 06:14:44PM -0400, Cole Robinson wrote:
> I'm hitting an error migrating from stock v2.2.0 to git master:
> 
> 2015-03-24T21:42:07.731317Z qemu-system-x86_64: error while loading state for
> instance 0x0 of device ':00:05.0/virtio-console'
> 2015-03-24T21:42:07.731392Z qemu-system-x86_64: load of migration failed:
> Invalid argument
> 
> I'm using libvirt's managedsave, which is migrate to/from file. I bisected to
> this commit:
> 
> commit 9b70c1790acacae54d559d38ca69186a85040bb8
> Author: Michael S. Tsirkin 
> Date:   Mon Feb 16 22:36:26 2015 +0100
> 
> virtio-serial: switch to standard-headers
> 
> Problem seems to be that the old virtio_console_config structure was
> different, missing the emerg_wr field. If I apply this patch:
> 
> diff --git a/include/standard-headers/linux/virtio_console.h
> b/include/standard-headers/linux/virtio_console.h
> index 0dedc9e..242a0c5 100644
> --- a/include/standard-headers/linux/virtio_console.h
> +++ b/include/standard-headers/linux/virtio_console.h
> @@ -50,8 +50,6 @@ struct virtio_console_config {
> uint16_t rows;
> /* max. number of ports this device can hold */
> uint32_t max_nr_ports;
> -   /* emergency write register */
> -   uint32_t emerg_wr;
>  } QEMU_PACKED;
> 
> 
> My VMs restore correctly. I assume that change isn't acceptable as-is 
> though...

Thanks! I see the problem, will fix it shortly.

> Here's the massive libvirt command line:
> 
> /home/crobinso/src/qemu/x86_64-softmmu/qemu-system-x86_64 -name
> migrateion-tester.py-vm -S -machine pc-i440fx-2.2,accel=kvm,usb=off -cpu
> Opteron_G4,+nodeid_msr,+wdt,+skinit,+ibs,+osvw,+cr8legacy,+extapic,+cmp_legacy,+fxsr_opt,+mmxext,+osxsave,+monitor,+ht,+vme
> -m 2048 -realtime mlock=off -smp 2,sockets=2,cores=1,threads=1 -uuid
> ce2a1280-78e5-7233-3f67-139dfedfdfe9 -no-user-config -nodefaults -chardev
> socket,id=charmonitor,path=/var/lib/libvirt/qemu/migrateion-tester.py-vm.monitor,server,nowait
> -mon chardev=charmonitor,id=monitor,mode=control -rtc base=utc -no-shutdown
> -boot strict=on -device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 -device
> virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x5 -drive
> file=/mnt/data/devel/images/ztester-f18-migrate-overlay.qcow2,if=none,id=drive-virtio-disk0,format=qcow2
> -device
> virtio-blk-pci,scsi=off,bus=pci.0,addr=0x6,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1
> -netdev tap,fd=27,id=hostnet0,vhost=on,vhostfd=28 -device
> virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:40:ee:0b,bus=pci.0,addr=0x3
>  -chardev
> spicevmc,id=charchannel0,name=vdagent -device
> virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=com.redhat.spice.0
> -chardev pty,id=charconsole0 -device
> virtconsole,chardev=charconsole0,id=console0 -device usb-tablet,id=input0
> -spice
> port=5901,tls-port=5902,addr=127.0.0.1,disable-ticketing,x509-dir=/etc/pki/libvirt-spice,seamless-migration=on
> -device
> qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,vgamem_mb=16,bus=pci.0,addr=0x2
> -device intel-hda,id=sound0,bus=pci.0,addr=0x4 -device
> hda-duplex,id=sound0-codec0,bus=sound0.0,cad=0 -incoming fd:24 -device
> virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x7 -snapshot -msg timestamp=on
> 
> 
> I tried to reduce it to a minimal reproducer but I couldn't trigger it, but I
> didn't try too long. I can test any proposed fix though.
> 
> Thanks,
> Cole



Re: [Qemu-devel] [RFC PATCH v2 02/23] spapr: Add DRC dt entries for CPUs

2015-03-24 Thread Bharata B Rao
On Wed, Mar 25, 2015 at 11:07:10AM +1100, David Gibson wrote:
> On Mon, Mar 23, 2015 at 07:05:43PM +0530, Bharata B Rao wrote:
> > Advertise CPU DR-capability to the guest via device tree.
> > 
> > Signed-off-by: Bharata B Rao 
> > Signed-off-by: Michael Roth 
> >[spapr_drc_reset implementation]
> > Reviewed-by: David Gibson 
> > ---
> >  hw/ppc/spapr.c | 29 +
> >  1 file changed, 29 insertions(+)
> > 
> > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> > index a782e28..920e650 100644
> > --- a/hw/ppc/spapr.c
> > +++ b/hw/ppc/spapr.c
> > @@ -807,6 +807,15 @@ static void spapr_finalize_fdt(sPAPREnvironment *spapr,
> >  spapr_populate_chosen_stdout(fdt, spapr->vio_bus);
> >  }
> >  
> > +if (spapr->dr_cpu_enabled) {
> > +int offset = fdt_path_offset(fdt, "/cpus");
> > +ret = spapr_drc_populate_dt(fdt, offset, NULL,
> > +SPAPR_DR_CONNECTOR_TYPE_CPU);
> > +if (ret < 0) {
> > +fprintf(stderr, "Couldn't set up CPU DR device tree 
> > properties\n");
> > +}
> > +}
> > +
> >  _FDT((fdt_pack(fdt)));
> >  
> >  if (fdt_totalsize(fdt) > FDT_MAX_SIZE) {
> > @@ -1393,6 +1402,16 @@ static SaveVMHandlers savevm_htab_handlers = {
> >  .load_state = htab_load,
> >  };
> >  
> > +static void spapr_drc_reset(void *opaque)
> > +{
> > +sPAPRDRConnector *drc = opaque;
> > +DeviceState *d = DEVICE(drc);
> > +
> > +if (d) {
> > +device_reset(d);
> > +}
> > +}
> > +
> >  /* pSeries LPAR / sPAPR hardware init */
> >  static void ppc_spapr_init(MachineState *machine)
> >  {
> > @@ -1418,6 +1437,7 @@ static void ppc_spapr_init(MachineState *machine)
> >  long load_limit, fw_size;
> >  bool kernel_le = false;
> >  char *filename;
> > +int smt = kvmppc_smt_threads();
> >  
> >  msi_supported = true;
> >  
> > @@ -1564,6 +1584,15 @@ static void ppc_spapr_init(MachineState *machine)
> >  spapr->dr_cpu_enabled = smc->dr_cpu_enabled;
> >  spapr->dr_lmb_enabled = smc->dr_lmb_enabled;
> >  
> > +if (spapr->dr_cpu_enabled) {
> > +for (i = 0; i < max_cpus/smp_threads; i++) {
> > +sPAPRDRConnector *drc =
> > +spapr_dr_connector_new(OBJECT(machine),
> > +   SPAPR_DR_CONNECTOR_TYPE_CPU, i * 
> > smt);
> > +qemu_register_reset(spapr_drc_reset, drc);
> 
> This seems to be per-core, rather than per-socket as your patch
> comments suggest.

Though we initialize socket-wise at boot time and add one CPU socket
at a time during hot add, the DR connectors are still per-core. 
ibm,my-drc-index property is still per-core.

Also the hotplug event that is sent to the kernel is  per-core and kernel
will bring up one full core (including all its thread) in response to
hot-add.

Socket addition is just a higher level notion but we still do hotplug
at core-level underneath.

Regards,
Bharata.




Re: [Qemu-devel] [RFC PATCH v2 15/23] ppc: Move cpu_exec_init() call to realize function

2015-03-24 Thread David Gibson
On Mon, Mar 23, 2015 at 07:05:56PM +0530, Bharata B Rao wrote:
> Move cpu_exec_init() call from instance_init to realize. This allows
> any failures from cpu_exec_init() to be handled appropriately.
> 
> Also add cpu_exec_exit() call from unrealize.

This still leaves all non-ppc archs not ever calling cpu_exec_exit().

> 
> Signed-off-by: Bharata B Rao 
> ---
>  target-ppc/translate_init.c | 9 +++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
> index 9f4f172..fccee82 100644
> --- a/target-ppc/translate_init.c
> +++ b/target-ppc/translate_init.c
> @@ -8928,6 +8928,11 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error 
> **errp)
>  return;
>  }
>  
> +cpu_exec_init(&cpu->env, &local_err);
> +if (local_err != NULL) {
> +error_propagate(errp, local_err);
> +return;
> +}
>  cpu->cpu_dt_id = (cs->cpu_index / smp_threads) * max_smt
>  + (cs->cpu_index % smp_threads);
>  #endif
> @@ -9141,6 +9146,8 @@ static void ppc_cpu_unrealizefn(DeviceState *dev, Error 
> **errp)
>  opc_handler_t **table;
>  int i, j;
>  
> +cpu_exec_exit(CPU(dev));
> +
>  for (i = 0; i < PPC_CPU_OPCODES_LEN; i++) {
>  if (env->opcodes[i] == &invalid_handler) {
>  continue;
> @@ -9679,8 +9686,6 @@ static void ppc_cpu_initfn(Object *obj)
>  CPUPPCState *env = &cpu->env;
>  
>  cs->env_ptr = env;
> -cpu_exec_init(env, NULL);
> -cpu->cpu_dt_id = cs->cpu_index;
>  
>  env->msr_mask = pcc->msr_mask;
>  env->mmu_model = pcc->mmu_model;

-- 
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


pgpgxujVxbNgj.pgp
Description: PGP signature


Re: [Qemu-devel] [RFC PATCH v2 13/23] cpus: Add Error argument to cpu_exec_init()

2015-03-24 Thread David Gibson
On Mon, Mar 23, 2015 at 07:05:54PM +0530, Bharata B Rao wrote:
> Add an Error argument to cpu_exec_init() to let users collect the
> error. Change all callers to currently pass NULL error argument. This change
> is needed for the following reasons:
> 
> - A subsequent commit changes the CPU enumeration logic in cpu_exec_init()
>   resulting in cpu_exec_init() to fail if cpu_index values corresponding
>   to max_cpus have already been handed out.
> - There is a thinking that cpu_exec_init() should be called from realize
>   rather than instance_init. With this change, those architectures
>   that can move this call into realize function can do so in a phased
>   manner.
> 
> Signed-off-by: Bharata B Rao 

Reviewed-by: David Gibson 

-- 
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


pgpbneWflrFHB.pgp
Description: PGP signature


Re: [Qemu-devel] [RFC PATCH v2 14/23] cpus: Convert cpu_index into a bitmap

2015-03-24 Thread David Gibson
On Mon, Mar 23, 2015 at 07:05:55PM +0530, Bharata B Rao wrote:
> Currently CPUState.cpu_index is monotonically increasing and a newly
> created CPU always gets the next higher index. The next available
> index is calculated by counting the existing number of CPUs. This is
> fine as long as we only add CPUs, but there are architectures which
> are starting to support CPU removal too. For an architecture like PowerPC
> which derives its CPU identifier (device tree ID) from cpu_index, the
> existing logic of generating cpu_index values causes problems.
> 
> With the currently proposed method of handling vCPU removal by parking
> the vCPU fd in QEMU
> (Ref: http://lists.gnu.org/archive/html/qemu-devel/2015-02/msg02604.html),
> generating cpu_index this way will not work for PowerPC.
> 
> This patch changes the way cpu_index is handed out by maintaining
> a bit map of the CPUs that tracks both addition and removal of CPUs.
> 
> Signed-off-by: Bharata B Rao 
> ---
>  exec.c| 37 ++---
>  include/qom/cpu.h |  8 
>  2 files changed, 42 insertions(+), 3 deletions(-)
> 
> diff --git a/exec.c b/exec.c
> index e1ff6b0..9bbab02 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -527,21 +527,52 @@ void tcg_cpu_address_space_init(CPUState *cpu, 
> AddressSpace *as)
>  }
>  #endif
>  
> +#ifndef CONFIG_USER_ONLY
> +static DECLARE_BITMAP(cpu_index_map, MAX_CPUMASK_BITS);
> +
> +static int cpu_get_free_index(Error **errp)
> +{
> +int cpu = find_first_zero_bit(cpu_index_map, max_cpus);
> +
> +if (cpu == max_cpus) {
> +error_setg(errp, "Trying to use more CPUs than allowed max of %d\n",
> +max_cpus);
> +return max_cpus;
> +} else {
> +bitmap_set(cpu_index_map, cpu, 1);
> +return cpu;
> +}
> +}
> +
> +void cpu_exec_exit(CPUState *cpu)
> +{
> +bitmap_clear(cpu_index_map, cpu->cpu_index, 1);
> +}

AFAICT, this function is never called, which seems like a bug.

> +#endif
> +
>  void cpu_exec_init(CPUArchState *env, Error **errp)
>  {
>  CPUState *cpu = ENV_GET_CPU(env);
>  CPUClass *cc = CPU_GET_CLASS(cpu);
> -CPUState *some_cpu;
>  int cpu_index;
> -
>  #if defined(CONFIG_USER_ONLY)
> +CPUState *some_cpu;
> +
>  cpu_list_lock();
> -#endif
>  cpu_index = 0;
>  CPU_FOREACH(some_cpu) {
>  cpu_index++;
>  }
>  cpu->cpu_index = cpu_index;
> +#else
> +Error *local_err = NULL;
> +
> +cpu_index = cpu->cpu_index = cpu_get_free_index(&local_err);
> +if (local_err) {
> +error_propagate(errp, local_err);
> +return;
> +}
> +#endif
>  cpu->numa_node = 0;
>  QTAILQ_INIT(&cpu->breakpoints);
>  QTAILQ_INIT(&cpu->watchpoints);
> diff --git a/include/qom/cpu.h b/include/qom/cpu.h
> index 48fd6fb..5241cf4 100644
> --- a/include/qom/cpu.h
> +++ b/include/qom/cpu.h
> @@ -659,6 +659,14 @@ void cpu_watchpoint_remove_all(CPUState *cpu, int mask);
>  void QEMU_NORETURN cpu_abort(CPUState *cpu, const char *fmt, ...)
>  GCC_FMT_ATTR(2, 3);
>  
> +#ifndef CONFIG_USER_ONLY
> +void cpu_exec_exit(CPUState *cpu);
> +#else
> +static inline void cpu_exec_exit(CPUState *cpu)
> +{
> +}
> +#endif
> +
>  #ifdef CONFIG_SOFTMMU
>  extern const struct VMStateDescription vmstate_cpu_common;
>  #else

-- 
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


pgp2A3Gnq6M9O.pgp
Description: PGP signature


Re: [Qemu-devel] [PATCH v5 5/7] vfio-pci: pass the aer error to guest

2015-03-24 Thread Chen Fan


On 03/25/2015 10:41 AM, Alex Williamson wrote:

On Wed, 2015-03-25 at 09:53 +0800, Chen Fan wrote:

On 03/16/2015 10:09 PM, Alex Williamson wrote:

On Mon, 2015-03-16 at 15:35 +0800, Chen Fan wrote:

On 03/16/2015 11:52 AM, Alex Williamson wrote:

On Mon, 2015-03-16 at 11:05 +0800, Chen Fan wrote:

On 03/14/2015 06:34 AM, Alex Williamson wrote:

On Thu, 2015-03-12 at 18:23 +0800, Chen Fan wrote:

when the vfio device encounters an uncorrectable error in host,
the vfio_pci driver will signal the eventfd registered by this
vfio device, the results in the qemu eventfd handler getting
invoked.

this patch is to pass the error to guest and have the guest driver
recover from the error.

What is going to be the typical recovery mechanism for the guest?  I'm
concerned that the topology of the device in the guest doesn't
necessarily match the topology of the device in the host, so if the
guest were to attempt a bus reset to recover a device, for instance,
what happens?

the recovery mechanism is that when guest got an aer error from a device,
guest will clean the corresponding status bit in device register. and for
need reset device, the guest aer driver would reset all devices under bus.

Sorry, I'm still confused, how does the guest aer driver reset all
devices under a bus?  Are we talking about function-level, device
specific reset mechanisms or secondary bus resets?  If the guest is
performing secondary bus resets, what guarantee do they have that it
will translate to a physical secondary bus reset?  vfio may only do an
FLR when the bus is reset or it may not be able to do anything depending
on the available function-level resets and physical and virtual topology
of the device.  Thanks,

in general, functions depends on the corresponding device driver behaviors
to do the recovery. e.g: implemented the error_detect, slot_reset callbacks.
and for link reset, it usually do secondary bus reset.

and do we must require to the physical secondary bus reset for vfio device
as bus reset?

That depends on how the guest driver attempts recovery, doesn't it?
There are only a very limited number of cases where a secondary bus
reset initiated by the guest will translate to a secondary bus reset of
the physical device (iirc, single function device without FLR).  In most
cases, it will at best be translated to an FLR.  VFIO really only does
bus resets on VM reset because that's the only time we know that it's ok
to reset multiple devices.  If the guest driver is depending on a
secondary bus reset to put the device into a recoverable state and we're
not able to provide that, then we're actually reducing containment of
the error by exposing AER to the guest and allowing it to attempt
recovery.  So in practice, I'm afraid we're risking the integrity of the
VM by exposing AER to the guest and making it think that it can perform
recovery operations that are not effective.  Thanks,

I also have seen that if device without FLR, it seems can do hot reset
by ioctl VFIO_DEVICE_PCI_HOT_RESET to reset the physical slot or bus
in vfio_pci_reset. does it satisfy the recovery issues that you said?

The hot reset interface can only be used when a) the user (QEMU) owns
all of the devices on the bus and b) we know we're resetting all of the
devices.  That mostly limits its use to VM reset.  I think that on a
secondary bus reset, we don't know the scope of the reset at the QEMU
vfio driver, so we only make use of reset methods with a function-level
scope.  That would only result in a secondary bus reset if that's the
reset mechanism used by the host kernel's PCI code (pci_reset_function),
which is limited to single function devices on a secondary bus, with no
other reset mechanisms.  The host reset is also only available in some
configurations, for instance if we have a dual-port NIC where each
function is a separate IOMMU group, then we clearly cannot do a hot
reset unless both functions are assigned to the same VM _and_ appear to
the guest on the same virtual bus.  So even if we could know the scope
of the reset in the QEMU vfio driver, we can only make use of it under
very strict guest configurations.  Thanks,


it seems difficult to allow guest to participate in recovery.
but I think that we might be able to capture the vfio_pci_reset
result. if vfio device reset fail. then we stop the VM.

Thanks,
Chen



Alex

.






Re: [Qemu-devel] [RFC PATCH v2 12/23] spapr: CPU hotplug support

2015-03-24 Thread David Gibson
On Mon, Mar 23, 2015 at 07:05:53PM +0530, Bharata B Rao wrote:
> Support CPU hotplug via device-add command. Set up device tree
> entries for the hotplugged CPU core and use the exising EPOW event
> infrastructure to send CPU hotplug notification to the guest.
> 
> Signed-off-by: Bharata B Rao 
> ---
>  hw/ppc/spapr.c| 75 
> +++
>  hw/ppc/spapr_events.c |  8 +++---
>  hw/ppc/spapr_rtas.c   | 11 
>  3 files changed, 91 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index f52d38f..b48994b 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -33,6 +33,7 @@
>  #include "sysemu/block-backend.h"
>  #include "sysemu/cpus.h"
>  #include "sysemu/kvm.h"
> +#include "sysemu/device_tree.h"
>  #include "kvm_ppc.h"
>  #include "mmu-hash64.h"
>  #include "qom/cpu.h"
> @@ -660,6 +661,10 @@ static void spapr_populate_cpu_dt(CPUState *cs, void 
> *fdt, int offset)
>  QemuOpts *opts = qemu_opts_find(qemu_find_opts("smp-opts"), NULL);
>  unsigned sockets = opts ? qemu_opt_get_number(opts, "sockets", 0) : 0;
>  uint32_t cpus_per_socket = sockets ? (smp_cpus / sockets) : 1;
> +sPAPRDRConnector *drc =
> +spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_CPU, index);
> +sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
> +int drc_index = drck->get_index(drc);
>  
>  _FDT((fdt_setprop_cell(fdt, offset, "reg", index)));
>  _FDT((fdt_setprop_string(fdt, offset, "device_type", "cpu")));
> @@ -728,6 +733,8 @@ static void spapr_populate_cpu_dt(CPUState *cs, void 
> *fdt, int offset)
>  
>  _FDT((fdt_setprop_cell(fdt, offset, "ibm,chip-id",
>  cs->cpu_index / cpus_per_socket)));
> +_FDT((fdt_setprop_cell(fdt, offset, "ibm,my-drc-index", drc_index)));
> +

What effect will this have when running with DR disabled?

>  _FDT(spapr_fixup_cpu_numa_smt_dt(fdt, offset, cs, spapr));
>  }
> @@ -1840,6 +1847,70 @@ static void spapr_nmi(NMIState *n, int cpu_index, 
> Error **errp)
>  }
>  }
>  
> +static void spapr_cpu_hotplug_add(DeviceState *dev, CPUState *cs, Error 
> **errp)
> +{
> +PowerPCCPU *cpu = POWERPC_CPU(cs);
> +DeviceClass *dc = DEVICE_GET_CLASS(cs);
> +int id = ppc_get_vcpu_dt_id(cpu);
> +sPAPRDRConnector *drc =
> +spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_CPU, id);
> +sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
> +void *fdt;
> +int offset, i, fdt_size;
> +char *nodename;
> +
> +fdt = create_device_tree(&fdt_size);
> +nodename = g_strdup_printf("%s@%x", dc->fw_name, id);
> +offset = fdt_add_subnode(fdt, 0, nodename);
> +
> +/* Set NUMA node for the added CPU core */
> +for (i = 0; i < nb_numa_nodes; i++) {
> +if (test_bit(cs->cpu_index, numa_info[i].node_cpu)) {
> +cs->numa_node = i;
> +break;
> +}
> +}
> +
> +spapr_populate_cpu_dt(cs, fdt, offset);
> +g_free(nodename);
> +
> +drck->attach(drc, dev, fdt, offset, !dev->hotplugged, errp);
> +if (*errp) {
> +g_free(fdt);
> +}
> +}
> +
> +static void spapr_cpu_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
> +Error **errp)
> +{
> +CPUState *cs = CPU(dev);
> +PowerPCCPU *cpu = POWERPC_CPU(cs);
> +int id = ppc_get_vcpu_dt_id(cpu);
> +sPAPRDRConnector *drc =
> +spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_CPU, id);
> +int smt = kvmppc_smt_threads();
> +Error *local_err = NULL;
> +
> +/*
> + * SMT threads return from here, only main thread (core) will
> + * continue and signal hotplug event to the guest.
> + */
> +if ((id % smt) != 0) {
> +return;
> +}
> +
> +g_assert(drc);
> +
> +spapr_cpu_hotplug_add(dev, cs, &local_err);
> +if (local_err) {
> +error_propagate(errp, local_err);
> +return;
> +}
> +spapr_hotplug_req_add_event(drc);
> +
> +return;
> +}
> +
>  static void spapr_machine_device_plug(HotplugHandler *hotplug_dev,
>DeviceState *dev, Error **errp)
>  {
> @@ -1848,6 +1919,10 @@ static void spapr_machine_device_plug(HotplugHandler 
> *hotplug_dev,
>  PowerPCCPU *cpu = POWERPC_CPU(cs);
>  
>  spapr_cpu_init(cpu);
> +spapr_cpu_reset(cpu);
> +if (dev->hotplugged && spapr->dr_cpu_enabled) {
> +spapr_cpu_plug(hotplug_dev, dev, errp);
> +}
>  }
>  }
>  
> diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
> index be82815..4ae818a 100644
> --- a/hw/ppc/spapr_events.c
> +++ b/hw/ppc/spapr_events.c
> @@ -421,14 +421,16 @@ static void spapr_hotplug_req_event(sPAPRDRConnector 
> *drc, uint8_t hp_action)
>  hp->hdr.section_length = cpu_to_be16(sizeof(*hp));
>  hp->hdr.section_version = 1; /* includes extended modifier */
>  hp->hotplug_action = hp_action;
> -
> +hp->drc.index = cpu_to_b

[Qemu-devel] [PATCH v3] block: Switch to host monotonic clock for IO throttling

2015-03-24 Thread Fam Zheng
Currently, throttle timers won't make any progress when VCPU is not
running, which would stall the request queue in utils, qtest, vm
suspending, and live migration without special handling.

Block jobs are confusingly inconsistent between with and without
throttling: if user sets a bps limit, starts a block job, then stops vm,
the block job will not make any progress; in contrary, if user unsets
the bps limit, the block job will run normally.

After this patch, with the host clock, even if the VCPUs are stopped,
the throttle queues will be processed.

This patch also enables potential to add throttle to bdrv_drain_all.
Currently all requests are drained immediately. In other words whenever
it is called, IO throttling goes ineffective (examples: system reset,
migration and many block job operations.). This is a loophole that guest
could exploit. If we use the host clock, we can later just trust the
nested poll. This could be done on top.

Note that for qemu-iotests case 093, which uses qtest, we still keep vm
clock so the script can control the clock stepping in order to be
deterministic.

Reviewed-by: Paolo Bonzini 
Reviewed-by: Alberto Garcia 
Signed-off-by: Fam Zheng 

---
v3: More justification in commit message. [Stefan]
Add Paolo's and Alberto's rev-bys.
v2: Don't break qemu-iotests 093.
---
 block.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/block.c b/block.c
index 0fe97de..89a1d5b 100644
--- a/block.c
+++ b/block.c
@@ -30,6 +30,7 @@
 #include "qapi/qmp/qjson.h"
 #include "sysemu/block-backend.h"
 #include "sysemu/sysemu.h"
+#include "sysemu/qtest.h"
 #include "qemu/notify.h"
 #include "block/coroutine.h"
 #include "block/qapi.h"
@@ -181,10 +182,16 @@ static void bdrv_throttle_write_timer_cb(void *opaque)
 /* should be called before bdrv_set_io_limits if a limit is set */
 void bdrv_io_limits_enable(BlockDriverState *bs)
 {
+int clock_type = QEMU_CLOCK_REALTIME;
+
+if (qtest_enabled()) {
+/* For testing block IO throttling only */
+clock_type = QEMU_CLOCK_VIRTUAL;
+}
 assert(!bs->io_limits_enabled);
 throttle_init(&bs->throttle_state,
   bdrv_get_aio_context(bs),
-  QEMU_CLOCK_VIRTUAL,
+  clock_type,
   bdrv_throttle_read_timer_cb,
   bdrv_throttle_write_timer_cb,
   bs);
-- 
1.9.3




Re: [Qemu-devel] [PATCH v5 5/7] vfio-pci: pass the aer error to guest

2015-03-24 Thread Alex Williamson
On Wed, 2015-03-25 at 09:53 +0800, Chen Fan wrote:
> On 03/16/2015 10:09 PM, Alex Williamson wrote:
> > On Mon, 2015-03-16 at 15:35 +0800, Chen Fan wrote:
> >> On 03/16/2015 11:52 AM, Alex Williamson wrote:
> >>> On Mon, 2015-03-16 at 11:05 +0800, Chen Fan wrote:
>  On 03/14/2015 06:34 AM, Alex Williamson wrote:
> > On Thu, 2015-03-12 at 18:23 +0800, Chen Fan wrote:
> >> when the vfio device encounters an uncorrectable error in host,
> >> the vfio_pci driver will signal the eventfd registered by this
> >> vfio device, the results in the qemu eventfd handler getting
> >> invoked.
> >>
> >> this patch is to pass the error to guest and have the guest driver
> >> recover from the error.
> > What is going to be the typical recovery mechanism for the guest?  I'm
> > concerned that the topology of the device in the guest doesn't
> > necessarily match the topology of the device in the host, so if the
> > guest were to attempt a bus reset to recover a device, for instance,
> > what happens?
>  the recovery mechanism is that when guest got an aer error from a device,
>  guest will clean the corresponding status bit in device register. and for
>  need reset device, the guest aer driver would reset all devices under 
>  bus.
> >>> Sorry, I'm still confused, how does the guest aer driver reset all
> >>> devices under a bus?  Are we talking about function-level, device
> >>> specific reset mechanisms or secondary bus resets?  If the guest is
> >>> performing secondary bus resets, what guarantee do they have that it
> >>> will translate to a physical secondary bus reset?  vfio may only do an
> >>> FLR when the bus is reset or it may not be able to do anything depending
> >>> on the available function-level resets and physical and virtual topology
> >>> of the device.  Thanks,
> >> in general, functions depends on the corresponding device driver behaviors
> >> to do the recovery. e.g: implemented the error_detect, slot_reset 
> >> callbacks.
> >> and for link reset, it usually do secondary bus reset.
> >>
> >> and do we must require to the physical secondary bus reset for vfio device
> >> as bus reset?
> > That depends on how the guest driver attempts recovery, doesn't it?
> > There are only a very limited number of cases where a secondary bus
> > reset initiated by the guest will translate to a secondary bus reset of
> > the physical device (iirc, single function device without FLR).  In most
> > cases, it will at best be translated to an FLR.  VFIO really only does
> > bus resets on VM reset because that's the only time we know that it's ok
> > to reset multiple devices.  If the guest driver is depending on a
> > secondary bus reset to put the device into a recoverable state and we're
> > not able to provide that, then we're actually reducing containment of
> > the error by exposing AER to the guest and allowing it to attempt
> > recovery.  So in practice, I'm afraid we're risking the integrity of the
> > VM by exposing AER to the guest and making it think that it can perform
> > recovery operations that are not effective.  Thanks,
> I also have seen that if device without FLR, it seems can do hot reset
> by ioctl VFIO_DEVICE_PCI_HOT_RESET to reset the physical slot or bus
> in vfio_pci_reset. does it satisfy the recovery issues that you said?

The hot reset interface can only be used when a) the user (QEMU) owns
all of the devices on the bus and b) we know we're resetting all of the
devices.  That mostly limits its use to VM reset.  I think that on a
secondary bus reset, we don't know the scope of the reset at the QEMU
vfio driver, so we only make use of reset methods with a function-level
scope.  That would only result in a secondary bus reset if that's the
reset mechanism used by the host kernel's PCI code (pci_reset_function),
which is limited to single function devices on a secondary bus, with no
other reset mechanisms.  The host reset is also only available in some
configurations, for instance if we have a dual-port NIC where each
function is a separate IOMMU group, then we clearly cannot do a hot
reset unless both functions are assigned to the same VM _and_ appear to
the guest on the same virtual bus.  So even if we could know the scope
of the reset in the QEMU vfio driver, we can only make use of it under
very strict guest configurations.  Thanks,

Alex




Re: [Qemu-devel] [RFC PATCH v2 08/23] ppc: Prepare CPU socket/core abstraction

2015-03-24 Thread David Gibson
On Mon, Mar 23, 2015 at 07:05:49PM +0530, Bharata B Rao wrote:

Again, this needs a commit message explaining why the new abstraction
is valuable.

> Signed-off-by: Bharata B Rao 
> Signed-off-by: Andreas Färber 
> ---
>  hw/ppc/Makefile.objs|  1 +
>  hw/ppc/cpu-core.c   | 46 
>  hw/ppc/cpu-socket.c | 47 
> +
>  include/hw/ppc/cpu-core.h   | 32 ++
>  include/hw/ppc/cpu-socket.h | 32 ++
>  5 files changed, 158 insertions(+)
>  create mode 100644 hw/ppc/cpu-core.c
>  create mode 100644 hw/ppc/cpu-socket.c
>  create mode 100644 include/hw/ppc/cpu-core.h
>  create mode 100644 include/hw/ppc/cpu-socket.h
> 
> diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
> index c8ab06e..a35cac5 100644
> --- a/hw/ppc/Makefile.objs
> +++ b/hw/ppc/Makefile.objs
> @@ -1,5 +1,6 @@
>  # shared objects
>  obj-y += ppc.o ppc_booke.o
> +obj-y += cpu-socket.o cpu-core.o
>  # IBM pSeries (sPAPR)
>  obj-$(CONFIG_PSERIES) += spapr.o spapr_vio.o spapr_events.o
>  obj-$(CONFIG_PSERIES) += spapr_hcall.o spapr_iommu.o spapr_rtas.o
> diff --git a/hw/ppc/cpu-core.c b/hw/ppc/cpu-core.c
> new file mode 100644
> index 000..ed0481f
> --- /dev/null
> +++ b/hw/ppc/cpu-core.c
> @@ -0,0 +1,46 @@
> +/*
> + * ppc CPU core abstraction
> + *
> + * Copyright (c) 2015 SUSE Linux GmbH
> + * Copyright (C) 2015 Bharata B Rao 
> + */
> +
> +#include "hw/qdev.h"
> +#include "hw/ppc/cpu-core.h"
> +
> +static int ppc_cpu_core_realize_child(Object *child, void *opaque)
> +{
> +Error **errp = opaque;
> +
> +object_property_set_bool(child, true, "realized", errp);
> +if (*errp) {
> +return 1;
> +}
> +
> +return 0;
> +}
> +
> +static void ppc_cpu_core_realize(DeviceState *dev, Error **errp)
> +{
> +object_child_foreach(OBJECT(dev), ppc_cpu_core_realize_child, errp);
> +}
> +
> +static void ppc_cpu_core_class_init(ObjectClass *oc, void *data)
> +{
> +DeviceClass *dc = DEVICE_CLASS(oc);
> +
> +dc->realize = ppc_cpu_core_realize;
> +}
> +
> +static const TypeInfo ppc_cpu_core_type_info = {
> +.name = TYPE_POWERPC_CPU_CORE,
> +.parent = TYPE_DEVICE,
> +.class_init = ppc_cpu_core_class_init,
> +};
> +
> +static void ppc_cpu_core_register_types(void)
> +{
> +type_register_static(&ppc_cpu_core_type_info);
> +}
> +
> +type_init(ppc_cpu_core_register_types)
> diff --git a/hw/ppc/cpu-socket.c b/hw/ppc/cpu-socket.c
> new file mode 100644
> index 000..602a060
> --- /dev/null
> +++ b/hw/ppc/cpu-socket.c
> @@ -0,0 +1,47 @@
> +/*
> + * PPC CPU socket abstraction
> + *
> + * Copyright (c) 2015 SUSE Linux GmbH
> + * Copyright (C) 2015 Bharata B Rao 
> + */
> +
> +#include "hw/qdev.h"
> +#include "hw/ppc/cpu-socket.h"
> +#include "sysemu/cpus.h"
> +
> +static int ppc_cpu_socket_realize_child(Object *child, void *opaque)
> +{
> +Error **errp = opaque;
> +
> +object_property_set_bool(child, true, "realized", errp);
> +if (*errp) {
> +return 1;
> +} else {
> +return 0;
> +}
> +}
> +
> +static void ppc_cpu_socket_realize(DeviceState *dev, Error **errp)
> +{
> +object_child_foreach(OBJECT(dev), ppc_cpu_socket_realize_child, errp);
> +}
> +
> +static void ppc_cpu_socket_class_init(ObjectClass *oc, void *data)
> +{
> +DeviceClass *dc = DEVICE_CLASS(oc);
> +
> +dc->realize = ppc_cpu_socket_realize;
> +}
> +
> +static const TypeInfo ppc_cpu_socket_type_info = {
> +.name = TYPE_POWERPC_CPU_SOCKET,
> +.parent = TYPE_CPU_SOCKET,
> +.class_init = ppc_cpu_socket_class_init,
> +};
> +
> +static void ppc_cpu_socket_register_types(void)
> +{
> +type_register_static(&ppc_cpu_socket_type_info);
> +}
> +
> +type_init(ppc_cpu_socket_register_types)
> diff --git a/include/hw/ppc/cpu-core.h b/include/hw/ppc/cpu-core.h
> new file mode 100644
> index 000..95f1c28
> --- /dev/null
> +++ b/include/hw/ppc/cpu-core.h
> @@ -0,0 +1,32 @@
> +/*
> + * PowerPC CPU core abstraction
> + *
> + * Copyright (c) 2015 SUSE Linux GmbH
> + * Copyright (C) 2015 Bharata B Rao 
> + */
> +#ifndef HW_PPC_CPU_CORE_H
> +#define HW_PPC_CPU_CORE_H
> +
> +#include "hw/qdev.h"
> +#include "cpu.h"
> +
> +#ifdef TARGET_PPC64
> +#define TYPE_POWERPC_CPU_CORE "powerpc64-cpu-core"
> +#elif defined(TARGET_PPCEMB)
> +#define TYPE_POWERPC_CPU_CORE "embedded-powerpc-cpu-core"
> +#else
> +#define TYPE_POWERPC_CPU_CORE "powerpc-cpu-core"
> +#endif
> +
> +#define POWERPC_CPU_CORE(obj) \
> +OBJECT_CHECK(PowerPCCPUCore, (obj), TYPE_POWERPC_CPU_CORE)
> +
> +typedef struct PowerPCCPUCore {
> +/*< private >*/
> +DeviceState parent_obj;
> +/*< public >*/
> +
> +PowerPCCPU thread[0];
> +} PowerPCCPUCore;
> +
> +#endif
> diff --git a/include/hw/ppc/cpu-socket.h b/include/hw/ppc/cpu-socket.h
> new file mode 100644
> index 000..5ae19d0
> --- /dev/null
> +++ b/include/hw/ppc/cpu-socket.h
> @@ -0,0 +1,32 @@
> +/*
> + * PowerPC CPU socke

Re: [Qemu-devel] [RFC PATCH v2 10/23] ppc: Update cpu_model in MachineState

2015-03-24 Thread David Gibson
On Mon, Mar 23, 2015 at 07:05:51PM +0530, Bharata B Rao wrote:
> Keep cpu_model field in MachineState uptodate so that it can be used
> from the CPU hotplug path.
> 
> Signed-off-by: Bharata B Rao 

Reviewed-by: David Gibson 

-- 
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


pgplDmQVwCVad.pgp
Description: PGP signature


Re: [Qemu-devel] [RFC PATCH v2 09/23] spapr: Add CPU hotplug handler

2015-03-24 Thread David Gibson
On Mon, Mar 23, 2015 at 07:05:50PM +0530, Bharata B Rao wrote:
> Add CPU hotplug handler to spapr machine class and let the plug handler
> initialize spapr CPU specific initialization bits for a realized CPU.
> This lets CPU boot path and hotplug path to share as much code as possible.
> 
> Signed-off-by: Bharata B Rao 

Reviewed-by: David Gibson 


> ---
>  hw/ppc/spapr.c | 25 -
>  1 file changed, 24 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 200dd75..6650f82 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -1555,7 +1555,6 @@ static void ppc_spapr_init(MachineState *machine)
>  fprintf(stderr, "Unable to find PowerPC CPU definition\n");
>  exit(1);
>  }
> -spapr_cpu_init(cpu);
>  }
>  
>  /* allocate RAM */
> @@ -1841,12 +1840,33 @@ static void spapr_nmi(NMIState *n, int cpu_index, 
> Error **errp)
>  }
>  }
>  
> +static void spapr_machine_device_plug(HotplugHandler *hotplug_dev,
> +  DeviceState *dev, Error **errp)
> +{
> +if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
> +CPUState *cs = CPU(dev);
> +PowerPCCPU *cpu = POWERPC_CPU(cs);
> +
> +spapr_cpu_init(cpu);
> +}
> +}
> +
> +static HotplugHandler *spapr_get_hotpug_handler(MachineState *machine,
> + DeviceState *dev)
> +{
> +if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
> +return HOTPLUG_HANDLER(machine);
> +}
> +return NULL;
> +}
> +
>  static void spapr_machine_class_init(ObjectClass *oc, void *data)
>  {
>  MachineClass *mc = MACHINE_CLASS(oc);
>  sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(oc);
>  FWPathProviderClass *fwc = FW_PATH_PROVIDER_CLASS(oc);
>  NMIClass *nc = NMI_CLASS(oc);
> +HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
>  
>  mc->init = ppc_spapr_init;
>  mc->reset = ppc_spapr_reset;
> @@ -1856,6 +1876,8 @@ static void spapr_machine_class_init(ObjectClass *oc, 
> void *data)
>  mc->default_boot_order = NULL;
>  mc->kvm_type = spapr_kvm_type;
>  mc->has_dynamic_sysbus = true;
> +mc->get_hotplug_handler = spapr_get_hotpug_handler;
> +hc->plug = spapr_machine_device_plug;
>  smc->dr_phb_enabled = false;
>  smc->dr_cpu_enabled = false;
>  smc->dr_lmb_enabled = false;
> @@ -1875,6 +1897,7 @@ static const TypeInfo spapr_machine_info = {
>  .interfaces = (InterfaceInfo[]) {
>  { TYPE_FW_PATH_PROVIDER },
>  { TYPE_NMI },
> +{ TYPE_HOTPLUG_HANDLER },
>  { }
>  },
>  };

-- 
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


pgp78uJ6UO0GL.pgp
Description: PGP signature


Re: [Qemu-devel] [RFC PATCH v2 07/23] cpu: Prepare Socket container type

2015-03-24 Thread David Gibson
On Mon, Mar 23, 2015 at 07:05:48PM +0530, Bharata B Rao wrote:
> From: Andreas Färber 

This really wants a commit message explaining the function of this new
abstraction.

> 
> Signed-off-by: Andreas Färber 
> Signed-off-by: Bharata B Rao 
> ---
>  hw/cpu/Makefile.objs|  2 +-
>  hw/cpu/socket.c | 21 +
>  include/hw/cpu/socket.h | 14 ++
>  3 files changed, 36 insertions(+), 1 deletion(-)
>  create mode 100644 hw/cpu/socket.c
>  create mode 100644 include/hw/cpu/socket.h
> 
> diff --git a/hw/cpu/Makefile.objs b/hw/cpu/Makefile.objs
> index 6381238..e6890cf 100644
> --- a/hw/cpu/Makefile.objs
> +++ b/hw/cpu/Makefile.objs
> @@ -3,4 +3,4 @@ obj-$(CONFIG_REALVIEW) += realview_mpcore.o
>  obj-$(CONFIG_A9MPCORE) += a9mpcore.o
>  obj-$(CONFIG_A15MPCORE) += a15mpcore.o
>  obj-$(CONFIG_ICC_BUS) += icc_bus.o
> -
> +obj-y += socket.o
> diff --git a/hw/cpu/socket.c b/hw/cpu/socket.c
> new file mode 100644
> index 000..5ca47e9
> --- /dev/null
> +++ b/hw/cpu/socket.c
> @@ -0,0 +1,21 @@
> +/*
> + * CPU socket abstraction
> + *
> + * Copyright (c) 2013-2014 SUSE LINUX Products GmbH
> + * Copyright (c) 2015 SUSE Linux GmbH
> + */
> +
> +#include "hw/cpu/socket.h"
> +
> +static const TypeInfo cpu_socket_type_info = {
> +.name = TYPE_CPU_SOCKET,
> +.parent = TYPE_DEVICE,
> +.abstract = true,
> +};
> +
> +static void cpu_socket_register_types(void)
> +{
> +type_register_static(&cpu_socket_type_info);
> +}
> +
> +type_init(cpu_socket_register_types)
> diff --git a/include/hw/cpu/socket.h b/include/hw/cpu/socket.h
> new file mode 100644
> index 000..c8e0c18
> --- /dev/null
> +++ b/include/hw/cpu/socket.h
> @@ -0,0 +1,14 @@
> +/*
> + * CPU socket abstraction
> + *
> + * Copyright (c) 2013-2014 SUSE LINUX Products GmbH
> + * Copyright (c) 2015 SUSE Linux GmbH
> + */
> +#ifndef HW_CPU_SOCKET_H
> +#define HW_CPU_SOCKET_H
> +
> +#include "hw/qdev.h"
> +
> +#define TYPE_CPU_SOCKET "cpu-socket"
> +
> +#endif

-- 
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


pgp3BTO7EAdme.pgp
Description: PGP signature


Re: [Qemu-devel] [RFC PATCH v2 11/23] ppc: Create sockets and cores for CPUs

2015-03-24 Thread David Gibson
On Mon, Mar 23, 2015 at 07:05:52PM +0530, Bharata B Rao wrote:
> ppc machine init functions create individual CPU threads. Change this
> for sPAPR by switching to socket creation. CPUs are created recursively
> by socket and core instance init routines.
> 
> TODO: Switching to socket level CPU creation is done only for sPAPR
> target now.
> 
> Signed-off-by: Bharata B Rao 
> ---
>  hw/ppc/cpu-core.c   | 17 +
>  hw/ppc/cpu-socket.c | 15 +++
>  hw/ppc/spapr.c  | 15 ---
>  target-ppc/cpu.h|  1 +
>  target-ppc/translate_init.c | 46 
> +
>  5 files changed, 87 insertions(+), 7 deletions(-)
> 
> diff --git a/hw/ppc/cpu-core.c b/hw/ppc/cpu-core.c
> index ed0481f..f60646d 100644
> --- a/hw/ppc/cpu-core.c
> +++ b/hw/ppc/cpu-core.c
> @@ -7,6 +7,8 @@
>  
>  #include "hw/qdev.h"
>  #include "hw/ppc/cpu-core.h"
> +#include "hw/boards.h"
> +#include 
>  
>  static int ppc_cpu_core_realize_child(Object *child, void *opaque)
>  {
> @@ -32,10 +34,25 @@ static void ppc_cpu_core_class_init(ObjectClass *oc, void 
> *data)
>  dc->realize = ppc_cpu_core_realize;
>  }
>  
> +static void ppc_cpu_core_instance_init(Object *obj)
> +{
> +int i;
> +PowerPCCPU *cpu = NULL;
> +MachineState *machine = MACHINE(qdev_get_machine());
> +
> +for (i = 0; i < smp_threads; i++) {
> +cpu = POWERPC_CPU(cpu_ppc_create(TYPE_POWERPC_CPU, 
> machine->cpu_model));
> +object_property_add_child(obj, "thread[*]", OBJECT(cpu), 
> &error_abort);
> +object_unref(OBJECT(cpu));
> +}
> +}
> +
>  static const TypeInfo ppc_cpu_core_type_info = {
>  .name = TYPE_POWERPC_CPU_CORE,
>  .parent = TYPE_DEVICE,
>  .class_init = ppc_cpu_core_class_init,
> +.instance_init = ppc_cpu_core_instance_init,
> +.instance_size = sizeof(PowerPCCPUCore),

The PowerPCCPUCore structure isn't defined in this patch (I assume it
already existed), which suggests that setting the instance_size should
have already been in an earlier patch.

>  };
>  
>  static void ppc_cpu_core_register_types(void)
> diff --git a/hw/ppc/cpu-socket.c b/hw/ppc/cpu-socket.c
> index 602a060..f901336 100644
> --- a/hw/ppc/cpu-socket.c
> +++ b/hw/ppc/cpu-socket.c
> @@ -8,6 +8,7 @@
>  #include "hw/qdev.h"
>  #include "hw/ppc/cpu-socket.h"
>  #include "sysemu/cpus.h"
> +#include "cpu.h"
>  
>  static int ppc_cpu_socket_realize_child(Object *child, void *opaque)
>  {
> @@ -33,10 +34,24 @@ static void ppc_cpu_socket_class_init(ObjectClass *oc, 
> void *data)
>  dc->realize = ppc_cpu_socket_realize;
>  }
>  
> +static void ppc_cpu_socket_instance_init(Object *obj)
> +{
> +int i;
> +Object *core;
> +
> +for (i = 0; i < smp_cores; i++) {
> +core = object_new(TYPE_POWERPC_CPU_CORE);
> +object_property_add_child(obj, "core[*]", core, &error_abort);
> +object_unref(core);
> +}
> +}
> +
>  static const TypeInfo ppc_cpu_socket_type_info = {
>  .name = TYPE_POWERPC_CPU_SOCKET,
>  .parent = TYPE_CPU_SOCKET,
>  .class_init = ppc_cpu_socket_class_init,
> +.instance_init = ppc_cpu_socket_instance_init,
> +.instance_size = sizeof(PowerPCCPUSocket),

Likewise for PowerPCCPUSocket.
>  
> +/*
> + * This is essentially same as cpu_generic_init() but without a set
> + * realize call.
> + */

In which case it would probably make more sense to have this be a
generic function, and implement cpu_generic_init() in terms of it.

> +CPUState *cpu_ppc_create(const char *typename, const char *cpu_model)
> +{
> +char *str, *name, *featurestr;
> +CPUState *cpu;
> +ObjectClass *oc;
> +CPUClass *cc;
> +Error *err = NULL;
> +
> +str = g_strdup(cpu_model);
> +name = strtok(str, ",");
> +
> +oc = cpu_class_by_name(typename, name);
> +if (oc == NULL) {
> +g_free(str);
> +return NULL;
> +}
> +
> +cpu = CPU(object_new(object_class_get_name(oc)));
> +cc = CPU_GET_CLASS(cpu);
> +
> +featurestr = strtok(NULL, ",");
> +cc->parse_features(cpu, featurestr, &err);
> +g_free(str);
> +if (err != NULL) {
> +goto out;
> +}
> +
> +out:
> +if (err != NULL) {
> +error_report("%s", error_get_pretty(err));
> +error_free(err);
> +object_unref(OBJECT(cpu));
> +return NULL;
> +}
> +
> +return cpu;
> +}
> +
> +/*
> + * TODO: This can be removed when all powerpc targets are converted to
> + * socket level CPU realization.
> + */
>  PowerPCCPU *cpu_ppc_init(const char *cpu_model)
>  {
>  return POWERPC_CPU(cpu_generic_init(TYPE_POWERPC_CPU, cpu_model));

-- 
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


pgp7JtYBCZF1W.pgp
Description: PGP signature


Re: [Qemu-devel] [PATCH v5 5/7] vfio-pci: pass the aer error to guest

2015-03-24 Thread Alex Williamson
On Wed, 2015-03-25 at 09:33 +0800, Chen Fan wrote:
> On 03/16/2015 10:09 PM, Alex Williamson wrote:
> > On Mon, 2015-03-16 at 15:35 +0800, Chen Fan wrote:
> >> On 03/16/2015 11:52 AM, Alex Williamson wrote:
> >>> On Mon, 2015-03-16 at 11:05 +0800, Chen Fan wrote:
>  On 03/14/2015 06:34 AM, Alex Williamson wrote:
> > On Thu, 2015-03-12 at 18:23 +0800, Chen Fan wrote:
> >> when the vfio device encounters an uncorrectable error in host,
> >> the vfio_pci driver will signal the eventfd registered by this
> >> vfio device, the results in the qemu eventfd handler getting
> >> invoked.
> >>
> >> this patch is to pass the error to guest and have the guest driver
> >> recover from the error.
> > What is going to be the typical recovery mechanism for the guest?  I'm
> > concerned that the topology of the device in the guest doesn't
> > necessarily match the topology of the device in the host, so if the
> > guest were to attempt a bus reset to recover a device, for instance,
> > what happens?
>  the recovery mechanism is that when guest got an aer error from a device,
>  guest will clean the corresponding status bit in device register. and for
>  need reset device, the guest aer driver would reset all devices under 
>  bus.
> >>> Sorry, I'm still confused, how does the guest aer driver reset all
> >>> devices under a bus?  Are we talking about function-level, device
> >>> specific reset mechanisms or secondary bus resets?  If the guest is
> >>> performing secondary bus resets, what guarantee do they have that it
> >>> will translate to a physical secondary bus reset?  vfio may only do an
> >>> FLR when the bus is reset or it may not be able to do anything depending
> >>> on the available function-level resets and physical and virtual topology
> >>> of the device.  Thanks,
> >> in general, functions depends on the corresponding device driver behaviors
> >> to do the recovery. e.g: implemented the error_detect, slot_reset 
> >> callbacks.
> >> and for link reset, it usually do secondary bus reset.
> >>
> >> and do we must require to the physical secondary bus reset for vfio device
> >> as bus reset?
> > That depends on how the guest driver attempts recovery, doesn't it?
> > There are only a very limited number of cases where a secondary bus
> > reset initiated by the guest will translate to a secondary bus reset of
> > the physical device (iirc, single function device without FLR).  In most
> > cases, it will at best be translated to an FLR.  VFIO really only does
> > bus resets on VM reset because that's the only time we know that it's ok
> > to reset multiple devices.  If the guest driver is depending on a
> > secondary bus reset to put the device into a recoverable state and we're
> > not able to provide that, then we're actually reducing containment of
> > the error by exposing AER to the guest and allowing it to attempt
> > recovery.  So in practice, I'm afraid we're risking the integrity of the
> > VM by exposing AER to the guest and making it think that it can perform
> > recovery operations that are not effective.  Thanks,
> Hi Alex,
> 
>  if guest driver need reset a vfio device by secondary bus reset when
> an aer occured. how about keeping the behavior by stopping VM and
> output an fatal error information to user.

That sounds like a very fragile heuristic to try to associate the reason
for a secondary bus reset based on the timing of an AER notification.
How can we be sure there's an association?  Is it still worthwhile to
allow the guest to participate in recovery or will most of the cases
just stall the VM stop until a bus reset is attempted?  Thanks,

Alex





Re: [Qemu-devel] [PATCH v5 5/7] vfio-pci: pass the aer error to guest

2015-03-24 Thread Chen Fan


On 03/16/2015 10:09 PM, Alex Williamson wrote:

On Mon, 2015-03-16 at 15:35 +0800, Chen Fan wrote:

On 03/16/2015 11:52 AM, Alex Williamson wrote:

On Mon, 2015-03-16 at 11:05 +0800, Chen Fan wrote:

On 03/14/2015 06:34 AM, Alex Williamson wrote:

On Thu, 2015-03-12 at 18:23 +0800, Chen Fan wrote:

when the vfio device encounters an uncorrectable error in host,
the vfio_pci driver will signal the eventfd registered by this
vfio device, the results in the qemu eventfd handler getting
invoked.

this patch is to pass the error to guest and have the guest driver
recover from the error.

What is going to be the typical recovery mechanism for the guest?  I'm
concerned that the topology of the device in the guest doesn't
necessarily match the topology of the device in the host, so if the
guest were to attempt a bus reset to recover a device, for instance,
what happens?

the recovery mechanism is that when guest got an aer error from a device,
guest will clean the corresponding status bit in device register. and for
need reset device, the guest aer driver would reset all devices under bus.

Sorry, I'm still confused, how does the guest aer driver reset all
devices under a bus?  Are we talking about function-level, device
specific reset mechanisms or secondary bus resets?  If the guest is
performing secondary bus resets, what guarantee do they have that it
will translate to a physical secondary bus reset?  vfio may only do an
FLR when the bus is reset or it may not be able to do anything depending
on the available function-level resets and physical and virtual topology
of the device.  Thanks,

in general, functions depends on the corresponding device driver behaviors
to do the recovery. e.g: implemented the error_detect, slot_reset callbacks.
and for link reset, it usually do secondary bus reset.

and do we must require to the physical secondary bus reset for vfio device
as bus reset?

That depends on how the guest driver attempts recovery, doesn't it?
There are only a very limited number of cases where a secondary bus
reset initiated by the guest will translate to a secondary bus reset of
the physical device (iirc, single function device without FLR).  In most
cases, it will at best be translated to an FLR.  VFIO really only does
bus resets on VM reset because that's the only time we know that it's ok
to reset multiple devices.  If the guest driver is depending on a
secondary bus reset to put the device into a recoverable state and we're
not able to provide that, then we're actually reducing containment of
the error by exposing AER to the guest and allowing it to attempt
recovery.  So in practice, I'm afraid we're risking the integrity of the
VM by exposing AER to the guest and making it think that it can perform
recovery operations that are not effective.  Thanks,

I also have seen that if device without FLR, it seems can do hot reset
by ioctl VFIO_DEVICE_PCI_HOT_RESET to reset the physical slot or bus
in vfio_pci_reset. does it satisfy the recovery issues that you said?

Thanks,
Chen





Alex

.






Re: [Qemu-devel] [RFC PATCH v2 06/23] spapr: Consolidate cpu init code into a routine

2015-03-24 Thread David Gibson
On Mon, Mar 23, 2015 at 07:05:47PM +0530, Bharata B Rao wrote:
> Factor out bits of sPAPR specific CPU initialization code into
> a separate routine so that it can be called from CPU hotplug
> path too.
> 
> Signed-off-by: Bharata B Rao 

Reviewed-by: David Gibson 

-- 
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


pgpoW0YKWg203.pgp
Description: PGP signature


Re: [Qemu-devel] [RFC PATCH v2 05/23] spapr: Reorganize CPU dt generation code

2015-03-24 Thread David Gibson
On Mon, Mar 23, 2015 at 07:05:46PM +0530, Bharata B Rao wrote:
> Reorganize CPU device tree generation code so that it be reused from
> hotplug path. CPU dt entries are now generated from spapr_finalize_fdt()
> instead of spapr_create_fdt_skel().
> 
> Signed-off-by: Bharata B Rao 
> ---
>  hw/ppc/spapr.c | 288 
> ++---
>  1 file changed, 154 insertions(+), 134 deletions(-)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 36ff754..1a25cc0 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -206,24 +206,50 @@ static int spapr_fixup_cpu_smt_dt(void *fdt, int 
> offset, PowerPCCPU *cpu,
>  return ret;
>  }
>  
> +static int spapr_fixup_cpu_numa_smt_dt(void *fdt, int offset, CPUState *cs,
> +sPAPREnvironment *spapr)
> +{
> +int ret;
> +PowerPCCPU *cpu = POWERPC_CPU(cs);
> +int index = ppc_get_vcpu_dt_id(cpu);
> +uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr->htab_shift)};
> +uint32_t associativity[] = {cpu_to_be32(0x5),
> +cpu_to_be32(0x0),
> +cpu_to_be32(0x0),
> +cpu_to_be32(0x0),
> +cpu_to_be32(cs->numa_node),
> +cpu_to_be32(index)};
> +
> +/* Advertise NUMA via ibm,associativity */
> +if (nb_numa_nodes > 1) {
> +ret = fdt_setprop(fdt, offset, "ibm,associativity", associativity,
> +  sizeof(associativity));
> +if (ret < 0) {
> +return ret;
> +}
> +}
> +
> +ret = fdt_setprop(fdt, offset, "ibm,pft-size",
> +  pft_size_prop, sizeof(pft_size_prop));
> +if (ret < 0) {
> +return ret;
> +}

The pft-size property isn't actually related to NUMA, so it doesn't
really belong in this function.

> +return spapr_fixup_cpu_smt_dt(fdt, offset, cpu,
> + ppc_get_compat_smt_threads(cpu));

Likewise calling the smt fixup function from the numa fixup function
just seems odd to me; just be explicit and call the two sequentially.

Overall this seems an odd way to split things.  Why not just make a
spapr_fixup_one_cpu_dt() function, or similar, which should do all the
necessary pieces.

> +}
> +
>  static int spapr_fixup_cpu_dt(void *fdt, sPAPREnvironment *spapr)
>  {
>  int ret = 0, offset, cpus_offset;
>  CPUState *cs;
>  char cpu_model[32];
>  int smt = kvmppc_smt_threads();
> -uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr->htab_shift)};
>  
>  CPU_FOREACH(cs) {
>  PowerPCCPU *cpu = POWERPC_CPU(cs);
>  DeviceClass *dc = DEVICE_GET_CLASS(cs);
>  int index = ppc_get_vcpu_dt_id(cpu);
> -uint32_t associativity[] = {cpu_to_be32(0x5),
> -cpu_to_be32(0x0),
> -cpu_to_be32(0x0),
> -cpu_to_be32(0x0),
> -cpu_to_be32(cs->numa_node),
> -cpu_to_be32(index)};
>  
>  if ((index % smt) != 0) {
>  continue;
> @@ -247,22 +273,7 @@ static int spapr_fixup_cpu_dt(void *fdt, 
> sPAPREnvironment *spapr)
>  }
>  }
>  
> -if (nb_numa_nodes > 1) {
> -ret = fdt_setprop(fdt, offset, "ibm,associativity", 
> associativity,
> -  sizeof(associativity));
> -if (ret < 0) {
> -return ret;
> -}
> -}
> -
> -ret = fdt_setprop(fdt, offset, "ibm,pft-size",
> -  pft_size_prop, sizeof(pft_size_prop));
> -if (ret < 0) {
> -return ret;
> -}
> -
> -ret = spapr_fixup_cpu_smt_dt(fdt, offset, cpu,
> - ppc_get_compat_smt_threads(cpu));
> +ret = spapr_fixup_cpu_numa_smt_dt(fdt, offset, cs, spapr);
>  if (ret < 0) {
>  return ret;
>  }
> @@ -341,18 +352,13 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base,
> uint32_t epow_irq)
>  {
>  void *fdt;
> -CPUState *cs;
>  uint32_t start_prop = cpu_to_be32(initrd_base);
>  uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size);
>  GString *hypertas = g_string_sized_new(256);
>  GString *qemu_hypertas = g_string_sized_new(256);
>  uint32_t refpoints[] = {cpu_to_be32(0x4), cpu_to_be32(0x4)};
>  uint32_t interrupt_server_ranges_prop[] = {0, cpu_to_be32(max_cpus)};
> -int smt = kvmppc_smt_threads();
>  unsigned char vec5[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x80};
> -QemuOpts *opts = qemu_opts_find(qemu_find_opts("smp-opts"), NULL);
> -unsigned sockets = opts ? qemu_opt_get_number(opts, "sockets", 0) : 0;
> -uint32_t cpus_per_socket = sockets ? (smp_cpus / sockets) : 1;
>  char *buf;
>  
>  add_str(hyperta

Re: [Qemu-devel] [Xen-devel] [PATCH] SeaBios/vTPM: Enable Xen stubdom vTPM for HVM virtual machine

2015-03-24 Thread Xu, Quan


> -Original Message-
> From: Stefan Berger [mailto:stef...@linux.vnet.ibm.com]
> Sent: Tuesday, March 24, 2015 11:22 PM
> To: Xu, Quan; Ian Campbell
> Cc: ke...@koconnor.net; qemu-devel@nongnu.org;
> stefano.stabell...@eu.citrix.com; xen-de...@lists.xen.org; Jan Beulich;
> wei.l...@citrix.com
> Subject: Re: [Qemu-devel] [Xen-devel] [PATCH] SeaBios/vTPM: Enable Xen
> stubdom vTPM for HVM virtual machine
> 
> On 03/23/2015 10:20 PM, Xu, Quan wrote:
> >
> >> -Original Message-
> >> From: Stefan Berger [mailto:stef...@linux.vnet.ibm.com]
> >> Sent: Tuesday, March 24, 2015 4:01 AM
> >> To: Xu, Quan; Ian Campbell
> >> Cc: ke...@koconnor.net; qemu-devel@nongnu.org;
> >> stefano.stabell...@eu.citrix.com; xen-de...@lists.xen.org
> >> Subject: Re: [Qemu-devel] [Xen-devel] [PATCH] SeaBios/vTPM: Enable
> >> Xen stubdom vTPM for HVM virtual machine
> >>
> >> On 03/23/2015 08:03 AM, Xu, Quan wrote:
>  -Original Message-
>  From: Stefan Berger [mailto:stef...@linux.vnet.ibm.com]
>  Sent: Monday, March 23, 2015 6:57 PM
>  To: Xu, Quan; Ian Campbell
>  Cc: ke...@koconnor.net; xen-de...@lists.xen.org;
>  qemu-devel@nongnu.org; stefano.stabell...@eu.citrix.com
>  Subject: Re: [Xen-devel] [PATCH] SeaBios/vTPM: Enable Xen stubdom
>  vTPM for HVM virtual machine
> 
>  On 03/22/2015 09:47 PM, Xu, Quan wrote:
> >> -Original Message-
> >> From: Stefan Berger [mailto:stef...@linux.vnet.ibm.com]
> >> Sent: Friday, March 20, 2015 7:44 PM
> >> To: Ian Campbell; Xu, Quan
> >> Cc: ke...@koconnor.net; xen-de...@lists.xen.org;
> >> qemu-devel@nongnu.org; stefano.stabell...@eu.citrix.com
> >> Subject: Re: [Xen-devel] [PATCH] SeaBios/vTPM: Enable Xen stubdom
> >> vTPM for HVM virtual machine
> >>
> >> On 03/19/2015 08:56 AM, Ian Campbell wrote:
> >>> On Tue, 2015-03-10 at 08:16 -0400, Quan Xu wrote:
>  @@ -151,6 +152,8 @@ device_hardware_setup(void)
>   esp_scsi_setup();
>   megasas_setup();
>   pvscsi_setup();
>  +if (runningOnXen())
>  +vtpm4hvm_setup();
> >>> Is there anything which is actually Xen specific about the
> >>> driver in tpm.[ch]? Would it be better to just probe for it,
> >>> perhaps gates by a Kconfig option which enables TPM support.
> >> I also think the probing should be done. That code can also be
> >> recycled from what I posted earlier. It's gated by a Kconfig
> >> option, so it doesn't
>  fill up the 128k ROM.
> >> Stefan
> >>
> > Agree, I will do it ASAP.
>  I reposted v9 of my series of patches. I will probably post v10 today.
>  Please try that one then since these patches should cover Xen, QEMU
>  (using a driver that only I can test at the moment), and to some
>  extent bare metal system.
> 
> 
>    Stefan
> 
> >>> Great!  Could you also archive v10 to your github?
> >>> then I can also test it and go through these source code.
> >> I put it here now:
> >>
> >> https://github.com/stefanberger/seabios-tpm
> >>
> >>   Stefan
> > Thanks.
> > MS windows guest VM are maybe tricky issues. In my early-stage SeaBios
> > patch, I deal with TPM TCPA and SSDT in SeaBios, but MS windows guest VM is
> blue screens(Linux guest virtual machines are working).
> > It works when I deal with TPM TCPA and SSDT in hvmloader for Windows guest
> VM.
> 
> Can you be a bit more specific as to what gets it to work or which 
> modifications
> you have to make in SeaBIOS to make it work?
> 
> 
I put it here: https://github.com/virt2x/pseab2
It is my previous version of seabios to make it work for Linux guest virtual 
machines.
6d256386e823048cdbf23cf3e707f42cfd20a38b is my patch.
It based on:
   [PATCH 1/2] Add an implementation of a TPM TIS driver
   [PATCH 2/2] Provide ACPI SSDT table for TPM device

Maybe it was Xen bios tables issues. I deleted it in my previous patch.

[...]
-if (usingXen()) {
-xen_copy_biostables();
-return;
-}
-
[...]

Thanks, I look forward to workingwith you for vTPM/IMA ... .etc.

Quan





> Stefan



Re: [Qemu-devel] [PATCH 0/3] hw/arm: add Fixed Virtual Platform VE support

2015-03-24 Thread Sergey Fedorov


On 24.03.2015 18:30, Sergey Fedorov wrote:
> On 24.03.2015 17:48, Peter Maydell wrote:
>> On 25 March 2015 at 00:31, Sergey Fedorov  wrote:
>>> On 24.03.2015 17:23, Peter Maydell wrote:
 On 25 March 2015 at 00:18, Sergey Fedorov  wrote:
> This model uses spin table boot method.
 Yes, I noticed, that's a strong reason why I don't want to
 add it if we can avoid it :-)
>>> Why not? :-)
>> Because PSCI is the expected method for SMP support for
>> new 64-bit boards (as I understand it) and so I'd rather
>> not add a lot of legacy spintable code unless we really
>> need the board support for some other reason.
>>
 We already support SMP on AArch64 in TCG mode using PSCI.
>>> Ah, seems I missed this. But isn't it supported only in 'virt'
>>> board?
>> Yes, at the moment. But then 'virt' is our only 64 bit board...
> So if I understand you correctly, it would be suitable to implement a
> model like Juno ARM Development Platform in order to get AArch64 VE
> model with SMP support in system mode?

As you can guess, my objective is to get a model based on Versatile
Express with Cortex-A57 CPU which could be used to run an SMP Linux
kernel on system mode QEMU. So I decided to use the same model as ARM
FastModels provides. I could get ARMv8-A Foundation Platform model as
well, but it also uses spin table boot method. Seems there's no much choice.

Best regards,
Sergey



Re: [Qemu-devel] [PATCH v5 5/7] vfio-pci: pass the aer error to guest

2015-03-24 Thread Chen Fan


On 03/16/2015 10:09 PM, Alex Williamson wrote:

On Mon, 2015-03-16 at 15:35 +0800, Chen Fan wrote:

On 03/16/2015 11:52 AM, Alex Williamson wrote:

On Mon, 2015-03-16 at 11:05 +0800, Chen Fan wrote:

On 03/14/2015 06:34 AM, Alex Williamson wrote:

On Thu, 2015-03-12 at 18:23 +0800, Chen Fan wrote:

when the vfio device encounters an uncorrectable error in host,
the vfio_pci driver will signal the eventfd registered by this
vfio device, the results in the qemu eventfd handler getting
invoked.

this patch is to pass the error to guest and have the guest driver
recover from the error.

What is going to be the typical recovery mechanism for the guest?  I'm
concerned that the topology of the device in the guest doesn't
necessarily match the topology of the device in the host, so if the
guest were to attempt a bus reset to recover a device, for instance,
what happens?

the recovery mechanism is that when guest got an aer error from a device,
guest will clean the corresponding status bit in device register. and for
need reset device, the guest aer driver would reset all devices under bus.

Sorry, I'm still confused, how does the guest aer driver reset all
devices under a bus?  Are we talking about function-level, device
specific reset mechanisms or secondary bus resets?  If the guest is
performing secondary bus resets, what guarantee do they have that it
will translate to a physical secondary bus reset?  vfio may only do an
FLR when the bus is reset or it may not be able to do anything depending
on the available function-level resets and physical and virtual topology
of the device.  Thanks,

in general, functions depends on the corresponding device driver behaviors
to do the recovery. e.g: implemented the error_detect, slot_reset callbacks.
and for link reset, it usually do secondary bus reset.

and do we must require to the physical secondary bus reset for vfio device
as bus reset?

That depends on how the guest driver attempts recovery, doesn't it?
There are only a very limited number of cases where a secondary bus
reset initiated by the guest will translate to a secondary bus reset of
the physical device (iirc, single function device without FLR).  In most
cases, it will at best be translated to an FLR.  VFIO really only does
bus resets on VM reset because that's the only time we know that it's ok
to reset multiple devices.  If the guest driver is depending on a
secondary bus reset to put the device into a recoverable state and we're
not able to provide that, then we're actually reducing containment of
the error by exposing AER to the guest and allowing it to attempt
recovery.  So in practice, I'm afraid we're risking the integrity of the
VM by exposing AER to the guest and making it think that it can perform
recovery operations that are not effective.  Thanks,

Hi Alex,

if guest driver need reset a vfio device by secondary bus reset when
an aer occured. how about keeping the behavior by stopping VM and
output an fatal error information to user.

Thanks,
Chen



Alex

.






Re: [Qemu-devel] [PATCH 0/3] hw/arm: add Fixed Virtual Platform VE support

2015-03-24 Thread Sergey Fedorov
On 24.03.2015 17:48, Peter Maydell wrote:
> On 25 March 2015 at 00:31, Sergey Fedorov  wrote:
>> On 24.03.2015 17:23, Peter Maydell wrote:
>>> On 25 March 2015 at 00:18, Sergey Fedorov  wrote:
 This model uses spin table boot method.
>>> Yes, I noticed, that's a strong reason why I don't want to
>>> add it if we can avoid it :-)
>> Why not? :-)
> Because PSCI is the expected method for SMP support for
> new 64-bit boards (as I understand it) and so I'd rather
> not add a lot of legacy spintable code unless we really
> need the board support for some other reason.
>
>>> We already support SMP on AArch64 in TCG mode using PSCI.
>> Ah, seems I missed this. But isn't it supported only in 'virt'
>> board?
> Yes, at the moment. But then 'virt' is our only 64 bit board...

So if I understand you correctly, it would be suitable to implement a
model like Juno ARM Development Platform in order to get AArch64 VE
model with SMP support in system mode?



Re: [Qemu-devel] One question to lowlevel/xl/xl.c and lowlevel/xc/xc.c

2015-03-24 Thread Chen, Tiejun

On 2015/3/24 18:40, Ian Campbell wrote:

On Tue, 2015-03-24 at 18:31 +0800, Chen, Tiejun wrote:

NB, the libxl ones are broken and not even compiled right now, you can
ignore them.


Looks this is still compiled now.


xc is, xl is not, I am sure of that.


Indeed, you're right :)




I don't know what the semantics of flag is, if it is per SBDF then I


Yes, this should be a flag specific to a SBDF.

You know, I'm working to fix RMRR completely. Based on some discussion
about that design ( I assume you may read that thread previously :) ),
now we probably need to pass a flag to introduce our policy.


Unless you have a concrete requirement to expose RMRR via the Python
bindings to libxc (i.e. you know somebody is using them) then I think
you should not bother.


Actually my problem is that, I need to add a new parameter, 'flag', like 
this, xc_assign_device(xxx,xxx,flag). So if I don't refine xc.c, tools 
can't be compiled successfully. Or maybe you're suggesting I may isolate 
this file while building tools, right?




Making RMRR work via the (C) interface to libxl used by xl and libvirt
is sufficient for a new in tree feature.


Yeah.

Thanks
Tiejun



Ian.

suppose if you really wanted to expose this here then you would need to
invent some syntax for doing so.



Definitely.

When I finish this I will send you to review technically.

Again, really appreciate your clarification to me.

Thanks
Tiejun








Re: [Qemu-devel] [v3][PATCH 2/2] libxl: introduce gfx_passthru_kind

2015-03-24 Thread Chen, Tiejun

On 2015/3/24 22:50, Ian Campbell wrote:

On Mon, 2015-03-23 at 09:17 +0800, Tiejun Chen wrote:

Although we already have 'gfx_passthru' in b_info, this doesn' suffice




Fixed.


 ^t


after we want to handle IGD specifically. Now we define a new field of
type, gfx_passthru_kind, to indicate we're trying to pass IGD. Actually
this means we can benefit this to support other specific devices just
by extending gfx_passthru_kind. And then we can cooperate with
gfx_passthru to address IGD cases as follows:

 gfx_passthru = 0=> sets build_info.u.gfx_passthru to false
 gfx_passthru = 1=> sets build_info.u.gfx_passthru to true and
build_info.u.gfx_passthru_kind to DEFAULT
 gfx_passthru = "igd"=> sets build_info.u.gfx_passthru to false

true

You had it right in the code.


Fixed.




and build_info.u.gfx_passthru_kind to IGD



[snip]


+++ b/docs/man/xl.cfg.pod.5
@@ -671,7 +671,7 @@ through to this VM. See L above.
  devices passed through to this VM. See L
  above.

-=item B
+=item B


I think B is more accurate.


Yeah, it make more sense.




  Enable graphics device PCI passthrough. This option makes an assigned
  PCI graphics card become primary graphics card in the VM. The QEMU
@@ -699,9 +699,12 @@ working graphics passthrough. See the 
XenVGAPassthroughTestedAdapters
  L wiki page
  for currently supported graphics cards for gfx_passthru.

-gfx_passthru is currently only supported with the qemu-xen-traditional
-device-model. Upstream qemu-xen device-model currently does not have
-support for gfx_passthru.
+gfx_passthru is currently supported both with the qemu-xen-traditional
+device-model and upstream qemu-xen device-model. Note with the
+qemu-xen-traditional device-model this option is just treated as BOOLEAN
+actually, but with upstream qemu-xen device-model this option is extended
+to pass a specific device name to force work. Currently just 'igd' is
+defined to support Intel graphics device.


How about:

 When given as a boolean the B option either
 disables gfx passthru or enables autodetection.

 When given as a string the B option describes the
 type of passthru to enable.

 Valid options are:

 =over 4

 =item B

 Disables gfx_passthru.

 =item B, B

 Enables gfx_passthru and autodetects the type of device which is
 being used.

 =item "igd"

 Enables gfx_passthru of the Intel Graphics Device.

 =back

 Note: When used with the qemu-xen-traditional device model only
 IGD passthru is supported.

(do check my pod syntax, I'm mostly making it up!)


Please take a look at this,

@@ -671,7 +671,7 @@ through to this VM. See L above.
 devices passed through to this VM. See L
 above.

-=item B
+=item B

 Enable graphics device PCI passthrough. This option makes an assigned
 PCI graphics card become primary graphics card in the VM. The QEMU
@@ -699,9 +699,35 @@ working graphics passthrough. See the 
XenVGAPassthroughTestedAdapters

 L wiki page
 for currently supported graphics cards for gfx_passthru.

-gfx_passthru is currently only supported with the qemu-xen-traditional
-device-model. Upstream qemu-xen device-model currently does not have
-support for gfx_passthru.
+gfx_passthru is currently supported both with the qemu-xen-traditional
+device-model and upstream qemu-xen device-model.
+
+When given as a boolean the B option either disables gfx
+passthru or enables autodetection.
+
+But when given as a string the B option describes the type
+of device to enable. Not this behavior is only supported with upstream
+qemu-xen device-model.
+
+Currently, valid options are:
+
+=over 4
+
+=item B
+
+Disables graphics device PCI passthrough.
+
+=item B, B
+
+Enables graphics device PCI passthrough and autodetects the type of device
+which is being used.
+
+=item "igd"
+
+Enables graphics device PCI passthrough but force set the type of device
+with the Intel Graphics Device.
+
+=back

 Note that some graphics adapters (AMD/ATI cards, for example) do not
 necessarily require gfx_passthru option, so you can use the normal Xen



The note at the end makes me thing that perhaps something ought to check
this constraint in the qemu-xen-traditional case. It might be easiest to


I understand what you mean but that table just includes IGDs existed on 
BDW and HSW. Because in the case of qemu upstream we're just covering 
these platforms, and with our discussion we don't have any plan to add 
those legacy platforms in the future. But qemu-xen-traditional still 
covers those platforms. So I'm afraid its not good to check this with 
that table as well.



do it in libxl

Re: [Qemu-devel] [PATCH 0/3] hw/arm: add Fixed Virtual Platform VE support

2015-03-24 Thread Peter Maydell
On 25 March 2015 at 00:31, Sergey Fedorov  wrote:
> On 24.03.2015 17:23, Peter Maydell wrote:
>> On 25 March 2015 at 00:18, Sergey Fedorov  wrote:
>>> This model uses spin table boot method.
>> Yes, I noticed, that's a strong reason why I don't want to
>> add it if we can avoid it :-)
>
> Why not? :-)

Because PSCI is the expected method for SMP support for
new 64-bit boards (as I understand it) and so I'd rather
not add a lot of legacy spintable code unless we really
need the board support for some other reason.

>> We already support SMP on AArch64 in TCG mode using PSCI.
>
> Ah, seems I missed this. But isn't it supported only in 'virt'
> board?

Yes, at the moment. But then 'virt' is our only 64 bit board...

-- PMM



Re: [Qemu-devel] [PATCH 0/3] hw/arm: add Fixed Virtual Platform VE support

2015-03-24 Thread Sergey Fedorov
On 24.03.2015 17:23, Peter Maydell wrote:
> On 25 March 2015 at 00:18, Sergey Fedorov  wrote:
>> This model uses spin table boot method.
> Yes, I noticed, that's a strong reason why I don't want to
> add it if we can avoid it :-)

Why not? :-)

>
>> So it enables SMP on AArch64 in TCG mode.
> We already support SMP on AArch64 in TCG mode using PSCI.

Ah, seems I missed this. But isn't it supported only in 'virt' board?

Regards,
Sergey



Re: [Qemu-devel] [RFC PATCH v2 02/23] spapr: Add DRC dt entries for CPUs

2015-03-24 Thread David Gibson
On Mon, Mar 23, 2015 at 07:05:43PM +0530, Bharata B Rao wrote:
> Advertise CPU DR-capability to the guest via device tree.
> 
> Signed-off-by: Bharata B Rao 
> Signed-off-by: Michael Roth 
>[spapr_drc_reset implementation]
> Reviewed-by: David Gibson 
> ---
>  hw/ppc/spapr.c | 29 +
>  1 file changed, 29 insertions(+)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index a782e28..920e650 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -807,6 +807,15 @@ static void spapr_finalize_fdt(sPAPREnvironment *spapr,
>  spapr_populate_chosen_stdout(fdt, spapr->vio_bus);
>  }
>  
> +if (spapr->dr_cpu_enabled) {
> +int offset = fdt_path_offset(fdt, "/cpus");
> +ret = spapr_drc_populate_dt(fdt, offset, NULL,
> +SPAPR_DR_CONNECTOR_TYPE_CPU);
> +if (ret < 0) {
> +fprintf(stderr, "Couldn't set up CPU DR device tree 
> properties\n");
> +}
> +}
> +
>  _FDT((fdt_pack(fdt)));
>  
>  if (fdt_totalsize(fdt) > FDT_MAX_SIZE) {
> @@ -1393,6 +1402,16 @@ static SaveVMHandlers savevm_htab_handlers = {
>  .load_state = htab_load,
>  };
>  
> +static void spapr_drc_reset(void *opaque)
> +{
> +sPAPRDRConnector *drc = opaque;
> +DeviceState *d = DEVICE(drc);
> +
> +if (d) {
> +device_reset(d);
> +}
> +}
> +
>  /* pSeries LPAR / sPAPR hardware init */
>  static void ppc_spapr_init(MachineState *machine)
>  {
> @@ -1418,6 +1437,7 @@ static void ppc_spapr_init(MachineState *machine)
>  long load_limit, fw_size;
>  bool kernel_le = false;
>  char *filename;
> +int smt = kvmppc_smt_threads();
>  
>  msi_supported = true;
>  
> @@ -1564,6 +1584,15 @@ static void ppc_spapr_init(MachineState *machine)
>  spapr->dr_cpu_enabled = smc->dr_cpu_enabled;
>  spapr->dr_lmb_enabled = smc->dr_lmb_enabled;
>  
> +if (spapr->dr_cpu_enabled) {
> +for (i = 0; i < max_cpus/smp_threads; i++) {
> +sPAPRDRConnector *drc =
> +spapr_dr_connector_new(OBJECT(machine),
> +   SPAPR_DR_CONNECTOR_TYPE_CPU, i * smt);
> +qemu_register_reset(spapr_drc_reset, drc);

This seems to be per-core, rather than per-socket as your patch
comments suggest.

-- 
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


pgpej7lkl8sf2.pgp
Description: PGP signature


Re: [Qemu-devel] [RFC PATCH v2 04/23] spapr: Support ibm, lrdr-capacity device tree property

2015-03-24 Thread David Gibson
On Mon, Mar 23, 2015 at 07:05:45PM +0530, Bharata B Rao wrote:
> Add support for ibm,lrdr-capacity since this is needed by the guest
> kernel to know about the possible hot-pluggable CPUs and Memory. With
> this, pseries kernels will start reporting correct maxcpus in
> /sys/devices/system/cpu/possible.
> 
> Define minimum hotpluggable memory size as 256MB and start storing maximum
> possible memory for the guest in sPAPREnvironment.

[snip]
> @@ -666,6 +668,18 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr 
> rtas_addr,
>  }
>  
>  }
> +
> +lrdr_capacity[0] = cpu_to_be32(spapr->maxram_limit >> 32);
> +lrdr_capacity[1] = cpu_to_be32(spapr->maxram_limit & 0x);
> +lrdr_capacity[2] = 0;
> +lrdr_capacity[3] = cpu_to_be32(SPAPR_MEMORY_BLOCK_SIZE);
> +lrdr_capacity[4] = cpu_to_be32(max_cpus/smp_threads);
> +ret = qemu_fdt_setprop(fdt, "/rtas", "ibm,lrdr-capacity", lrdr_capacity,
> + sizeof(lrdr_capacity));
> +if (ret < 0) {
> +fprintf(stderr, "Couldn't add ibm,lrdr-capacity rtas property\n");

This should probably be report_error() these days.

Otherwise,

Reviewed-by: David Gibson 

-- 
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


pgpAY7HU1JfF4.pgp
Description: PGP signature


Re: [Qemu-devel] [RFC PATCH v2 01/23] spapr: enable PHB/CPU/LMB hotplug for pseries-2.3

2015-03-24 Thread David Gibson
On Mon, Mar 23, 2015 at 07:05:42PM +0530, Bharata B Rao wrote:
> From: Michael Roth 
> 
> Introduce an sPAPRMachineClass sub-class of MachineClass to
> handle sPAPR-specific machine configuration properties.
> 
> The 'dr_phb[cpu,lmb]_enabled' field of that class can be set as
> part of machine-specific init code, and is then propagated
> to sPAPREnvironment to conditional enable creation of DRC
> objects and device-tree description to facilitate hotplug
> of PHBs/CPUs/LMBs.
> 
> Since we can't migrate this state to older machine types,
> default the option to false and only enable it for new
> machine types.
> 
> Signed-off-by: Michael Roth 
> Signed-off-by: Bharata B Rao 
>   [Added CPU and LMB bits]
> Reviewed-by: Michael Roth 
> Reviewed-by: David Gibson 

[snip]
> @@ -1854,11 +1882,15 @@ static const TypeInfo spapr_machine_2_2_info = {
>  static void spapr_machine_2_3_class_init(ObjectClass *oc, void *data)
>  {
>  MachineClass *mc = MACHINE_CLASS(oc);
> +sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(oc);
>  
>  mc->name = "pseries-2.3";
>  mc->desc = "pSeries Logical Partition (PAPR compliant) v2.3";
>  mc->alias = "pseries";
>  mc->is_default = 1;
> +smc->dr_phb_enabled = true;
> +smc->dr_cpu_enabled = true;
> +smc->dr_lmb_enabled = true;
>  }

Presumably this will move to pseries-2.4 before merge.

-- 
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


pgpH_sVhSyaon.pgp
Description: PGP signature


Re: [Qemu-devel] [PATCH 0/3] hw/arm: add Fixed Virtual Platform VE support

2015-03-24 Thread Peter Maydell
On 25 March 2015 at 00:18, Sergey Fedorov  wrote:
> This model uses spin table boot method.

Yes, I noticed, that's a strong reason why I don't want to
add it if we can avoid it :-)

> So it enables SMP on AArch64 in TCG mode.

We already support SMP on AArch64 in TCG mode using PSCI.

-- PMM



Re: [Qemu-devel] [PATCH 0/3] hw/arm: add Fixed Virtual Platform VE support

2015-03-24 Thread Sergey Fedorov


On 24.03.2015 17:13, Peter Maydell wrote:
> On 24 March 2015 at 23:55, Sergey Fedorov  wrote:
>> These patches add support for ARM Fixed Virtual Platform Versatile Express
>> board. ARM VFP VE is similar to hardware Versatile Express boards. So these
>> changes rely largely on existing QEMU VE support code. First two patches are
>> prerequisites for the final patch which adds FVP VE board support itself.
>>
>> The changes were tested by running a Linux system in SMP mode using
>> 'arch/arm64/boot/dts/rtsm_ve-aemv8a.dts' from Linux kernel source code for
>> generating device tree blob.
> ...so what's the motivation for our attempting to model
> somebody else's board model? What do we gain over our
> existing VE hardware model?
>
> -- PMM

This model uses spin table boot method. So it enables SMP on AArch64 in
TCG mode.

Best regards,
Sergey.



Re: [Qemu-devel] [PATCH for-2.3] arm: memory: Replace memory_region_init_ram with memory_region_allocate_system_memory

2015-03-24 Thread Peter Maydell
On 25 March 2015 at 00:10, Peter Maydell  wrote:
> So why do only the ARM boards get fixes here?

...ah, I see you've submitted patches for other boards too,
you just didn't put them together into a single series. Sorry.

-- PMM



Re: [Qemu-devel] [PATCH 0/3] hw/arm: add Fixed Virtual Platform VE support

2015-03-24 Thread Peter Maydell
On 24 March 2015 at 23:55, Sergey Fedorov  wrote:
> These patches add support for ARM Fixed Virtual Platform Versatile Express
> board. ARM VFP VE is similar to hardware Versatile Express boards. So these
> changes rely largely on existing QEMU VE support code. First two patches are
> prerequisites for the final patch which adds FVP VE board support itself.
>
> The changes were tested by running a Linux system in SMP mode using
> 'arch/arm64/boot/dts/rtsm_ve-aemv8a.dts' from Linux kernel source code for
> generating device tree blob.

...so what's the motivation for our attempting to model
somebody else's board model? What do we gain over our
existing VE hardware model?

-- PMM



Re: [Qemu-devel] [PATCH for-2.3] arm: memory: Replace memory_region_init_ram with memory_region_allocate_system_memory

2015-03-24 Thread Peter Maydell
On 24 March 2015 at 21:24, Dirk Müller  wrote:
> Commit 0b183fc871:"memory: move mem_path handling to
> memory_region_allocate_system_memory" split memory_region_init_ram and
> memory_region_init_ram_from_file. Also it moved mem-path handling a step
> up from memory_region_init_ram to memory_region_allocate_system_memory.
>
> Therefore for any board that uses memory_region_init_ram directly,
> -mem-path is not supported.
>
> Fix this by replacing memory_region_init_ram with
> memory_region_allocate_system_memory.
>
> Signed-off-by: Dirk Mueller 
> ---
>  hw/arm/cubieboard.c   |  5 ++---
>  hw/arm/digic_boards.c |  3 +--
>  hw/arm/exynos4210.c   | 12 ++--
>  hw/arm/highbank.c |  2 +-
>  hw/arm/integratorcp.c |  4 ++--
>  hw/arm/kzm.c  |  3 +--
>  hw/arm/musicpal.c |  5 ++---
>  hw/arm/omap1.c|  7 ---
>  hw/arm/omap2.c|  6 +++---
>  hw/arm/realview.c | 10 --
>  hw/arm/strongarm.c|  7 ---
>  hw/arm/versatilepb.c  |  5 ++---
>  hw/arm/vexpress.c | 10 --
>  hw/arm/virt.c |  5 ++---
>  hw/arm/xilinx_zynq.c  |  5 ++---

So why do only the ARM boards get fixes here?
(Why did we allow ourselves to break half our boards
in commit 0b183fc871 in the first place?)

-- PMM



[Qemu-devel] [PATCH 3/3] hw/arm/vexpress: add FVP VE board support

2015-03-24 Thread Sergey Fedorov
This patch allows to boot AA64 linux kernel in SMP mode with DTB
generated from 'arch/arm64/boot/dts/rtsm_ve-aemv8a.dts' of Linux kernel
source code.

CPU and GIC creation parts are adaptation of code from "hw/arm/virt.c".

Signed-off-by: Sergey Fedorov 
---
 hw/arm/vexpress.c | 137 ++
 1 file changed, 137 insertions(+)

diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
index 97ccf15..8ab4e8a 100644
--- a/hw/arm/vexpress.c
+++ b/hw/arm/vexpress.c
@@ -170,6 +170,7 @@ typedef struct {
 #define TYPE_VEXPRESS_MACHINE   "vexpress"
 #define TYPE_VEXPRESS_A9_MACHINE   "vexpress-a9"
 #define TYPE_VEXPRESS_A15_MACHINE   "vexpress-a15"
+#define TYPE_FVP_VE_MACHINE   "fvp_ve"
 #define VEXPRESS_MACHINE(obj) \
 OBJECT_CHECK(VexpressMachineState, (obj), TYPE_VEXPRESS_MACHINE)
 #define VEXPRESS_MACHINE_GET_CLASS(obj) \
@@ -430,6 +431,124 @@ static VEDBoardInfo a15_daughterboard = {
 .init = a15_daughterboard_init,
 };
 
+static void fvp_ve_create_gic(const VexpressMachineState *vms,
+  hwaddr periphbase, qemu_irq *pic)
+{
+/* We create a standalone GIC v2 */
+DeviceState *gicdev;
+SysBusDevice *gicbusdev;
+int i;
+
+gicdev = qdev_create(NULL, "arm_gic");
+qdev_prop_set_uint32(gicdev, "revision", 2);
+qdev_prop_set_uint32(gicdev, "num-cpu", smp_cpus);
+qdev_prop_set_uint32(gicdev, "num-irq", 96);
+qdev_init_nofail(gicdev);
+gicbusdev = SYS_BUS_DEVICE(gicdev);
+sysbus_mmio_map(gicbusdev, 0, periphbase + 0x1000);
+sysbus_mmio_map(gicbusdev, 1, periphbase + 0x2000);
+
+/* Wire the outputs from each CPU's generic timer to the
+ * appropriate GIC PPI inputs, and the GIC's IRQ output to
+ * the CPU's IRQ input.
+ */
+for (i = 0; i < smp_cpus; i++) {
+DeviceState *cpudev = DEVICE(qemu_get_cpu(i));
+int ppibase = 64 + i * 32;
+/* physical timer; we wire it up to the non-secure timer's ID,
+ * since QEMU doesn't have TrustZone support so far.
+ */
+qdev_connect_gpio_out(cpudev, 0,
+  qdev_get_gpio_in(gicdev, ppibase + 30));
+/* virtual timer */
+qdev_connect_gpio_out(cpudev, 1,
+  qdev_get_gpio_in(gicdev, ppibase + 27));
+
+sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, 
ARM_CPU_IRQ));
+}
+
+for (i = 0; i < 64; i++) {
+pic[i] = qdev_get_gpio_in(gicdev, i);
+}
+}
+
+static void fvp_ve_daughterboard_init(const VexpressMachineState *vms,
+  ram_addr_t ram_size,
+  const char *cpu_model,
+  qemu_irq *pic)
+{
+MemoryRegion *sysmem = get_system_memory();
+MemoryRegion *ram = g_new(MemoryRegion, 1);
+MemoryRegion *sram = g_new(MemoryRegion, 1);
+const hwaddr periphbase = 0x2c00;
+int n;
+
+if (!cpu_model) {
+cpu_model = "cortex-a57";
+}
+
+{
+/* We have to use a separate 64 bit variable here to avoid the gcc
+ * "comparison is always false due to limited range of data type"
+ * warning if we are on a host where ram_addr_t is 32 bits.
+ */
+uint64_t rsz = ram_size;
+if (rsz > (30ULL * 1024 * 1024 * 1024)) {
+fprintf(stderr, "fvp_ve: cannot model more than 30GB RAM\n");
+exit(1);
+}
+}
+
+memory_region_init_ram(ram, NULL, "fvp.highmem", ram_size, &error_abort);
+vmstate_register_ram_global(ram);
+memory_region_add_subregion(sysmem, 0x8000, ram);
+
+for (n = 0; n < smp_cpus; n++) {
+ObjectClass *oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model);
+Object *cpuobj;
+
+if (!oc) {
+fprintf(stderr, "Unable to find CPU definition\n");
+exit(1);
+}
+cpuobj = object_new(object_class_get_name(oc));
+
+if (!vms->secure) {
+object_property_set_bool(cpuobj, false, "has_el3", NULL);
+}
+
+if (object_property_find(cpuobj, "reset-cbar", NULL)) {
+object_property_set_int(cpuobj, periphbase,
+"reset-cbar", &error_abort);
+}
+
+object_property_set_bool(cpuobj, true, "realized", NULL);
+}
+
+fvp_ve_create_gic(vms, periphbase, pic);
+
+memory_region_init_ram(sram, NULL, "fvp.sram", 0x1, &error_abort);
+vmstate_register_ram_global(sram);
+memory_region_add_subregion(sysmem, 0x2e00, sram);
+}
+
+static const uint32_t fvp_ve_clocks[] = {
+32000, /* refclk */
+100, /* timclk */
+2400, /* apb_pclk */
+};
+
+static VEDBoardInfo fvp_ve_daughterboard = {
+.motherboard_map = motherboard_aseries_map,
+.loader_start = 0x8000,
+.smp_bootreg_addr = 0x8000fff8,
+.gic_cpu_if_addr = 0x2c002000,
+.num_voltage_sensors = 0,
+.num_clocks = ARRAY_SIZE(fvp_ve_clocks),
+.clocks = fvp_v

[Qemu-devel] [PATCH 0/3] hw/arm: add Fixed Virtual Platform VE support

2015-03-24 Thread Sergey Fedorov
These patches add support for ARM Fixed Virtual Platform Versatile Express
board. ARM VFP VE is similar to hardware Versatile Express boards. So these
changes rely largely on existing QEMU VE support code. First two patches are
prerequisites for the final patch which adds FVP VE board support itself.

The changes were tested by running a Linux system in SMP mode using
'arch/arm64/boot/dts/rtsm_ve-aemv8a.dts' from Linux kernel source code for
generating device tree blob.

Sergey Fedorov (3):
  hw/arm/boot: add secondary loader for AArch64
  hw/arm/vexpress: introduce VEDBoardInfo::smp_bootreg_addr
  hw/arm/vexpress: add FVP VE board support

 hw/arm/boot.c |  26 +-
 hw/arm/vexpress.c | 142 +-
 2 files changed, 165 insertions(+), 3 deletions(-)

-- 
2.3.4




[Qemu-devel] [PATCH 2/3] hw/arm/vexpress: introduce VEDBoardInfo::smp_bootreg_addr

2015-03-24 Thread Sergey Fedorov
Require secondary CPU release address to be specified explicitly in each
daughterboard info structure.

Signed-off-by: Sergey Fedorov 
---
 hw/arm/vexpress.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
index 8496c16..97ccf15 100644
--- a/hw/arm/vexpress.c
+++ b/hw/arm/vexpress.c
@@ -186,6 +186,7 @@ struct VEDBoardInfo {
 struct arm_boot_info bootinfo;
 const hwaddr *motherboard_map;
 hwaddr loader_start;
+hwaddr smp_bootreg_addr;
 const hwaddr gic_cpu_if_addr;
 uint32_t proc_id;
 uint32_t num_voltage_sensors;
@@ -337,6 +338,7 @@ static const uint32_t a9_clocks[] = {
 static VEDBoardInfo a9_daughterboard = {
 .motherboard_map = motherboard_legacy_map,
 .loader_start = 0x6000,
+.smp_bootreg_addr = 0x1030,
 .gic_cpu_if_addr = 0x1e000100,
 .proc_id = 0x0c000191,
 .num_voltage_sensors = ARRAY_SIZE(a9_voltages),
@@ -418,6 +420,7 @@ static const uint32_t a15_clocks[] = {
 static VEDBoardInfo a15_daughterboard = {
 .motherboard_map = motherboard_aseries_map,
 .loader_start = 0x8000,
+.smp_bootreg_addr = 0x1c010030,
 .gic_cpu_if_addr = 0x2c002000,
 .proc_id = 0x14000237,
 .num_voltage_sensors = ARRAY_SIZE(a15_voltages),
@@ -700,7 +703,7 @@ static void vexpress_common_init(MachineState *machine)
 daughterboard->bootinfo.board_id = VEXPRESS_BOARD_ID;
 daughterboard->bootinfo.loader_start = daughterboard->loader_start;
 daughterboard->bootinfo.smp_loader_start = map[VE_SRAM];
-daughterboard->bootinfo.smp_bootreg_addr = map[VE_SYSREGS] + 0x30;
+daughterboard->bootinfo.smp_bootreg_addr = daughterboard->smp_bootreg_addr;
 daughterboard->bootinfo.gic_cpu_if_addr = daughterboard->gic_cpu_if_addr;
 daughterboard->bootinfo.modify_dtb = vexpress_modify_dtb;
 /* Indicate that when booting Linux we should be in secure state */
-- 
2.3.4




[Qemu-devel] [PATCH 1/3] hw/arm/boot: add secondary loader for AArch64

2015-03-24 Thread Sergey Fedorov
This default secondary loader is used to bring up secondary CPUs using
spin table boot method.

Signed-off-by: Sergey Fedorov 
---
 hw/arm/boot.c | 26 --
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index a48d1b2..2bff2f2 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -57,6 +57,18 @@ static const ARMInsnFixup bootloader_aarch64[] = {
 { 0, FIXUP_TERMINATOR }
 };
 
+static const ARMInsnFixup smpboot_aarch64[] = {
+{ 0xd503205f }, /* wfe */
+{ 0x58a0 }, /* ldr x0, bootreg_addr */
+{ 0xf940 }, /* ldr x0, [x0] */
+{ 0xb4a0 }, /* cbz x0,  */
+{ 0xd61f }, /* br  x0 */
+{ 0xd503201f }, /* nop */
+{ 0, FIXUP_BOOTREG }, /* bootreg_addr: .word 0x... */
+{ 0 }, /* .word 0 */
+{ 0, FIXUP_TERMINATOR }
+};
+
 /* The worlds second smallest bootloader.  Set r0-r2, then jump to kernel.  */
 static const ARMInsnFixup bootloader[] = {
 { 0xe3a0 }, /* mov r0, #0 */
@@ -152,6 +164,7 @@ static void default_write_secondary(ARMCPU *cpu,
 const struct arm_boot_info *info)
 {
 uint32_t fixupcontext[FIXUP_MAX];
+const ARMInsnFixup *secondary_loader;
 
 fixupcontext[FIXUP_GIC_CPU_IF] = info->gic_cpu_if_addr;
 fixupcontext[FIXUP_BOOTREG] = info->smp_bootreg_addr;
@@ -161,8 +174,13 @@ static void default_write_secondary(ARMCPU *cpu,
 fixupcontext[FIXUP_DSB] = CP15_DSB_INSN;
 }
 
+if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
+secondary_loader = smpboot_aarch64;
+} else {
+secondary_loader = smpboot;
+}
 write_bootloader("smpboot", info->smp_loader_start,
- smpboot, fixupcontext);
+ secondary_loader, fixupcontext);
 }
 
 static void default_reset_secondary(ARMCPU *cpu,
@@ -171,7 +189,11 @@ static void default_reset_secondary(ARMCPU *cpu,
 CPUARMState *env = &cpu->env;
 
 stl_phys_notdirty(&address_space_memory, info->smp_bootreg_addr, 0);
-env->regs[15] = info->smp_loader_start;
+if (is_a64(env)) {
+env->pc = info->smp_loader_start;
+} else {
+env->regs[15] = info->smp_loader_start;
+}
 }
 
 static inline bool have_dtb(const struct arm_boot_info *info)
-- 
2.3.4




Re: [Qemu-devel] [PATCH] Haiku: Platform build fixes

2015-03-24 Thread François Revol
On 25/03/2015 00:40, Andreas Färber wrote:
> Am 25.03.2015 um 00:11 schrieb Max Filippov:
>> On Wed, Mar 25, 2015 at 2:03 AM, François Revol  wrote:
>>> On 24/03/2015 23:56, Max Filippov wrote:
 On Wed, Mar 25, 2015 at 1:26 AM, Andreas Färber  wrote:
> Am 24.03.2015 um 00:36 schrieb Alexander von Gluck IV:
>>
>
> Why convert from array to switch statement? It looks like a very
> invasive change for no obvious reason.

 I'd be interested to know the reason too, but I'm OK with either way.
>>>
>>> Maybe because negative array indices are usually a bad idea in C?
>>
>> Sounds like a good reason (:
> 
> True, but assumes that error codes are indeed negative.
> 
> AFAIU linking with -lposix_error_helper or so (-> configure/Makefile*)
> may be an alternative, keeping errors POSIX-compliant in our code. I
> don't recall the implementation details though...

Indeed, although it doesn't solve everything (some things like nginx
want to use deprecated things like sys_errlist[] (although they dropped
this) or assume the codes are all < some very low positive value), and I
suspect it could have strange side effects on code used as a library by
other things.

As for myself, I consider POSIX to be boggus (they even changed their
mind in some places) and error prone on this (I've ported enough foreign
code to assert this) :p

François.




Re: [Qemu-devel] RFC: memory API changes

2015-03-24 Thread Peter Maydell
On 24 March 2015 at 20:00, Paolo Bonzini  wrote:
> On 24/03/2015 19:06, Peter Maydell wrote:
>> I think this is where we disagree. I see ld/st*_phys as being
>> really generic -- they take an AddressSpace, after all, and
>> part of the same family with address_space_read &c. If you
>> don't leave them as generic, then you end up having to use
>> the really awkward _read/_write for simple accesses and
>> then manage the byteswapping yourself. That's why I want
>> to rename them into address_space_* : to indicate that they
>> are all part of the same family, and you can use
>> address_space_read if you want to read an arbitrary byte
>> buffer, or address_space_ldl_be if you want to read a
>> big endian 32 bit word, and so on.
>
> I agree with that.  I just want to keep ld/st*_phys _in addition_ as the
> short forms of address_space_ld/st*, and keep ld/st*_phys instead of
> address_space_ld/st* for those uses that have cs->as as the first argument.

...but for ARM I want to be able to specify the memory
attribute argument (and possibly also get the behaviour
right on failure). So I definitely don't want the short
forms for my cs->as uses. And it seems to me at best
uncertain that anybody does, in the long run. So why leave
temptingly short and simple looking function names in
the codebase to trip people up?

> The rationale is to evolve ld/st*_phys into CPU-specific accessors
> paralleling the bus-specific accessors.

I don't think this is any harder starting from
address_space_ld/st* than if we leave ld/st*_phys
around.

-- PMM



Re: [Qemu-devel] [PATCH] Haiku: Platform build fixes

2015-03-24 Thread Andreas Färber
Am 25.03.2015 um 00:11 schrieb Max Filippov:
> On Wed, Mar 25, 2015 at 2:03 AM, François Revol  wrote:
>> On 24/03/2015 23:56, Max Filippov wrote:
>>> On Wed, Mar 25, 2015 at 1:26 AM, Andreas Färber  wrote:
 Am 24.03.2015 um 00:36 schrieb Alexander von Gluck IV:
>

 Why convert from array to switch statement? It looks like a very
 invasive change for no obvious reason.
>>>
>>> I'd be interested to know the reason too, but I'm OK with either way.
>>
>> Maybe because negative array indices are usually a bad idea in C?
> 
> Sounds like a good reason (:

True, but assumes that error codes are indeed negative.

AFAIU linking with -lposix_error_helper or so (-> configure/Makefile*)
may be an alternative, keeping errors POSIX-compliant in our code. I
don't recall the implementation details though...

Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Jennifer Guild, Dilip Upmanyu,
Graham Norton; HRB 21284 (AG Nürnberg)



Re: [Qemu-devel] [PATCH for-2.3 2/2] i440fx-test: Fix test paths to include architecture

2015-03-24 Thread John Snow



On 03/24/2015 07:20 PM, Andreas Färber wrote:

Am 25.03.2015 um 00:09 schrieb John Snow:

On 03/24/2015 06:45 PM, Andreas Färber wrote:

Replace g_test_add_func() with new qtest_add_func() and modify the path
passed to g_test_add() macro.

Signed-off-by: Andreas Färber 
---
   tests/i440fx-test.c | 8 +---
   1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/tests/i440fx-test.c b/tests/i440fx-test.c
index a3f7279..bc3f54c 100644
--- a/tests/i440fx-test.c
+++ b/tests/i440fx-test.c
@@ -383,8 +383,10 @@ static void add_firmware_test(const char *testpath,
 void
(*setup_fixture)(FirmwareTestFixture *f,
   gconstpointer
test_data))
   {
-g_test_add(testpath, FirmwareTestFixture, NULL, setup_fixture,
+char *path = g_strdup_printf("/%s%s", qtest_get_arch(), testpath);
+g_test_add(path, FirmwareTestFixture, NULL, setup_fixture,
  test_i440fx_firmware, NULL);
+g_free(path);
   }



Is it not worth adding an even more generic wrapper to prevent future
desynch from our preferred path format?


As mentioned in the commit message, g_test_add() is a macro, not a
function, so seemed more complicated to wrap. Can you post a patch if
you have an idea? :)



Not enough of one to bother delaying this for 2.3 -- I did forget this 
was a macro.


Reviewed-by: John Snow 


   static void request_bios(FirmwareTestFixture *fixture,
@@ -408,8 +410,8 @@ int main(int argc, char **argv)

   data.num_cpus = 1;

-g_test_add_data_func("/i440fx/defaults", &data,
test_i440fx_defaults);
-g_test_add_data_func("/i440fx/pam", &data, test_i440fx_pam);
+qtest_add_data_func("i440fx/defaults", &data, test_i440fx_defaults);
+qtest_add_data_func("i440fx/pam", &data, test_i440fx_pam);
   add_firmware_test("/i440fx/firmware/bios", request_bios);
   add_firmware_test("/i440fx/firmware/pflash", request_pflash);




Similar to above, is it worth replacing other test's usage of
g_test_add_data_func to force this standard path format everywhere?


I reviewed the test output from -rc0 while going through test failures.
fw_cfg-test and i440fx-test were the only nits I found. I wondered
whether we might poison the g_test_* versions or convert the other
tests, but did not want to unnecessarily risk this for 2.3.



I can get behind "change as little as possible."


Another issue that I've come across is that several tests misuse qmp(),
ignoring the return value instead of using qmp_discard_response().

Also I had the impression that my qom-test has noticeably degraded in
performance, and I wondered whether Paolo's changes to qmp(), parsing
the string argument into a QObject, might be to blame, given that a lot
of QMP qom-gets are performed by my test, and the number of objects and
properties tested keeps increasing (MemoryRegion, qemu_irq, machines).


I can always fire up valgrind and figure out something to point a finger 
at :)



Thanks a lot for your review.

Regards,
Andreas






Re: [Qemu-devel] [PATCH for-2.3 2/2] i440fx-test: Fix test paths to include architecture

2015-03-24 Thread Andreas Färber
Am 25.03.2015 um 00:09 schrieb John Snow:
> On 03/24/2015 06:45 PM, Andreas Färber wrote:
>> Replace g_test_add_func() with new qtest_add_func() and modify the path
>> passed to g_test_add() macro.
>>
>> Signed-off-by: Andreas Färber 
>> ---
>>   tests/i440fx-test.c | 8 +---
>>   1 file changed, 5 insertions(+), 3 deletions(-)
>>
>> diff --git a/tests/i440fx-test.c b/tests/i440fx-test.c
>> index a3f7279..bc3f54c 100644
>> --- a/tests/i440fx-test.c
>> +++ b/tests/i440fx-test.c
>> @@ -383,8 +383,10 @@ static void add_firmware_test(const char *testpath,
>> void
>> (*setup_fixture)(FirmwareTestFixture *f,
>>   gconstpointer
>> test_data))
>>   {
>> -g_test_add(testpath, FirmwareTestFixture, NULL, setup_fixture,
>> +char *path = g_strdup_printf("/%s%s", qtest_get_arch(), testpath);
>> +g_test_add(path, FirmwareTestFixture, NULL, setup_fixture,
>>  test_i440fx_firmware, NULL);
>> +g_free(path);
>>   }
>>
> 
> Is it not worth adding an even more generic wrapper to prevent future
> desynch from our preferred path format?

As mentioned in the commit message, g_test_add() is a macro, not a
function, so seemed more complicated to wrap. Can you post a patch if
you have an idea? :)

>>   static void request_bios(FirmwareTestFixture *fixture,
>> @@ -408,8 +410,8 @@ int main(int argc, char **argv)
>>
>>   data.num_cpus = 1;
>>
>> -g_test_add_data_func("/i440fx/defaults", &data,
>> test_i440fx_defaults);
>> -g_test_add_data_func("/i440fx/pam", &data, test_i440fx_pam);
>> +qtest_add_data_func("i440fx/defaults", &data, test_i440fx_defaults);
>> +qtest_add_data_func("i440fx/pam", &data, test_i440fx_pam);
>>   add_firmware_test("/i440fx/firmware/bios", request_bios);
>>   add_firmware_test("/i440fx/firmware/pflash", request_pflash);
>>
>>
> 
> Similar to above, is it worth replacing other test's usage of
> g_test_add_data_func to force this standard path format everywhere?

I reviewed the test output from -rc0 while going through test failures.
fw_cfg-test and i440fx-test were the only nits I found. I wondered
whether we might poison the g_test_* versions or convert the other
tests, but did not want to unnecessarily risk this for 2.3.

Another issue that I've come across is that several tests misuse qmp(),
ignoring the return value instead of using qmp_discard_response().

Also I had the impression that my qom-test has noticeably degraded in
performance, and I wondered whether Paolo's changes to qmp(), parsing
the string argument into a QObject, might be to blame, given that a lot
of QMP qom-gets are performed by my test, and the number of objects and
properties tested keeps increasing (MemoryRegion, qemu_irq, machines).

Thanks a lot for your review.

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Jennifer Guild, Dilip Upmanyu,
Graham Norton; HRB 21284 (AG Nürnberg)



Re: [Qemu-devel] [PATCH] Haiku: Platform build fixes

2015-03-24 Thread Max Filippov
On Wed, Mar 25, 2015 at 2:03 AM, François Revol  wrote:
> On 24/03/2015 23:56, Max Filippov wrote:
>> On Wed, Mar 25, 2015 at 1:26 AM, Andreas Färber  wrote:
>>> Am 24.03.2015 um 00:36 schrieb Alexander von Gluck IV:

>>>
>>> Why convert from array to switch statement? It looks like a very
>>> invasive change for no obvious reason.
>>
>> I'd be interested to know the reason too, but I'm OK with either way.
>
> Maybe because negative array indices are usually a bad idea in C?

Sounds like a good reason (:

> Are the host errno codes used there actually?

Yes.

-- 
Thanks.
-- Max



Re: [Qemu-devel] [PATCH for-2.3 2/2] i440fx-test: Fix test paths to include architecture

2015-03-24 Thread John Snow



On 03/24/2015 06:45 PM, Andreas Färber wrote:

Replace g_test_add_func() with new qtest_add_func() and modify the path
passed to g_test_add() macro.

Signed-off-by: Andreas Färber 
---
  tests/i440fx-test.c | 8 +---
  1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/tests/i440fx-test.c b/tests/i440fx-test.c
index a3f7279..bc3f54c 100644
--- a/tests/i440fx-test.c
+++ b/tests/i440fx-test.c
@@ -383,8 +383,10 @@ static void add_firmware_test(const char *testpath,
void (*setup_fixture)(FirmwareTestFixture *f,
  gconstpointer test_data))
  {
-g_test_add(testpath, FirmwareTestFixture, NULL, setup_fixture,
+char *path = g_strdup_printf("/%s%s", qtest_get_arch(), testpath);
+g_test_add(path, FirmwareTestFixture, NULL, setup_fixture,
 test_i440fx_firmware, NULL);
+g_free(path);
  }



Is it not worth adding an even more generic wrapper to prevent future 
desynch from our preferred path format?



  static void request_bios(FirmwareTestFixture *fixture,
@@ -408,8 +410,8 @@ int main(int argc, char **argv)

  data.num_cpus = 1;

-g_test_add_data_func("/i440fx/defaults", &data, test_i440fx_defaults);
-g_test_add_data_func("/i440fx/pam", &data, test_i440fx_pam);
+qtest_add_data_func("i440fx/defaults", &data, test_i440fx_defaults);
+qtest_add_data_func("i440fx/pam", &data, test_i440fx_pam);
  add_firmware_test("/i440fx/firmware/bios", request_bios);
  add_firmware_test("/i440fx/firmware/pflash", request_pflash);




Similar to above, is it worth replacing other test's usage of 
g_test_add_data_func to force this standard path format everywhere?


--js



Re: [Qemu-devel] [PATCH for-2.3] sparc: memory: Replace memory_region_init_ram with memory_region_allocate_system_memory

2015-03-24 Thread Andreas Färber
Am 24.03.2015 um 22:30 schrieb Dirk Müller:
> Commit 0b183fc871:"memory: move mem_path handling to
> memory_region_allocate_system_memory" split memory_region_init_ram and
> memory_region_init_ram_from_file. Also it moved mem-path handling a step
> up from memory_region_init_ram to memory_region_allocate_system_memory.
> 
> Therefore for any board that uses memory_region_init_ram directly,
> -mem-path is not supported.
> 
> Fix this by replacing memory_region_init_ram with
> memory_region_allocate_system_memory.
> 
> Signed-off-by: Dirk Mueller 
> ---
>  hw/sparc/leon3.c | 3 +--
>  hw/sparc/sun4m.c | 5 ++---
>  2 files changed, 3 insertions(+), 5 deletions(-)

Reviewed-by: Andreas Färber 

Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Jennifer Guild, Dilip Upmanyu,
Graham Norton; HRB 21284 (AG Nürnberg)



Re: [Qemu-devel] [PATCH v2 for-2.3] m68k: memory: Replace memory_region_init_ram with memory_region_allocate_system_memory

2015-03-24 Thread Andreas Färber
Am 24.03.2015 um 23:11 schrieb Dirk Müller:
> Commit 0b183fc871:"memory: move mem_path handling to
> memory_region_allocate_system_memory" split memory_region_init_ram and
> memory_region_init_ram_from_file. Also it moved mem-path handling a step
> up from memory_region_init_ram to memory_region_allocate_system_memory.
> 
> Therefore for any board that uses memory_region_init_ram directly,
> -mem-path is not supported.
> 
> Fix this by replacing memory_region_init_ram with
> memory_region_allocate_system_memory.
> 
> Signed-off-by: Dirk Mueller 
> ---
>  hw/m68k/an5206.c | 3 +--
>  hw/m68k/dummy_m68k.c | 4 ++--
>  hw/m68k/mcf5208.c| 3 +--
>  3 files changed, 4 insertions(+), 6 deletions(-)

Reviewed-by: Andreas Färber 

Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Jennifer Guild, Dilip Upmanyu,
Graham Norton; HRB 21284 (AG Nürnberg)



Re: [Qemu-devel] [PATCH for-2.3 1/2] qtest: Add qtest_add_data_func() wrapper function

2015-03-24 Thread John Snow



On 03/24/2015 06:45 PM, Andreas Färber wrote:

It calls g_test_add_data_func() with a path supplemented by the
architecture, like qtest_add_func() does.

Signed-off-by: Andreas Färber 
---
  tests/libqtest.c |  7 +++
  tests/libqtest.h | 12 
  2 files changed, 19 insertions(+)

diff --git a/tests/libqtest.c b/tests/libqtest.c
index 9a92aa7..e3f68d1 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -652,6 +652,13 @@ void qtest_add_func(const char *str, void (*fn))
  g_free(path);
  }

+void qtest_add_data_func(const char *str, void *data, void (*fn))
+{
+gchar *path = g_strdup_printf("/%s/%s", qtest_get_arch(), str);
+g_test_add_data_func(path, data, fn);
+g_free(path);
+}
+
  void qtest_memwrite(QTestState *s, uint64_t addr, const void *data, size_t 
size)
  {
  const uint8_t *ptr = data;
diff --git a/tests/libqtest.h b/tests/libqtest.h
index e7413d5..e363f7f 100644
--- a/tests/libqtest.h
+++ b/tests/libqtest.h
@@ -345,6 +345,18 @@ const char *qtest_get_arch(void);
  void qtest_add_func(const char *str, void (*fn));

  /**
+ * qtest_add_data_func:
+ * @str: Test case path.
+ * @data: Test case data
+ * @fn: Test case function
+ *
+ * Add a GTester testcase with the given name, data and function.
+ * The path is prefixed with the architecture under test, as
+ * returned by qtest_get_arch().
+ */
+void qtest_add_data_func(const char *str, void *data, void (*fn));
+
+/**
   * qtest_start:
   * @args: other arguments to pass to QEMU
   *



Reviewed-by: John Snow 



Re: [Qemu-devel] [PATCH] Haiku: Platform build fixes

2015-03-24 Thread François Revol
On 24/03/2015 23:56, Max Filippov wrote:
> On Wed, Mar 25, 2015 at 1:26 AM, Andreas Färber  wrote:
>> Am 24.03.2015 um 00:36 schrieb Alexander von Gluck IV:
>>>
>>
>> Why convert from array to switch statement? It looks like a very
>> invasive change for no obvious reason.
> 
> I'd be interested to know the reason too, but I'm OK with either way.

Maybe because negative array indices are usually a bad idea in C?
Are the host errno codes used there actually?

François.



Re: [Qemu-devel] [PATCH for-2.3] mips: memory: Replace memory_region_init_ram with memory_region_allocate_system_memory

2015-03-24 Thread Andreas Färber
Am 24.03.2015 um 22:28 schrieb Dirk Müller:
> Commit 0b183fc871:"memory: move mem_path handling to
> memory_region_allocate_system_memory" split memory_region_init_ram and
> memory_region_init_ram_from_file. Also it moved mem-path handling a step
> up from memory_region_init_ram to memory_region_allocate_system_memory.
> 
> Therefore for any board that uses memory_region_init_ram directly,
> -mem-path is not supported.
> 
> Fix this by replacing memory_region_init_ram with
> memory_region_allocate_system_memory.
> 
> Signed-off-by: Dirk Mueller 
> ---
>  hw/mips/mips_fulong2e.c | 3 +--
>  hw/mips/mips_jazz.c | 5 ++---
>  hw/mips/mips_malta.c| 5 ++---
>  hw/mips/mips_mipssim.c  | 5 ++---
>  hw/mips/mips_r4k.c  | 3 +--
>  5 files changed, 8 insertions(+), 13 deletions(-)

Reviewed-by: Andreas Färber 

Leon and Paolo, I assume one of you will be handling this?

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Jennifer Guild, Dilip Upmanyu,
Graham Norton; HRB 21284 (AG Nürnberg)



Re: [Qemu-devel] [PATCH] Haiku: Platform build fixes

2015-03-24 Thread Max Filippov
On Wed, Mar 25, 2015 at 1:26 AM, Andreas Färber  wrote:
> Am 24.03.2015 um 00:36 schrieb Alexander von Gluck IV:
>>
>> diff --git a/target-xtensa/xtensa-semi.c b/target-xtensa/xtensa-semi.c
>> index 16e9d8c..d0ea12a 100644
>> --- a/target-xtensa/xtensa-semi.c
>> +++ b/target-xtensa/xtensa-semi.c
>> @@ -95,59 +95,53 @@ enum {
>>
>>  static uint32_t errno_h2g(int host_errno)
>>  {
>> -static const uint32_t guest_errno[] = {
>> -[EPERM] = TARGET_EPERM,
>> -[ENOENT]= TARGET_ENOENT,
>> -[ESRCH] = TARGET_ESRCH,
>> -[EINTR] = TARGET_EINTR,
>> -[EIO]   = TARGET_EIO,
>> -[ENXIO] = TARGET_ENXIO,
>> -[E2BIG] = TARGET_E2BIG,
>> -[ENOEXEC]   = TARGET_ENOEXEC,
>> -[EBADF] = TARGET_EBADF,
>> -[ECHILD]= TARGET_ECHILD,
>> -[EAGAIN]= TARGET_EAGAIN,
>> -[ENOMEM]= TARGET_ENOMEM,
>> -[EACCES]= TARGET_EACCES,
>> -[EFAULT]= TARGET_EFAULT,
>> +switch (host_errno) {
>> +case 0: return 0;
>> +case EPERM: return TARGET_EPERM;
>> +case ENOENT: return TARGET_ENOENT;
>> +case ESRCH: return TARGET_ESRCH;
>> +case EINTR: return TARGET_EINTR;
>> +case EIO: return TARGET_EIO;
>> +case ENXIO: return TARGET_ENXIO;
>> +case E2BIG: return TARGET_E2BIG;
>> +case ENOEXEC: return TARGET_ENOEXEC;
>> +case EBADF: return TARGET_EBADF;
>> +case ECHILD: return TARGET_ECHILD;
>> +case EAGAIN: return TARGET_EAGAIN;
>> +case ENOMEM: return TARGET_ENOMEM;
>> +case EACCES: return TARGET_EACCES;
>> +case EFAULT: return TARGET_EFAULT;
>>  #ifdef ENOTBLK
>> -[ENOTBLK]   = TARGET_ENOTBLK,
>> +case ENOTBLK: return TARGET_ENOTBLK;
>>  #endif
>> -[EBUSY] = TARGET_EBUSY,
>> -[EEXIST]= TARGET_EEXIST,
>> -[EXDEV] = TARGET_EXDEV,
>> -[ENODEV]= TARGET_ENODEV,
>> -[ENOTDIR]   = TARGET_ENOTDIR,
>> -[EISDIR]= TARGET_EISDIR,
>> -[EINVAL]= TARGET_EINVAL,
>> -[ENFILE]= TARGET_ENFILE,
>> -[EMFILE]= TARGET_EMFILE,
>> -[ENOTTY]= TARGET_ENOTTY,
>> +case EBUSY: return TARGET_EBUSY;
>> +case EEXIST: return TARGET_EEXIST;
>> +case EXDEV: return TARGET_EXDEV;
>> +case ENODEV: return TARGET_ENODEV;
>> +case ENOTDIR: return TARGET_ENOTDIR;
>> +case EISDIR: return TARGET_EISDIR;
>> +case EINVAL: return TARGET_EINVAL;
>> +case ENFILE: return TARGET_ENFILE;
>> +case EMFILE: return TARGET_EMFILE;
>> +case ENOTTY: return TARGET_ENOTTY;
>
> Why convert from array to switch statement? It looks like a very
> invasive change for no obvious reason.

I'd be interested to know the reason too, but I'm OK with either way.

>>  #ifdef ETXTBSY
>> -[ETXTBSY]   = TARGET_ETXTBSY,
>> +case ETXTBSY: return TARGET_ETXTBSY;
>>  #endif
>> -[EFBIG] = TARGET_EFBIG,
>> -[ENOSPC]= TARGET_ENOSPC,
>> -[ESPIPE]= TARGET_ESPIPE,
>> -[EROFS] = TARGET_EROFS,
>> -[EMLINK]= TARGET_EMLINK,
>> -[EPIPE] = TARGET_EPIPE,
>> -[EDOM]  = TARGET_EDOM,
>> -[ERANGE]= TARGET_ERANGE,
>> -[ENOSYS]= TARGET_ENOSYS,
>> +case EFBIG: return TARGET_EFBIG;
>> +case ENOSPC: return TARGET_ENOSPC;
>> +case ESPIPE: return TARGET_ESPIPE;
>> +case EROFS: return TARGET_EROFS;
>> +case EMLINK: return TARGET_EMLINK;
>> +case EPIPE: return TARGET_EPIPE;
>> +case EDOM: return TARGET_EDOM;
>> +case ERANGE: return TARGET_ERANGE;
>> +case ENOSYS: return TARGET_ENOSYS;
>>  #ifdef ELOOP
>> -[ELOOP] = TARGET_ELOOP,
>> +case ELOOP: return TARGET_ELOOP;
>>  #endif
>>  };

No need for semicolon here.

-- 
Thanks.
-- Max



[Qemu-devel] [PATCH for-2.3 2/2] i440fx-test: Fix test paths to include architecture

2015-03-24 Thread Andreas Färber
Replace g_test_add_func() with new qtest_add_func() and modify the path
passed to g_test_add() macro.

Signed-off-by: Andreas Färber 
---
 tests/i440fx-test.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/tests/i440fx-test.c b/tests/i440fx-test.c
index a3f7279..bc3f54c 100644
--- a/tests/i440fx-test.c
+++ b/tests/i440fx-test.c
@@ -383,8 +383,10 @@ static void add_firmware_test(const char *testpath,
   void (*setup_fixture)(FirmwareTestFixture *f,
 gconstpointer test_data))
 {
-g_test_add(testpath, FirmwareTestFixture, NULL, setup_fixture,
+char *path = g_strdup_printf("/%s%s", qtest_get_arch(), testpath);
+g_test_add(path, FirmwareTestFixture, NULL, setup_fixture,
test_i440fx_firmware, NULL);
+g_free(path);
 }
 
 static void request_bios(FirmwareTestFixture *fixture,
@@ -408,8 +410,8 @@ int main(int argc, char **argv)
 
 data.num_cpus = 1;
 
-g_test_add_data_func("/i440fx/defaults", &data, test_i440fx_defaults);
-g_test_add_data_func("/i440fx/pam", &data, test_i440fx_pam);
+qtest_add_data_func("i440fx/defaults", &data, test_i440fx_defaults);
+qtest_add_data_func("i440fx/pam", &data, test_i440fx_pam);
 add_firmware_test("/i440fx/firmware/bios", request_bios);
 add_firmware_test("/i440fx/firmware/pflash", request_pflash);
 
-- 
2.1.4




Re: [Qemu-devel] [PATCH 1/5] block: allow block jobs in any arbitrary node

2015-03-24 Thread Eric Blake
On 03/23/2015 09:12 AM, Alberto Garcia wrote:
> Currently, block jobs can only be owned by root nodes. This patch
> allows block jobs to be in any arbitrary node, by making the following
> changes:
> 
> - Block jobs can now be identified by the node name of their
>   BlockDriverState in addition to the device name. Since both device
>   and node names live in the same namespace there's no ambiguity.
> 
> - The "device" parameter used by all commands that operate on block
>   jobs can also be a node name now.
> 
> - The node name is used as a fallback to fill in the BlockJobInfo
>   structure and all BLOCK_JOB_* events if there is no device name for
>   that job.
> 
> - When querying the list of existing block jobs, all nodes are
>   searched, not just the ones at the root.
> 
> Signed-off-by: Alberto Garcia 
> ---

Reviewed-by: Eric Blake 

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



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PATCH for-2.3 1/2] qtest: Add qtest_add_data_func() wrapper function

2015-03-24 Thread Andreas Färber
It calls g_test_add_data_func() with a path supplemented by the
architecture, like qtest_add_func() does.

Signed-off-by: Andreas Färber 
---
 tests/libqtest.c |  7 +++
 tests/libqtest.h | 12 
 2 files changed, 19 insertions(+)

diff --git a/tests/libqtest.c b/tests/libqtest.c
index 9a92aa7..e3f68d1 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -652,6 +652,13 @@ void qtest_add_func(const char *str, void (*fn))
 g_free(path);
 }
 
+void qtest_add_data_func(const char *str, void *data, void (*fn))
+{
+gchar *path = g_strdup_printf("/%s/%s", qtest_get_arch(), str);
+g_test_add_data_func(path, data, fn);
+g_free(path);
+}
+
 void qtest_memwrite(QTestState *s, uint64_t addr, const void *data, size_t 
size)
 {
 const uint8_t *ptr = data;
diff --git a/tests/libqtest.h b/tests/libqtest.h
index e7413d5..e363f7f 100644
--- a/tests/libqtest.h
+++ b/tests/libqtest.h
@@ -345,6 +345,18 @@ const char *qtest_get_arch(void);
 void qtest_add_func(const char *str, void (*fn));
 
 /**
+ * qtest_add_data_func:
+ * @str: Test case path.
+ * @data: Test case data
+ * @fn: Test case function
+ *
+ * Add a GTester testcase with the given name, data and function.
+ * The path is prefixed with the architecture under test, as
+ * returned by qtest_get_arch().
+ */
+void qtest_add_data_func(const char *str, void *data, void (*fn));
+
+/**
  * qtest_start:
  * @args: other arguments to pass to QEMU
  *
-- 
2.1.4




[Qemu-devel] [PATCH for-2.3 0/2] qtest: Fix remaining test paths to include architecture

2015-03-24 Thread Andreas Färber
Hello,

This mini-series is a follow-up, fixing the last remaining GTester paths
to indicate the architecture they are executed for (i386 vs. x86_64).

Unlike the previous patch, there is no libqtest wrapper function adding the
architecture yet; other tests manually constructed a correct path to pass to
g_test_add_data_func(). For convenience, add such a helper function.

Based on "[PATCH for-2.3] fw_cfg-test: Fix test path to include architecture",
which missed -rc1. If there's no objection, I'll put these in a pull for -rc2.

Regards,
Andreas

Andreas Färber (2):
  qtest: Add qtest_add_data_func() wrapper function
  i440fx-test: Fix test paths to include architecture

 tests/i440fx-test.c |  8 +---
 tests/libqtest.c|  7 +++
 tests/libqtest.h| 12 
 3 files changed, 24 insertions(+), 3 deletions(-)

-- 
2.1.4




Re: [Qemu-devel] [PATCH v5 20/45] Modify savevm handlers for postcopy

2015-03-24 Thread David Gibson
On Tue, Mar 24, 2015 at 08:04:14PM +, Dr. David Alan Gilbert wrote:
> * David Gibson (da...@gibson.dropbear.id.au) wrote:
> > On Fri, Mar 20, 2015 at 12:37:59PM +, Dr. David Alan Gilbert wrote:
> > > * David Gibson (da...@gibson.dropbear.id.au) wrote:
> > > > On Fri, Mar 13, 2015 at 10:19:54AM +, Dr. David Alan Gilbert wrote:
> > > > > * David Gibson (da...@gibson.dropbear.id.au) wrote:
> > > > > > On Wed, Feb 25, 2015 at 04:51:43PM +, Dr. David Alan Gilbert 
> > > > > > (git) wrote:
> > > > > > > From: "Dr. David Alan Gilbert" 
> > > > > > > 
> > > > > > > Modify save_live_pending to return separate postcopiable and
> > > > > > > non-postcopiable counts.
> > > > > > > 
> > > > > > > Add 'can_postcopy' to allow a device to state if it can postcopy
> > > > > > 
> > > > > > What's the purpose of the can_postcopy callback?  There are no 
> > > > > > callers
> > > > > > in this patch - is it still necessary with the change to
> > > > > > save_live_pending?
> > > > > 
> > > > > The patch 'qemu_savevm_state_complete: Postcopy changes' uses
> > > > > it in qemu_savevm_state_postcopy_complete and 
> > > > > qemu_savevm_state_complete
> > > > > to decide which devices must be completed at that point.
> > > > 
> > > > Couldn't they check for non-zero postcopiable state from
> > > > save_live_pending instead?
> > > 
> > > That would be a bit weird.
> > > 
> > > At the moment for each device we call the:
> > >save_live_setup method (from qemu_savevm_state_begin)
> > > 
> > >0...multiple times we call:
> > >save_live_pending
> > >save_live_iterate
> > > 
> > >and then we always call
> > >save_live_complete
> > > 
> > > 
> > > To my mind we have to call save_live_complete for any device
> > > that we've called save_live_setup on (maybe it allocated something
> > > in _setup that it clears up in _complete).
> > > 
> > > save_live_pending could perfectly well return 0 remaining at the end of
> > > the migrate for our device, and thus if we used that then we wouldn't
> > > call save_live_complete.
> > 
> > Um.. I don't follow.  I was suggesting that at the precopy->postcopy
> > transition point you call save_live_complete for everything that
> > reports 0 post-copiable state.
> > 
> > 
> > Then again, a different approach would be to split the
> > save_live_complete hook into (possibly NULL) "complete precopy" and
> > "complete postcopy" hooks.  The core would ensure that every chunk of
> > state has both completion hooks called (unless NULL).  That might also
> > address my concerns about the no longer entirely accurate
> > save_live_complete function name.
> 
> OK, that one I prefer.  Are you OK with:
> qemu_savevm_state_complete_precopy
>calls -> save_live_complete_precopy
> 
> qemu_savevm_state_complete_postcopy
>calls -> save_live_complete_postcopy
> 
> ?

Sounds ok to me.  Fwiw, I was thinking that both the complete_precopy
and complete_postcopy hooks should always be called.  For a
non-postcopy migration, the postcopy hooks would just be called
immediately after the precopy hooks.

-- 
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


pgpDGzYOL0FAj.pgp
Description: PGP signature


Re: [Qemu-devel] [PATCH] Haiku: Platform build fixes

2015-03-24 Thread Andreas Färber
Hi Alexander,

Am 24.03.2015 um 00:36 schrieb Alexander von Gluck IV:
> * skip syscall.h on Haiku
> * skip signal.h on Haiku
> * no daemon function
> * only attach SIGIO when it exists
> * use termios.h on Haiku

We cannot accept patches without Signed-off-by, indicating that this
code is either from you or someone who has signed it off before you
according to the DCO.

That is, if you took this patch from HaikuPorts, you'll need to track
down who wrote which parts of this and get them to sign off before
resubmitting here. Michael Lotz never responded after posting the
previous big patch.

> ---
>  main-loop.c |2 +
>  os-posix.c  |4 ++
>  target-xtensa/xtensa-semi.c |   84 
> ---
>  tests/Makefile  |2 +-
>  util/compatfd.c |2 +
>  util/oslib-posix.c  |7 
>  util/qemu-openpty.c |4 ++-
>  7 files changed, 58 insertions(+), 47 deletions(-)

Can you split this up into a series of smaller patches? That'll make it
easier to start applying fixes.

You also forgot to CC the Xtensa maintainer whose code you are touching.

> 
> diff --git a/main-loop.c b/main-loop.c
> index 981bcb5..947d7cd 100644
> --- a/main-loop.c
> +++ b/main-loop.c
> @@ -81,7 +81,9 @@ static int qemu_signal_init(void)
>   */
>  sigemptyset(&set);
>  sigaddset(&set, SIG_IPI);
> +#ifdef SIGIO

Unless there is precedent (which I doubt), do not indent #ifdefs beyond
recognition.

>  sigaddset(&set, SIGIO);
> +#endif
>  sigaddset(&set, SIGALRM);
>  sigaddset(&set, SIGBUS);
>  /* SIGINT cannot be handled via signalfd, so that ^C can be used

Otherwise this hunk looks okay.

> diff --git a/os-posix.c b/os-posix.c
> index ba091f1..43f7fec 100644
> --- a/os-posix.c
> +++ b/os-posix.c
> @@ -323,6 +323,9 @@ bool is_daemonized(void)
>  
>  int os_mlock(void)
>  {
> +#if defined(CONFIG_HAIKU)
> +return ENOSYS;

So Haiku does not implement mlock*? That should be explained in the
commit message.

Are you sure that ENOSYS is correct here as opposed to -ENOSYS? :)
BeOS used negative E* codes, POSIX uses positive ones - or the other way
around - and to complicate the matter further, Ingo had written some
Haiku library hack to translate between both versions...

> +#else
>  int ret = 0;
>  
>  ret = mlockall(MCL_CURRENT | MCL_FUTURE);
> @@ -331,4 +334,5 @@ int os_mlock(void)
>  }
>  
>  return ret;
> +#endif
>  }
> diff --git a/target-xtensa/xtensa-semi.c b/target-xtensa/xtensa-semi.c
> index 16e9d8c..d0ea12a 100644
> --- a/target-xtensa/xtensa-semi.c
> +++ b/target-xtensa/xtensa-semi.c
> @@ -95,59 +95,53 @@ enum {
>  
>  static uint32_t errno_h2g(int host_errno)
>  {
> -static const uint32_t guest_errno[] = {
> -[EPERM] = TARGET_EPERM,
> -[ENOENT]= TARGET_ENOENT,
> -[ESRCH] = TARGET_ESRCH,
> -[EINTR] = TARGET_EINTR,
> -[EIO]   = TARGET_EIO,
> -[ENXIO] = TARGET_ENXIO,
> -[E2BIG] = TARGET_E2BIG,
> -[ENOEXEC]   = TARGET_ENOEXEC,
> -[EBADF] = TARGET_EBADF,
> -[ECHILD]= TARGET_ECHILD,
> -[EAGAIN]= TARGET_EAGAIN,
> -[ENOMEM]= TARGET_ENOMEM,
> -[EACCES]= TARGET_EACCES,
> -[EFAULT]= TARGET_EFAULT,
> +switch (host_errno) {
> +case 0: return 0;
> +case EPERM: return TARGET_EPERM;
> +case ENOENT: return TARGET_ENOENT;
> +case ESRCH: return TARGET_ESRCH;
> +case EINTR: return TARGET_EINTR;
> +case EIO: return TARGET_EIO;
> +case ENXIO: return TARGET_ENXIO;
> +case E2BIG: return TARGET_E2BIG;
> +case ENOEXEC: return TARGET_ENOEXEC;
> +case EBADF: return TARGET_EBADF;
> +case ECHILD: return TARGET_ECHILD;
> +case EAGAIN: return TARGET_EAGAIN;
> +case ENOMEM: return TARGET_ENOMEM;
> +case EACCES: return TARGET_EACCES;
> +case EFAULT: return TARGET_EFAULT;
>  #ifdef ENOTBLK
> -[ENOTBLK]   = TARGET_ENOTBLK,
> +case ENOTBLK: return TARGET_ENOTBLK;
>  #endif
> -[EBUSY] = TARGET_EBUSY,
> -[EEXIST]= TARGET_EEXIST,
> -[EXDEV] = TARGET_EXDEV,
> -[ENODEV]= TARGET_ENODEV,
> -[ENOTDIR]   = TARGET_ENOTDIR,
> -[EISDIR]= TARGET_EISDIR,
> -[EINVAL]= TARGET_EINVAL,
> -[ENFILE]= TARGET_ENFILE,
> -[EMFILE]= TARGET_EMFILE,
> -[ENOTTY]= TARGET_ENOTTY,
> +case EBUSY: return TARGET_EBUSY;
> +case EEXIST: return TARGET_EEXIST;
> +case EXDEV: return TARGET_EXDEV;
> +case ENODEV: return TARGET_ENODEV;
> +case ENOTDIR: return TARGET_ENOTDIR;
> +case EISDIR: return TARGET_EISDIR;
> +case EINVAL: return TARGET_EINVAL;
> +case ENFILE: r

[Qemu-devel] virtconsole migration regression from 2.2.0

2015-03-24 Thread Cole Robinson
I'm hitting an error migrating from stock v2.2.0 to git master:

2015-03-24T21:42:07.731317Z qemu-system-x86_64: error while loading state for
instance 0x0 of device ':00:05.0/virtio-console'
2015-03-24T21:42:07.731392Z qemu-system-x86_64: load of migration failed:
Invalid argument

I'm using libvirt's managedsave, which is migrate to/from file. I bisected to
this commit:

commit 9b70c1790acacae54d559d38ca69186a85040bb8
Author: Michael S. Tsirkin 
Date:   Mon Feb 16 22:36:26 2015 +0100

virtio-serial: switch to standard-headers

Problem seems to be that the old virtio_console_config structure was
different, missing the emerg_wr field. If I apply this patch:

diff --git a/include/standard-headers/linux/virtio_console.h
b/include/standard-headers/linux/virtio_console.h
index 0dedc9e..242a0c5 100644
--- a/include/standard-headers/linux/virtio_console.h
+++ b/include/standard-headers/linux/virtio_console.h
@@ -50,8 +50,6 @@ struct virtio_console_config {
uint16_t rows;
/* max. number of ports this device can hold */
uint32_t max_nr_ports;
-   /* emergency write register */
-   uint32_t emerg_wr;
 } QEMU_PACKED;


My VMs restore correctly. I assume that change isn't acceptable as-is though...

Here's the massive libvirt command line:

/home/crobinso/src/qemu/x86_64-softmmu/qemu-system-x86_64 -name
migrateion-tester.py-vm -S -machine pc-i440fx-2.2,accel=kvm,usb=off -cpu
Opteron_G4,+nodeid_msr,+wdt,+skinit,+ibs,+osvw,+cr8legacy,+extapic,+cmp_legacy,+fxsr_opt,+mmxext,+osxsave,+monitor,+ht,+vme
-m 2048 -realtime mlock=off -smp 2,sockets=2,cores=1,threads=1 -uuid
ce2a1280-78e5-7233-3f67-139dfedfdfe9 -no-user-config -nodefaults -chardev
socket,id=charmonitor,path=/var/lib/libvirt/qemu/migrateion-tester.py-vm.monitor,server,nowait
-mon chardev=charmonitor,id=monitor,mode=control -rtc base=utc -no-shutdown
-boot strict=on -device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 -device
virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x5 -drive
file=/mnt/data/devel/images/ztester-f18-migrate-overlay.qcow2,if=none,id=drive-virtio-disk0,format=qcow2
-device
virtio-blk-pci,scsi=off,bus=pci.0,addr=0x6,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1
-netdev tap,fd=27,id=hostnet0,vhost=on,vhostfd=28 -device
virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:40:ee:0b,bus=pci.0,addr=0x3 
-chardev
spicevmc,id=charchannel0,name=vdagent -device
virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=com.redhat.spice.0
-chardev pty,id=charconsole0 -device
virtconsole,chardev=charconsole0,id=console0 -device usb-tablet,id=input0
-spice
port=5901,tls-port=5902,addr=127.0.0.1,disable-ticketing,x509-dir=/etc/pki/libvirt-spice,seamless-migration=on
-device
qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,vgamem_mb=16,bus=pci.0,addr=0x2
-device intel-hda,id=sound0,bus=pci.0,addr=0x4 -device
hda-duplex,id=sound0-codec0,bus=sound0.0,cad=0 -incoming fd:24 -device
virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x7 -snapshot -msg timestamp=on


I tried to reduce it to a minimal reproducer but I couldn't trigger it, but I
didn't try too long. I can test any proposed fix though.

Thanks,
Cole



[Qemu-devel] [ANNOUNCE] QEMU 2.3.0-rc1 is now available

2015-03-24 Thread Michael Roth
Hello,

On behalf of the QEMU Team, I'd like to announce the availability of the
second release candidate for the QEMU 2.3 release.  This release is meant
for testing purposes and should not be used in a production environment.

  http://wiki.qemu.org/download/qemu-2.3.0-rc1.tar.bz2

We're currently aware of issue an involving VNC disconnects due to a
recent CVE fix. This will likely be addressed in a follow-up.

  https://bugs.launchpad.net/qemu/

The release plan for the 2.3 release is available at:

  http://wiki.qemu.org/Planning/2.3

Please add entries to the ChangeLog for the 2.3 release below:

  http://wiki.qemu.org/ChangeLog/2.3

Changes since 2.3.0-rc0:

054903a: Update version for v2.3.0-rc1 release (Peter Maydell)
f69c24e: target-tricore: properly fix dvinit_b/h_13 (Bastian Koppelmann)
00e1754: target-tricore: fix RRPW_DEXTR using wrong reg (Bastian Koppelmann)
2b9d09b: target-tricore: fix DVINIT_HU/BU calculating overflow before result 
(Bastian Koppelmann)
30a0d72: target-tricore: Fix two helper functions (clang warnings) (Stefan Weil)
54fced0: ahci-test: improve rw buffer patterns (John Snow)
ac38123: ahci: Fix sglist offset manipulation for BE machines (John Snow)
dd0bf7b: ide: fix cmd_read_pio when nsectors > 1 (John Snow)
6aff22c: ide: fix cmd_write_pio when nsectors > 1 (John Snow)
61c7480: linux-user: fix broken cpu_copy() (Leon Alrae)
17644b3: linux-user: fix emulation of splice syscall (Andreas Schwab)
92bed46: linux-user/main.c: Remove redundant end_exclusive() in 
arm_kernel_cmpxchg64_helper() (Chen Gang S)
4e289b1: ehci: fix segfault when hot-unplugging ehci controller (Gonglei)
88dd1b8: ohci: fix resource cleanup leak (Gonglei)
537e572: uhci: fix segfault when hot-unplugging uhci controller (Gonglei)
a356850: target-i386: Haswell-noTSX and Broadwell-noTSX (Eduardo Habkost)
1ee9159: Revert "target-i386: Disable HLE and RTM on Haswell & Broadwell" 
(Eduardo Habkost)
549fc54: numa: Print warning if no node is assigned to a CPU (Eduardo Habkost)
fb43b73: pc: fix default VCPU to NUMA node mapping (Igor Mammedov)
57924bc: numa: introduce machine callback for VCPU to node mapping (Igor 
Mammedov)
3ef7197: numa: Reject configuration if CPU appears on multiple nodes (Eduardo 
Habkost)
8979c94: numa: Reject CPU indexes > max_cpus (Eduardo Habkost)
ed26b92: numa: Fix off-by-one error at MAX_CPUMASK_BITS check (Eduardo Habkost)
5b347c5: block: Fix blockdev-backup not to use funky error class (Markus 
Armbruster)
4add73a: virtio: serial: expose a 'guest_writable' callback for users (Amit 
Shah)
9651825: raw-posix: Deprecate aio=threads fallback without O_DIRECT (Kevin Wolf)
92a539d: raw-posix: Deprecate host floppy passthrough (Markus Armbruster)
8ce1ee4: qga/commands-posix: Fix resource leak (Shannon Zhao)
23bf2e7: elf-loader: Add missing error handling for call of lseek (Stefan Weil)
6cbfb86: elf-loader: Fix truncation warning from coverity (Stefan Weil)
b76d799: hmp: Fix texinfo documentation (Markus Armbruster)
de7ad4c: Fix typos in comments (Viswesh)
7e7d49d: qtest/ahci: Fix a bit mask expression (John Snow)
636a30a: vl: fix resource leak with monitor_fdset_add_fd (Paolo Bonzini)
3ebd6cc: smbios: add max speed comdline option for type-17 (meory device) 
structure (Gabriel L. Somlo)
bdd0977: pc-dimm: Add description for device list. (Paulo Vital)
18b8263: configure: enable kvm on x32 (Michael Tokarev)
1986754: error: Replace error_report() & error_free() with error_report_err() 
(zhanghailiang)
6e05a12: arm: fix memory leak (Gonglei)
293811f: qmp: Drop unused .user_print from command definitions (Markus 
Armbruster)
46db7b8: hmp: Fix definition of command quit (Markus Armbruster)
6093d01: target-moxie: Fix warnings from Sparse (one-bit signed bitfield) 
(Stefan Weil)
2c20fa2: block/qapi: Fix Sparse warning (Stefan Weil)
e7ae771: Fix remaining warnings from Sparse (void return) (Stefan Weil)
fbe95bf: qom: Fix warning from Sparse (Stefan Weil)
327e975: target-mips: Fix warning from Sparse (Stefan Weil)
30d76f1: arm/nseries: Fix warnings from Sparse (Stefan Weil)
77a8257: omap: Fix warnings from Sparse (Stefan Weil)
0289a41: 9pfs: Fix warnings from Sparse (Stefan Weil)
9c80d95: backends: Fix warning from Sparse (Stefan Weil)
302cb24: cris: remove unused cris_cond15 declarations (Michael Tokarev)
ce39494: pcie_aer: fix comment to match pcie spec (Michael S. Tsirkin)
98a2f30: pci: fix several trivial typos in comment (Chen Fan)
310e91f: aer: fix a wrong init PCI_ERR_COR_STATUS w1cmask type register (Chen 
Fan)
b01738c: pcie_aer: fix typos in pcie_aer_inject_error comment (Chen Fan)
77a3c1d: aer: fix wrong check on expose aer tlp prefix log (Chen Fan)
30b04f8: pcie: correct mistaken register bit for End-End TLP Prefix Blocking 
(Chen Fan)
c3c1bb9: exec: Respect as_tranlsate_internal length clamp (Peter Crosthwaite)
196d4fc: virtio-scsi-dataplane: fix memory leak in virtio_scsi_vring_init (Bo 
Su)
89d5cbd: profiler: Reenable built-in profiler (Alexey Kardashevskiy)
b680c5b: kvm: fix ioeventfd end

[Qemu-devel] [PATCH v2 for-2.3] m68k: memory: Replace memory_region_init_ram with memory_region_allocate_system_memory

2015-03-24 Thread Dirk Müller
Commit 0b183fc871:"memory: move mem_path handling to
memory_region_allocate_system_memory" split memory_region_init_ram and
memory_region_init_ram_from_file. Also it moved mem-path handling a step
up from memory_region_init_ram to memory_region_allocate_system_memory.

Therefore for any board that uses memory_region_init_ram directly,
-mem-path is not supported.

Fix this by replacing memory_region_init_ram with
memory_region_allocate_system_memory.

Signed-off-by: Dirk Mueller 
---
 hw/m68k/an5206.c | 3 +--
 hw/m68k/dummy_m68k.c | 4 ++--
 hw/m68k/mcf5208.c| 3 +--
 3 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/hw/m68k/an5206.c b/hw/m68k/an5206.c
index f1f1350..f63ab2b 100644
--- a/hw/m68k/an5206.c
+++ b/hw/m68k/an5206.c
@@ -50,8 +50,7 @@ static void an5206_init(MachineState *machine)
 env->rambar0 = AN5206_RAMBAR_ADDR | 1;

 /* DRAM at address zero */
-memory_region_init_ram(ram, NULL, "an5206.ram", ram_size, &error_abort);
-vmstate_register_ram_global(ram);
+memory_region_allocate_system_memory(ram, NULL, "an5206.ram", ram_size);
 memory_region_add_subregion(address_space_mem, 0, ram);

 /* Internal SRAM.  */
diff --git a/hw/m68k/dummy_m68k.c b/hw/m68k/dummy_m68k.c
index 278f4c0..5b77d93 100644
--- a/hw/m68k/dummy_m68k.c
+++ b/hw/m68k/dummy_m68k.c
@@ -42,8 +42,8 @@ static void dummy_m68k_init(MachineState *machine)
 env->vbr = 0;

 /* RAM at address zero */
-memory_region_init_ram(ram, NULL, "dummy_m68k.ram", ram_size,
&error_abort);
-vmstate_register_ram_global(ram);
+memory_region_allocate_system_memory(ram, NULL, "dummy_m68k.ram",
+ ram_size);
 memory_region_add_subregion(address_space_mem, 0, ram);

 /* Load kernel.  */
diff --git a/hw/m68k/mcf5208.c b/hw/m68k/mcf5208.c
index a01a445..326a42d 100644
--- a/hw/m68k/mcf5208.c
+++ b/hw/m68k/mcf5208.c
@@ -218,8 +218,7 @@ static void mcf5208evb_init(MachineState *machine)
 /* TODO: Configure BARs.  */

 /* DRAM at 0x4000 */
-memory_region_init_ram(ram, NULL, "mcf5208.ram", ram_size, &error_abort);
-vmstate_register_ram_global(ram);
+memory_region_allocate_system_memory(ram, NULL, "mcf5208.ram", ram_size);
 memory_region_add_subregion(address_space_mem, 0x4000, ram);

 /* Internal SRAM.  */
-- 
2.0.4



Re: [Qemu-devel] [PATCH for-2.3] arm: memory: Replace memory_region_init_ram with memory_region_allocate_system_memory

2015-03-24 Thread Dirk Müller
Hi Paolo,

> You cannot call memory_region_allocate_system_memory twice.  For cases
> like this one, the right thing to do is to create a region with
> memory_region_allocate_system_memory, and then replace
> memory_region_init_ram with memory_region_init_alias.  This "slices" the
> region created by memory_region_allocate_system_memory.

Thanks for the review and the explanation. Like this?

--- a/hw/arm/exynos4210.c
+++ b/hw/arm/exynos4210.c
@@ -144,6 +144,7 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
 DeviceState *dev;
 SysBusDevice *busdev;
 ObjectClass *cpu_oc;
+MemoryRegion *ram_all = g_new(MemoryRegion, 1);

 cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, "cortex-a9");
 assert(cpu_oc);
@@ -281,18 +282,22 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
 &s->iram_mem);

 /* DRAM */
+memory_region_allocate_system_memory(ram_all, NULL, "exynos4210.ram",
+ ram_size);
+
 mem_size = ram_size;
 if (mem_size > EXYNOS4210_DRAM_MAX_SIZE) {
-memory_region_init_ram(&s->dram1_mem, NULL, "exynos4210.dram1",
-mem_size - EXYNOS4210_DRAM_MAX_SIZE, &error_abort);
-vmstate_register_ram_global(&s->dram1_mem);
+memory_region_init_alias(&s->dram1_mem, NULL, "exynos4210.dram1",
+ ram_all,
+ EXYNOS4210_DRAM1_BASE_ADDR,
+ mem_size - EXYNOS4210_DRAM_MAX_SIZE);
 memory_region_add_subregion(system_mem, EXYNOS4210_DRAM1_BASE_ADDR,
 &s->dram1_mem);
 mem_size = EXYNOS4210_DRAM_MAX_SIZE;
 }
-memory_region_init_ram(&s->dram0_mem, NULL, "exynos4210.dram0", mem_size,
-   &error_abort);
-vmstate_register_ram_global(&s->dram0_mem);
+memory_region_init_alias(&s->dram1_mem, NULL, "exynos4210.dram0",
+ram_all,
+EXYNOS4210_DRAM0_BASE_ADDR, mem_size);
 memory_region_add_subregion(system_mem, EXYNOS4210_DRAM0_BASE_ADDR,
 &s->dram0_mem);



[Qemu-devel] [Bug 1392504] Re: USB Passthrough is not working anymore

2015-03-24 Thread Leen Keus
Hi Kevin, finally somebody that found a solution. Great, thank you very
much! It is working now.

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

Title:
  USB Passthrough is not working anymore

Status in QEMU:
  New
Status in qemu package in Ubuntu:
  Triaged

Bug description:
  After upgrading from Ubuntu 14.04 to Ubuntu 14.10 USB passthrough in
  QEMU (version is now 2.1.0 - Debian2.1+dfsg-4ubuntu6.1) is not working
  any more. Already tried to remove and attach the USB devices. I use 1
  USB2 HDD  +  1 USB3 HDD to a virtual linux machine; 1 USB2 HDD to a
  virual FNAS machine and a USB 2camera to virtual Win7 machine. All
  these devices are not working any more.

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



[Qemu-devel] [PATCH for-2.3] sparc: memory: Replace memory_region_init_ram with memory_region_allocate_system_memory

2015-03-24 Thread Dirk Müller
Commit 0b183fc871:"memory: move mem_path handling to
memory_region_allocate_system_memory" split memory_region_init_ram and
memory_region_init_ram_from_file. Also it moved mem-path handling a step
up from memory_region_init_ram to memory_region_allocate_system_memory.

Therefore for any board that uses memory_region_init_ram directly,
-mem-path is not supported.

Fix this by replacing memory_region_init_ram with
memory_region_allocate_system_memory.

Signed-off-by: Dirk Mueller 
---
 hw/sparc/leon3.c | 3 +--
 hw/sparc/sun4m.c | 5 ++---
 2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c
index e41ec0b..7f5dcd6 100644
--- a/hw/sparc/leon3.c
+++ b/hw/sparc/leon3.c
@@ -151,8 +151,7 @@ static void leon3_generic_hw_init(MachineState *machine)
 exit(1);
 }

-memory_region_init_ram(ram, NULL, "leon3.ram", ram_size, &error_abort);
-vmstate_register_ram_global(ram);
+memory_region_allocate_system_memory(ram, NULL, "leon3.ram", ram_size);
 memory_region_add_subregion(address_space_mem, 0x4000, ram);

 /* Allocate BIOS */
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index b879aa9..7761321 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -805,9 +805,8 @@ static int ram_init1(SysBusDevice *dev)
 {
 RamDevice *d = SUN4M_RAM(dev);

-memory_region_init_ram(&d->ram, OBJECT(d), "sun4m.ram", d->size,
-   &error_abort);
-vmstate_register_ram_global(&d->ram);
+memory_region_allocate_system_memory(&d->ram, OBJECT(d), "sun4m.ram",
+ d->size);
 sysbus_init_mmio(dev, &d->ram);
 return 0;
 }
-- 
2.0.4



Re: [Qemu-devel] [PATCH for-2.3] m68k: memory: Replace memory_region_init_ram with memory_region_allocate_system_memory

2015-03-24 Thread Paolo Bonzini


On 24/03/2015 22:26, Dirk Müller wrote:
> Commit 0b183fc871:"memory: move mem_path handling to
> memory_region_allocate_system_memory" split memory_region_init_ram and
> memory_region_init_ram_from_file. Also it moved mem-path handling a step
> up from memory_region_init_ram to memory_region_allocate_system_memory.
> 
> Therefore for any board that uses memory_region_init_ram directly,
> -mem-path is not supported.
> 
> Fix this by replacing memory_region_init_ram with
> memory_region_allocate_system_memory.
> 
> Signed-off-by: Dirk Mueller 
> ---
>  hw/m68k/an5206.c | 3 +--
>  hw/m68k/dummy_m68k.c | 3 ++-
>  hw/m68k/mcf5208.c| 3 +--
>  3 files changed, 4 insertions(+), 5 deletions(-)
> 
> diff --git a/hw/m68k/an5206.c b/hw/m68k/an5206.c
> index f1f1350..f63ab2b 100644
> --- a/hw/m68k/an5206.c
> +++ b/hw/m68k/an5206.c
> @@ -50,8 +50,7 @@ static void an5206_init(MachineState *machine)
>  env->rambar0 = AN5206_RAMBAR_ADDR | 1;
> 
>  /* DRAM at address zero */
> -memory_region_init_ram(ram, NULL, "an5206.ram", ram_size, &error_abort);
> -vmstate_register_ram_global(ram);
> +memory_region_allocate_system_memory(ram, NULL, "an5206.ram", ram_size);
>  memory_region_add_subregion(address_space_mem, 0, ram);
> 
>  /* Internal SRAM.  */
> diff --git a/hw/m68k/dummy_m68k.c b/hw/m68k/dummy_m68k.c
> index 278f4c0..6e5fa50 100644
> --- a/hw/m68k/dummy_m68k.c
> +++ b/hw/m68k/dummy_m68k.c
> @@ -42,7 +42,8 @@ static void dummy_m68k_init(MachineState *machine)
>  env->vbr = 0;
> 
>  /* RAM at address zero */
> -memory_region_init_ram(ram, NULL, "dummy_m68k.ram", ram_size,
> &error_abort);
> +memory_region_allocate_system_memory(ram, NULL, "dummy_m68k.ram",
> + ram_size);
>  vmstate_register_ram_global(ram);

You need to remove vmstate_register_ram_global too.

Paolo

>  memory_region_add_subregion(address_space_mem, 0, ram);
> 
> diff --git a/hw/m68k/mcf5208.c b/hw/m68k/mcf5208.c
> index a01a445..326a42d 100644
> --- a/hw/m68k/mcf5208.c
> +++ b/hw/m68k/mcf5208.c
> @@ -218,8 +218,7 @@ static void mcf5208evb_init(MachineState *machine)
>  /* TODO: Configure BARs.  */
> 
>  /* DRAM at 0x4000 */
> -memory_region_init_ram(ram, NULL, "mcf5208.ram", ram_size, &error_abort);
> -vmstate_register_ram_global(ram);
> +memory_region_allocate_system_memory(ram, NULL, "mcf5208.ram", ram_size);
>  memory_region_add_subregion(address_space_mem, 0x4000, ram);
> 
>  /* Internal SRAM.  */
> 



Re: [Qemu-devel] [PATCH for-2.3] arm: memory: Replace memory_region_init_ram with memory_region_allocate_system_memory

2015-03-24 Thread Paolo Bonzini


On 24/03/2015 22:24, Dirk Müller wrote:
> +++ b/hw/arm/exynos4210.c
> @@ -283,16 +283,16 @@ Exynos4210State *exynos4210_init(MemoryRegion 
> *system_mem,
>  /* DRAM */
>  mem_size = ram_size;
>  if (mem_size > EXYNOS4210_DRAM_MAX_SIZE) {
> -memory_region_init_ram(&s->dram1_mem, NULL, "exynos4210.dram1",
> -mem_size - EXYNOS4210_DRAM_MAX_SIZE, &error_abort);
> -vmstate_register_ram_global(&s->dram1_mem);
> +unsigned long dram1_size = mem_size - EXYNOS4210_DRAM_MAX_SIZE;
> +memory_region_allocate_system_memory(&s->dram1_mem, NULL,
> + "exynos4210.dram1",
> + dram1_size);
>  memory_region_add_subregion(system_mem, EXYNOS4210_DRAM1_BASE_ADDR,
>  &s->dram1_mem);
>  mem_size = EXYNOS4210_DRAM_MAX_SIZE;
>  }
> -memory_region_init_ram(&s->dram0_mem, NULL, "exynos4210.dram0", mem_size,
> -   &error_abort);
> -vmstate_register_ram_global(&s->dram0_mem);
> +memory_region_allocate_system_memory(&s->dram0_mem, NULL,
> + "exynos4210.dram0", mem_size);
>  memory_region_add_subregion(system_mem, EXYNOS4210_DRAM0_BASE_ADDR,
>  &s->dram0_mem);

You cannot call memory_region_allocate_system_memory twice.  For cases
like this one, the right thing to do is to create a region with
memory_region_allocate_system_memory, and then replace
memory_region_init_ram with memory_region_init_alias.  This "slices" the
region created by memory_region_allocate_system_memory.

Paolo



[Qemu-devel] [PATCH for-2.3] mips: memory: Replace memory_region_init_ram with memory_region_allocate_system_memory

2015-03-24 Thread Dirk Müller
Commit 0b183fc871:"memory: move mem_path handling to
memory_region_allocate_system_memory" split memory_region_init_ram and
memory_region_init_ram_from_file. Also it moved mem-path handling a step
up from memory_region_init_ram to memory_region_allocate_system_memory.

Therefore for any board that uses memory_region_init_ram directly,
-mem-path is not supported.

Fix this by replacing memory_region_init_ram with
memory_region_allocate_system_memory.

Signed-off-by: Dirk Mueller 
---
 hw/mips/mips_fulong2e.c | 3 +--
 hw/mips/mips_jazz.c | 5 ++---
 hw/mips/mips_malta.c| 5 ++---
 hw/mips/mips_mipssim.c  | 5 ++---
 hw/mips/mips_r4k.c  | 3 +--
 5 files changed, 8 insertions(+), 13 deletions(-)

diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c
index ea73585..4aae64a 100644
--- a/hw/mips/mips_fulong2e.c
+++ b/hw/mips/mips_fulong2e.c
@@ -301,8 +301,7 @@ static void mips_fulong2e_init(MachineState *machine)
 bios_size = 1024 * 1024;

 /* allocate RAM */
-memory_region_init_ram(ram, NULL, "fulong2e.ram", ram_size, &error_abort);
-vmstate_register_ram_global(ram);
+memory_region_allocate_system_memory(ram, NULL, "fulong2e.ram", ram_size);
 memory_region_init_ram(bios, NULL, "fulong2e.bios", bios_size,
&error_abort);
 vmstate_register_ram_global(bios);
diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c
index ef5dd7d..07f3c27 100644
--- a/hw/mips/mips_jazz.c
+++ b/hw/mips/mips_jazz.c
@@ -182,9 +182,8 @@ static void mips_jazz_init(MachineState *machine,
 cc->do_unassigned_access = mips_jazz_do_unassigned_access;

 /* allocate RAM */
-memory_region_init_ram(ram, NULL, "mips_jazz.ram", machine->ram_size,
-   &error_abort);
-vmstate_register_ram_global(ram);
+memory_region_allocate_system_memory(ram, NULL, "mips_jazz.ram",
+ machine->ram_size);
 memory_region_add_subregion(address_space, 0, ram);

 memory_region_init_ram(bios, NULL, "mips_jazz.bios", MAGNUM_BIOS_SIZE,
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 533b2e6..b0fa71a 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -993,9 +993,8 @@ void mips_malta_init(MachineState *machine)
 }

 /* register RAM at high address where it is undisturbed by IO */
-memory_region_init_ram(ram_high, NULL, "mips_malta.ram", ram_size,
-   &error_abort);
-vmstate_register_ram_global(ram_high);
+memory_region_allocate_system_memory(ram_high, NULL, "mips_malta.ram",
+ ram_size);
 memory_region_add_subregion(system_memory, 0x8000, ram_high);

 /* alias for pre IO hole access */
diff --git a/hw/mips/mips_mipssim.c b/hw/mips/mips_mipssim.c
index 5d44c3f..61f74a6 100644
--- a/hw/mips/mips_mipssim.c
+++ b/hw/mips/mips_mipssim.c
@@ -171,9 +171,8 @@ mips_mipssim_init(MachineState *machine)
 qemu_register_reset(main_cpu_reset, reset_info);

 /* Allocate RAM. */
-memory_region_init_ram(ram, NULL, "mips_mipssim.ram", ram_size,
-   &error_abort);
-vmstate_register_ram_global(ram);
+memory_region_allocate_system_memory(ram, NULL, "mips_mipssim.ram",
+ ram_size);
 memory_region_init_ram(bios, NULL, "mips_mipssim.bios", BIOS_SIZE,
&error_abort);
 vmstate_register_ram_global(bios);
diff --git a/hw/mips/mips_r4k.c b/hw/mips/mips_r4k.c
index 52564be..66e2a58 100644
--- a/hw/mips/mips_r4k.c
+++ b/hw/mips/mips_r4k.c
@@ -205,8 +205,7 @@ void mips_r4k_init(MachineState *machine)
 ((unsigned int)ram_size / (1 << 20)));
 exit(1);
 }
-memory_region_init_ram(ram, NULL, "mips_r4k.ram", ram_size, &error_abort);
-vmstate_register_ram_global(ram);
+memory_region_allocate_system_memory(ram, NULL, "mips_r4k.ram", ram_size);

 memory_region_add_subregion(address_space_mem, 0, ram);

-- 
2.0.4



[Qemu-devel] [PATCH for-2.3] m68k: memory: Replace memory_region_init_ram with memory_region_allocate_system_memory

2015-03-24 Thread Dirk Müller
Commit 0b183fc871:"memory: move mem_path handling to
memory_region_allocate_system_memory" split memory_region_init_ram and
memory_region_init_ram_from_file. Also it moved mem-path handling a step
up from memory_region_init_ram to memory_region_allocate_system_memory.

Therefore for any board that uses memory_region_init_ram directly,
-mem-path is not supported.

Fix this by replacing memory_region_init_ram with
memory_region_allocate_system_memory.

Signed-off-by: Dirk Mueller 
---
 hw/m68k/an5206.c | 3 +--
 hw/m68k/dummy_m68k.c | 3 ++-
 hw/m68k/mcf5208.c| 3 +--
 3 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/hw/m68k/an5206.c b/hw/m68k/an5206.c
index f1f1350..f63ab2b 100644
--- a/hw/m68k/an5206.c
+++ b/hw/m68k/an5206.c
@@ -50,8 +50,7 @@ static void an5206_init(MachineState *machine)
 env->rambar0 = AN5206_RAMBAR_ADDR | 1;

 /* DRAM at address zero */
-memory_region_init_ram(ram, NULL, "an5206.ram", ram_size, &error_abort);
-vmstate_register_ram_global(ram);
+memory_region_allocate_system_memory(ram, NULL, "an5206.ram", ram_size);
 memory_region_add_subregion(address_space_mem, 0, ram);

 /* Internal SRAM.  */
diff --git a/hw/m68k/dummy_m68k.c b/hw/m68k/dummy_m68k.c
index 278f4c0..6e5fa50 100644
--- a/hw/m68k/dummy_m68k.c
+++ b/hw/m68k/dummy_m68k.c
@@ -42,7 +42,8 @@ static void dummy_m68k_init(MachineState *machine)
 env->vbr = 0;

 /* RAM at address zero */
-memory_region_init_ram(ram, NULL, "dummy_m68k.ram", ram_size,
&error_abort);
+memory_region_allocate_system_memory(ram, NULL, "dummy_m68k.ram",
+ ram_size);
 vmstate_register_ram_global(ram);
 memory_region_add_subregion(address_space_mem, 0, ram);

diff --git a/hw/m68k/mcf5208.c b/hw/m68k/mcf5208.c
index a01a445..326a42d 100644
--- a/hw/m68k/mcf5208.c
+++ b/hw/m68k/mcf5208.c
@@ -218,8 +218,7 @@ static void mcf5208evb_init(MachineState *machine)
 /* TODO: Configure BARs.  */

 /* DRAM at 0x4000 */
-memory_region_init_ram(ram, NULL, "mcf5208.ram", ram_size, &error_abort);
-vmstate_register_ram_global(ram);
+memory_region_allocate_system_memory(ram, NULL, "mcf5208.ram", ram_size);
 memory_region_add_subregion(address_space_mem, 0x4000, ram);

 /* Internal SRAM.  */
-- 
2.0.4



[Qemu-devel] [PATCH for-2.3] arm: memory: Replace memory_region_init_ram with memory_region_allocate_system_memory

2015-03-24 Thread Dirk Müller
Commit 0b183fc871:"memory: move mem_path handling to
memory_region_allocate_system_memory" split memory_region_init_ram and
memory_region_init_ram_from_file. Also it moved mem-path handling a step
up from memory_region_init_ram to memory_region_allocate_system_memory.

Therefore for any board that uses memory_region_init_ram directly,
-mem-path is not supported.

Fix this by replacing memory_region_init_ram with
memory_region_allocate_system_memory.

Signed-off-by: Dirk Mueller 
---
 hw/arm/cubieboard.c   |  5 ++---
 hw/arm/digic_boards.c |  3 +--
 hw/arm/exynos4210.c   | 12 ++--
 hw/arm/highbank.c |  2 +-
 hw/arm/integratorcp.c |  4 ++--
 hw/arm/kzm.c  |  3 +--
 hw/arm/musicpal.c |  5 ++---
 hw/arm/omap1.c|  7 ---
 hw/arm/omap2.c|  6 +++---
 hw/arm/realview.c | 10 --
 hw/arm/strongarm.c|  7 ---
 hw/arm/versatilepb.c  |  5 ++---
 hw/arm/vexpress.c | 10 --
 hw/arm/virt.c |  5 ++---
 hw/arm/xilinx_zynq.c  |  5 ++---
 15 files changed, 40 insertions(+), 49 deletions(-)

diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c
index d1e53be..1582250 100644
--- a/hw/arm/cubieboard.c
+++ b/hw/arm/cubieboard.c
@@ -63,9 +63,8 @@ static void cubieboard_init(MachineState *machine)
 exit(1);
 }

-memory_region_init_ram(&s->sdram, NULL, "cubieboard.ram",
-   machine->ram_size, &error_abort);
-vmstate_register_ram_global(&s->sdram);
+memory_region_allocate_system_memory(&s->sdram, NULL, "cubieboard.ram",
+ machine->ram_size);
 memory_region_add_subregion(get_system_memory(), AW_A10_SDRAM_BASE,
 &s->sdram);

diff --git a/hw/arm/digic_boards.c b/hw/arm/digic_boards.c
index e576646..f8ba9e5 100644
--- a/hw/arm/digic_boards.c
+++ b/hw/arm/digic_boards.c
@@ -51,9 +51,8 @@ typedef struct DigicBoard {

 static void digic4_board_setup_ram(DigicBoardState *s, hwaddr ram_size)
 {
-memory_region_init_ram(&s->ram, NULL, "ram", ram_size, &error_abort);
+memory_region_allocate_system_memory(&s->ram, NULL, "ram", ram_size);
 memory_region_add_subregion(get_system_memory(), 0, &s->ram);
-vmstate_register_ram_global(&s->ram);
 }

 static void digic4_board_init(DigicBoard *board)
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
index c55fab8..63ea4a9 100644
--- a/hw/arm/exynos4210.c
+++ b/hw/arm/exynos4210.c
@@ -283,16 +283,16 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
 /* DRAM */
 mem_size = ram_size;
 if (mem_size > EXYNOS4210_DRAM_MAX_SIZE) {
-memory_region_init_ram(&s->dram1_mem, NULL, "exynos4210.dram1",
-mem_size - EXYNOS4210_DRAM_MAX_SIZE, &error_abort);
-vmstate_register_ram_global(&s->dram1_mem);
+unsigned long dram1_size = mem_size - EXYNOS4210_DRAM_MAX_SIZE;
+memory_region_allocate_system_memory(&s->dram1_mem, NULL,
+ "exynos4210.dram1",
+ dram1_size);
 memory_region_add_subregion(system_mem, EXYNOS4210_DRAM1_BASE_ADDR,
 &s->dram1_mem);
 mem_size = EXYNOS4210_DRAM_MAX_SIZE;
 }
-memory_region_init_ram(&s->dram0_mem, NULL, "exynos4210.dram0", mem_size,
-   &error_abort);
-vmstate_register_ram_global(&s->dram0_mem);
+memory_region_allocate_system_memory(&s->dram0_mem, NULL,
+ "exynos4210.dram0", mem_size);
 memory_region_add_subregion(system_mem, EXYNOS4210_DRAM0_BASE_ADDR,
 &s->dram0_mem);

diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
index ddd10dc..4458315 100644
--- a/hw/arm/highbank.c
+++ b/hw/arm/highbank.c
@@ -267,7 +267,7 @@ static void calxeda_init(MachineState *machine,
enum cxmachines machine_id)

 sysmem = get_system_memory();
 dram = g_new(MemoryRegion, 1);
-memory_region_init_ram(dram, NULL, "highbank.dram", ram_size,
&error_abort);
+memory_region_allocate_system_memory(dram, NULL, "highbank.dram",
ram_size);
 /* SDRAM at address zero.  */
 memory_region_add_subregion(sysmem, 0, dram);

diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
index cb609cd..0fbbf99 100644
--- a/hw/arm/integratorcp.c
+++ b/hw/arm/integratorcp.c
@@ -567,8 +567,8 @@ static void integratorcp_init(MachineState *machine)

 cpu = ARM_CPU(cpuobj);

-memory_region_init_ram(ram, NULL, "integrator.ram", ram_size,
&error_abort);
-vmstate_register_ram_global(ram);
+memory_region_allocate_system_memory(ram, NULL, "integrator.ram",
+ ram_size);
 /* ??? On a real system the first 1Mb is mapped as SSRAM or boot flash.  */
 /* ??? RAM should repeat to fill physical memory space.  */
 /* SDRAM at address zero*/
diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c
index 94ceab6..5be0369 100644
--- a/hw/arm/kzm.c
+++ b/hw/arm/kzm.c
@@ -97,8 +97,7 @@ stat

[Qemu-devel] [Bug 1435973] [NEW] Qemu crash when a guest linux issues specific scsi command via ioctl(SG_IO) with SCSI disk emulation.

2015-03-24 Thread hiroaki
Public bug reported:

As of git revision 362ca922eea03240916287a8a6267801ab095d12, when guest
linux issues specifit scsi command, qemu crashes.

To reproduce.

1. launch qemu with scsi emulatoin
qemu-sysytem-i386.exe -kernel bzImage -drive file=rootfs.ext2,index=0,if=scsi 
-append root=/dev/sda -drive file=\\.\PhysicalDrive1,index=1,if=scsi
2. issues scsi command via ioctl(SG_IO) on guest linux. like below.

-
struct request_sense sens;
struct sg_io_hdr sg;
unsigned char cdb[6];
unsigned char buf[127];

memset( &sens, 0, sizeof(sens) );
memset(&sg, 0, sizeof(sg));
memset(cdb, 0, sizeof(cdb));
memset(buf, 0, sizeof(buf));

// qemu crash!!!
cdb[0] = 0xff;

sg.dxferp = buf;
sg.dxfer_len = sizeof(buf);
sg.dxfer_direction = SG_DXFER_FROM_DEV;
sg.flags = 0;
sg.interface_id = 'S';
sg.cmdp = cdb;
sg.cmd_len = sizeof( cdb );
sg.sbp = (unsigned char*)&sens;
sg.mx_sb_len = sizeof( sens );

ioctl( fd, SG_IO, &sg );
-

I think cause is below code.

scsi-bus.c L1239
int scsi_req_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf)
{
int rc;

cmd->lba = -1;
cmd->len = scsi_cdb_length(buf);
...
memcpy(cmd->buf, buf, cmd->len);
}

scsi_cdb_length(buf) returns -1 when buf[0] is unexpected value.
Then memcpy(cmd->buf, buf, 4294967295); is executed and crash.

Environment
Qemu: git revision 362ca922eea03240916287a8a6267801ab095d12
Guest: linux kernel 3.18.4 + buildroot
Host: Windows 7 64bit

Thanks,
hiroaki

** Affects: qemu
 Importance: Undecided
 Status: New

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

Title:
  Qemu crash when a guest linux issues specific scsi command via
  ioctl(SG_IO) with SCSI disk emulation.

Status in QEMU:
  New

Bug description:
  As of git revision 362ca922eea03240916287a8a6267801ab095d12, when
  guest linux issues specifit scsi command, qemu crashes.

  To reproduce.

  1. launch qemu with scsi emulatoin
  qemu-sysytem-i386.exe -kernel bzImage -drive file=rootfs.ext2,index=0,if=scsi 
-append root=/dev/sda -drive file=\\.\PhysicalDrive1,index=1,if=scsi
  2. issues scsi command via ioctl(SG_IO) on guest linux. like below.

  -
  struct request_sense sens;
  struct sg_io_hdr sg;
  unsigned char cdb[6];
  unsigned char buf[127];

  memset( &sens, 0, sizeof(sens) );
  memset(&sg, 0, sizeof(sg));
  memset(cdb, 0, sizeof(cdb));
  memset(buf, 0, sizeof(buf));

  // qemu crash!!!
  cdb[0] = 0xff;

  sg.dxferp = buf;
  sg.dxfer_len = sizeof(buf);
  sg.dxfer_direction = SG_DXFER_FROM_DEV;
  sg.flags = 0;
  sg.interface_id = 'S';
  sg.cmdp = cdb;
  sg.cmd_len = sizeof( cdb );
  sg.sbp = (unsigned char*)&sens;
  sg.mx_sb_len = sizeof( sens );

  ioctl( fd, SG_IO, &sg );
  -

  I think cause is below code.

  scsi-bus.c L1239
  int scsi_req_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf)
  {
  int rc;

  cmd->lba = -1;
  cmd->len = scsi_cdb_length(buf);
  ...
  memcpy(cmd->buf, buf, cmd->len);
  }

  scsi_cdb_length(buf) returns -1 when buf[0] is unexpected value.
  Then memcpy(cmd->buf, buf, 4294967295); is executed and crash.

  Environment
  Qemu: git revision 362ca922eea03240916287a8a6267801ab095d12
  Guest: linux kernel 3.18.4 + buildroot
  Host: Windows 7 64bit

  Thanks,
  hiroaki

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



Re: [Qemu-devel] [PATCH v5 12/28] qapi: Introduce 'alternate' to replace anonymous union

2015-03-24 Thread Eric Blake
On 03/24/2015 02:03 PM, Eric Blake wrote:
> Rather than special-casing "'union':'foo','alternate':{}" as an

And continuing my belated proofreading:

s/alternate/discriminator/

> unusual union that can represent a non-dictionary, it is nicer
> to designate a separate meta-type "'alternate':'foo'" for the
> purpose.  This involves a lot of documentation tweaks and fallout
> from .json files, but I already split as much as possible into
> earlier commits.
> 
> Signed-off-by: Eric Blake 
> ---

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



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH v5 08/28] qapi: Better error messages for bad unions

2015-03-24 Thread Eric Blake
On 03/24/2015 02:03 PM, Eric Blake wrote:
> Previous commits demonstrated that the generator had several
> flaws with less-than-perfect unions:
> - make the use of a base without discriminator a hard error,
> since the previous patch removed all remaining uses of it
> - a simple union that listed the same branch twice (or two variant
> names that map to the same C enumerator, including the implicit
> MAX sentinel) ended up generating invalid C code
> - checking 'if discriminator' prior to 'if discriminator == {}'

Another commit typo; should read:
 checking 'if not discriminator' prior to 'if discriminator == {}'

> leads to dead code in python, and ended up processing anonymous
> unions as if they were simple unions
> - an anonymous union that listed two branches with the same qtype
> ended up generating invalid C code
> - the generator crashed on anonymous union attempts to use an
> array type
> - the generator was silently ignoring a base type for anonymous
> unions
> - the generator allowed unknown types or nested anonymous unions
> as a branch in an anonymous union
> 
> Signed-off-by: Eric Blake 
> ---


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



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH v5 03/28] qapi: Require ASCII in schema

2015-03-24 Thread Eric Blake
On 03/24/2015 02:03 PM, Eric Blake wrote:
> Python 2 and Python 3 have a wild history of whether strings
> default to ascii or unicode, where Python 3 requires checking
> instanceof(foo, basestr) to cover all strings, but where that
> code is not portable to Python 2.  It's simpler to just state
> that we don't care about Unicode strings, and to just always
> use the simpler instanceof(foo, str) everywhere.

And for all my proof-reading, I already have a commit message change:

s/instanceof/isinstance/

(you can tell I'm not that proficient in python...)

> 
> I'm no python expert, so I'm basing it on this conversation:
> https://lists.gnu.org/archive/html/qemu-devel/2014-09/msg05278.html
> 
> Signed-off-by: Eric Blake 
> ---
>  scripts/qapi.py | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 

> @@ -354,7 +354,7 @@ def parse_schema(input_file):
>  return exprs
> 
>  def parse_args(typeinfo):
> -if isinstance(typeinfo, basestring):
> +if isinstance(typeinfo, str):

at least the code is right.

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



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PATCH v5 14/28] qapi: Better error messages for bad expressions

2015-03-24 Thread Eric Blake
The previous commit demonstrated that the generator overlooked some
fairly basic broken expressions:
- missing metataype
- metatype key has a non-string value
- unknown key in relation to the metatype
- conflicting metatype (this patch treats the second metatype as an
unknown key of the first key visited, which is not necessarily the
first key the user typed)

Add check_keys to cover these situations, and update testcases to
match.  A couple other tests (enum-missing-data, indented-expr) had
to change since the validation added here occurs so early.

While valid .json files won't trigger any of these cases, we might
as well be nicer to developers that make a typo while trying to add
new QAPI code.

Signed-off-by: Eric Blake 
---
 scripts/qapi.py | 45 +++--
 tests/qapi-schema/alternate-base.err|  2 +-
 tests/qapi-schema/bad-type-dict.err |  1 +
 tests/qapi-schema/bad-type-dict.exit|  2 +-
 tests/qapi-schema/bad-type-dict.json|  2 +-
 tests/qapi-schema/bad-type-dict.out |  3 ---
 tests/qapi-schema/double-type.err   |  1 +
 tests/qapi-schema/double-type.exit  |  2 +-
 tests/qapi-schema/double-type.json  |  2 +-
 tests/qapi-schema/double-type.out   |  3 ---
 tests/qapi-schema/enum-missing-data.err |  2 +-
 tests/qapi-schema/indented-expr.json|  4 +--
 tests/qapi-schema/indented-expr.out |  2 +-
 tests/qapi-schema/missing-type.err  |  1 +
 tests/qapi-schema/missing-type.exit |  2 +-
 tests/qapi-schema/missing-type.json |  2 +-
 tests/qapi-schema/missing-type.out  |  3 ---
 tests/qapi-schema/unknown-expr-key.err  |  1 +
 tests/qapi-schema/unknown-expr-key.exit |  2 +-
 tests/qapi-schema/unknown-expr-key.json |  2 +-
 tests/qapi-schema/unknown-expr-key.out  |  3 ---
 21 files changed, 54 insertions(+), 33 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 018ec45..90eb3bc 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -341,12 +341,6 @@ def check_alternate(expr, expr_info):
 values = { 'MAX': '(automatic)' }
 types_seen = {}

-base = expr.get('base')
-if base:
-raise QAPIExprError(expr_info,
-"Alternate '%s' must not have a base"
-% name)
-
 # Check every branch
 for (key, value) in members.items():
 # Check for conflicts in the generated enum
@@ -408,6 +402,26 @@ def check_exprs(schema):
 elif expr.has_key('event'):
 check_event(expr, info)

+def check_keys(expr_elem, meta, required, optional=[]):
+expr = expr_elem['expr']
+info = expr_elem['info']
+name = expr[meta]
+if not isinstance(name, str):
+raise QAPIExprError(info,
+"%s key must have a string value" % meta)
+required = required + [ meta ]
+for (key, value) in expr.items():
+if not key in required and not key in optional:
+raise QAPIExprError(info,
+"%s '%s' has unknown key '%s'"
+% (meta, name, key))
+for key in required:
+if not expr.has_key(key):
+raise QAPIExprError(info,
+"%s '%s' is missing key '%s'"
+% (meta, name, key))
+
+
 def parse_schema(input_file):
 # First pass: read entire file into memory
 try:
@@ -419,15 +433,30 @@ def parse_schema(input_file):
 exprs = []

 try:
-# Next pass: learn the types.
+# Next pass: learn the types and check for valid expression keys. At
+# this point, top-level 'include' has already been flattened.
 for expr_elem in schema.exprs:
 expr = expr_elem['expr']
 if expr.has_key('enum'):
-add_enum(expr['enum'], expr.get('data'))
+check_keys(expr_elem, 'enum', ['data'])
+add_enum(expr['enum'], expr['data'])
 elif expr.has_key('union'):
+check_keys(expr_elem, 'union', ['data'],
+   ['base', 'discriminator'])
 add_union(expr)
+elif expr.has_key('alternate'):
+check_keys(expr_elem, 'alternate', ['data'])
 elif expr.has_key('type'):
+check_keys(expr_elem, 'type', ['data'], ['base'])
 add_struct(expr)
+elif expr.has_key('command'):
+check_keys(expr_elem, 'command', [],
+   ['data', 'returns', 'gen', 'success-response'])
+elif expr.has_key('event'):
+check_keys(expr_elem, 'event', [], ['data'])
+else:
+raise QAPIExprError(expr_elem['info'],
+"Expression is missing metatype")
 exprs.append(expr)

 # Try again for hidden UnionKind enum
diff --git a/tests/qapi-schema/alternate-base.err 
b/tests/qapi-schema/alternate-base.err
index 4a2566e.

[Qemu-devel] [PATCH v5 28/28] qapi: Drop support for inline nested types

2015-03-24 Thread Eric Blake
A future patch will be using a 'name':{dictionary} entry in the
QAPI schema to specify a default value for an optional argument;
but existing use of inline nested structs conflicts with that goal.
Now that all commands have been changed to avoid inline nested
structs, nuke support for them, and turn it into a hard error.
Update the testsuite to reflect tighter parsing rules.

Signed-off-by: Eric Blake 
---
 scripts/qapi-commands.py |  8 +++---
 scripts/qapi-event.py|  4 +--
 scripts/qapi-types.py|  9 ++-
 scripts/qapi-visit.py| 37 
 scripts/qapi.py  | 18 +-
 tests/qapi-schema/event-nest-struct.err  |  2 +-
 tests/qapi-schema/nested-struct-data.err |  1 +
 tests/qapi-schema/nested-struct-data.exit|  2 +-
 tests/qapi-schema/nested-struct-data.json|  2 +-
 tests/qapi-schema/nested-struct-data.out |  3 ---
 tests/qapi-schema/nested-struct-returns.err  |  1 +
 tests/qapi-schema/nested-struct-returns.exit |  2 +-
 tests/qapi-schema/nested-struct-returns.json |  2 +-
 tests/qapi-schema/nested-struct-returns.out  |  3 ---
 14 files changed, 26 insertions(+), 68 deletions(-)

diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index 053ba85..db81044 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -28,7 +28,7 @@ def type_visitor(name):

 def generate_command_decl(name, args, ret_type):
 arglist=""
-for argname, argtype, optional, structured in parse_args(args):
+for argname, argtype, optional in parse_args(args):
 argtype = c_type(argtype, is_param=True)
 if optional:
 arglist += "bool has_%s, " % c_var(argname)
@@ -53,7 +53,7 @@ def gen_sync_call(name, args, ret_type, indent=0):
 retval=""
 if ret_type:
 retval = "retval = "
-for argname, argtype, optional, structured in parse_args(args):
+for argname, argtype, optional in parse_args(args):
 if optional:
 arglist += "has_%s, " % c_var(argname)
 arglist += "%s, " % (c_var(argname))
@@ -96,7 +96,7 @@ Visitor *v;
 def gen_visitor_input_vars_decl(args):
 ret = ""
 push_indent()
-for argname, argtype, optional, structured in parse_args(args):
+for argname, argtype, optional in parse_args(args):
 if optional:
 ret += mcgen('''
 bool has_%(argname)s = false;
@@ -139,7 +139,7 @@ v = qapi_dealloc_get_visitor(md);
 v = qmp_input_get_visitor(mi);
 ''')

-for argname, argtype, optional, structured in parse_args(args):
+for argname, argtype, optional in parse_args(args):
 if optional:
 ret += mcgen('''
 visit_optional(v, &has_%(c_name)s, "%(name)s", %(errp)s);
diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py
index 601e307..47dc041 100644
--- a/scripts/qapi-event.py
+++ b/scripts/qapi-event.py
@@ -21,7 +21,7 @@ def _generate_event_api_name(event_name, params):
 l = len(api_name)

 if params:
-for argname, argentry, optional, structured in parse_args(params):
+for argname, argentry, optional in parse_args(params):
 if optional:
 api_name += "bool has_%s,\n" % c_var(argname)
 api_name += "".ljust(l)
@@ -93,7 +93,7 @@ def generate_event_implement(api_name, event_name, params):
 """,
 event_name = event_name)

-for argname, argentry, optional, structured in parse_args(params):
+for argname, argentry, optional in parse_args(params):
 if optional:
 ret += mcgen("""
 if (has_%(var)s) {
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 9c8d68c..4789528 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -63,18 +63,13 @@ typedef struct %(name)sList
 def generate_struct_fields(members):
 ret = ''

-for argname, argentry, optional, structured in parse_args(members):
+for argname, argentry, optional in parse_args(members):
 if optional:
 ret += mcgen('''
 bool has_%(c_name)s;
 ''',
  c_name=c_var(argname))
-if structured:
-push_indent()
-ret += generate_struct({ "field": argname, "data": argentry})
-pop_indent()
-else:
-ret += mcgen('''
+ret += mcgen('''
 %(c_type)s %(c_name)s;
 ''',
  c_type=c_type(argentry), c_name=c_var(argname))
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 3e11089..10b08c6 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -51,27 +51,6 @@ def generate_visit_struct_fields(name, field_prefix, 
fn_prefix, members, base =
 else:
 full_name = "%s_%s" % (name, fn_prefix)

-for argname, argentry, optional, structured in parse_args(members):
-if structured:
-if not fn_prefix:
-nested_fn_prefix = argnam

[Qemu-devel] [PATCH v5 19/28] qapi: Add some type check tests

2015-03-24 Thread Eric Blake
Demonstrate that the qapi generator silently parses confusing
types, which may cause other errors later on. Later patches
will update the expected results as the generator is made stricter.

Signed-off-by: Eric Blake 
---
 tests/Makefile   |  8 ++--
 tests/qapi-schema/data-array-empty.err   |  0
 tests/qapi-schema/data-array-empty.exit  |  1 +
 tests/qapi-schema/data-array-empty.json  |  2 ++
 tests/qapi-schema/data-array-empty.out   |  3 +++
 tests/qapi-schema/data-array-unknown.err |  0
 tests/qapi-schema/data-array-unknown.exit|  1 +
 tests/qapi-schema/data-array-unknown.json|  2 ++
 tests/qapi-schema/data-array-unknown.out |  3 +++
 tests/qapi-schema/data-int.err   |  0
 tests/qapi-schema/data-int.exit  |  1 +
 tests/qapi-schema/data-int.json  |  2 ++
 tests/qapi-schema/data-int.out   |  3 +++
 tests/qapi-schema/data-member-array-bad.err  |  0
 tests/qapi-schema/data-member-array-bad.exit |  1 +
 tests/qapi-schema/data-member-array-bad.json |  2 ++
 tests/qapi-schema/data-member-array-bad.out  |  3 +++
 tests/qapi-schema/data-member-array.err  |  0
 tests/qapi-schema/data-member-array.exit |  1 +
 tests/qapi-schema/data-member-array.json |  4 
 tests/qapi-schema/data-member-array.out  |  5 +
 tests/qapi-schema/data-member-unknown.err|  0
 tests/qapi-schema/data-member-unknown.exit   |  1 +
 tests/qapi-schema/data-member-unknown.json   |  2 ++
 tests/qapi-schema/data-member-unknown.out|  3 +++
 tests/qapi-schema/data-unknown.err   |  0
 tests/qapi-schema/data-unknown.exit  |  1 +
 tests/qapi-schema/data-unknown.json  |  2 ++
 tests/qapi-schema/data-unknown.out   |  3 +++
 tests/qapi-schema/nested-struct-data.err |  0
 tests/qapi-schema/nested-struct-data.exit|  1 +
 tests/qapi-schema/nested-struct-data.json|  4 
 tests/qapi-schema/nested-struct-data.out |  3 +++
 tests/qapi-schema/nested-struct-returns.err  |  0
 tests/qapi-schema/nested-struct-returns.exit |  1 +
 tests/qapi-schema/nested-struct-returns.json |  3 +++
 tests/qapi-schema/nested-struct-returns.out  |  3 +++
 tests/qapi-schema/returns-alternate.err  |  0
 tests/qapi-schema/returns-alternate.exit |  1 +
 tests/qapi-schema/returns-alternate.json |  3 +++
 tests/qapi-schema/returns-alternate.out  |  4 
 tests/qapi-schema/returns-array-bad.err  |  0
 tests/qapi-schema/returns-array-bad.exit |  1 +
 tests/qapi-schema/returns-array-bad.json |  2 ++
 tests/qapi-schema/returns-array-bad.out  |  3 +++
 tests/qapi-schema/returns-int.err|  0
 tests/qapi-schema/returns-int.exit   |  1 +
 tests/qapi-schema/returns-int.json   |  2 ++
 tests/qapi-schema/returns-int.out|  3 +++
 tests/qapi-schema/returns-unknown.err|  0
 tests/qapi-schema/returns-unknown.exit   |  1 +
 tests/qapi-schema/returns-unknown.json   |  2 ++
 tests/qapi-schema/returns-unknown.out|  3 +++
 tests/qapi-schema/returns-whitelist.err  |  0
 tests/qapi-schema/returns-whitelist.exit |  1 +
 tests/qapi-schema/returns-whitelist.json | 11 +++
 tests/qapi-schema/returns-whitelist.out  |  7 +++
 57 files changed, 112 insertions(+), 2 deletions(-)
 create mode 100644 tests/qapi-schema/data-array-empty.err
 create mode 100644 tests/qapi-schema/data-array-empty.exit
 create mode 100644 tests/qapi-schema/data-array-empty.json
 create mode 100644 tests/qapi-schema/data-array-empty.out
 create mode 100644 tests/qapi-schema/data-array-unknown.err
 create mode 100644 tests/qapi-schema/data-array-unknown.exit
 create mode 100644 tests/qapi-schema/data-array-unknown.json
 create mode 100644 tests/qapi-schema/data-array-unknown.out
 create mode 100644 tests/qapi-schema/data-int.err
 create mode 100644 tests/qapi-schema/data-int.exit
 create mode 100644 tests/qapi-schema/data-int.json
 create mode 100644 tests/qapi-schema/data-int.out
 create mode 100644 tests/qapi-schema/data-member-array-bad.err
 create mode 100644 tests/qapi-schema/data-member-array-bad.exit
 create mode 100644 tests/qapi-schema/data-member-array-bad.json
 create mode 100644 tests/qapi-schema/data-member-array-bad.out
 create mode 100644 tests/qapi-schema/data-member-array.err
 create mode 100644 tests/qapi-schema/data-member-array.exit
 create mode 100644 tests/qapi-schema/data-member-array.json
 create mode 100644 tests/qapi-schema/data-member-array.out
 create mode 100644 tests/qapi-schema/data-member-unknown.err
 create mode 100644 tests/qapi-schema/data-member-unknown.exit
 create mode 100644 tests/qapi-schema/data-member-unknown.json
 create mode 100644 tests/qapi-schema/data-member-unknown.out
 create mode 100644 tests/qapi-schema/data-unknown.err
 create mode 100644 tests/qapi-schema/data-unknown.exit
 create mode 100644 tests/qapi-schema/data-unknown.json
 create mode 100644 tests/qapi-schema/data-unknown.ou

Re: [Qemu-devel] [PATCH RFC for-2.3 1/1] block: New command line option --no-format-probing

2015-03-24 Thread Paolo Bonzini


On 24/03/2015 17:49, Markus Armbruster wrote:
>> But what about migration from newer to older QEMU?  Libvirt even
>> supports QEMU versions where the only way to specify disks is "-hda
>> XYZ", so it is _impossible_ to honor the format=raw specifier.
> 
> If you migrate to a QEMU that doesn't understand the new option, libvirt
> simply won't set it.  You lose the protection against libvirt bugs it
> provides.  Guest won't notice.
> 
> If you somehow manage to find a QEMU old enough to make libvirt use
> format-incapable interfaces, you'll be using insecure format probing on
> the destination.  My patch makes no difference.  Good luck migrating to
> such an old QEMU.

(Didn't mean live migration---sorry, could have simply said "switch").

Based on my reading of the code, libvirt will actually ignore the
allow_disk_format_probing setting, and not do anything about the format
when driving such an old QEMU.  By contrast, if you specify a format and
libvirt invokes an old qemu-nbd without --format, libvirt fails hard.
That's already CVE worthy, isn't it?

So I think an option like this is premature.  libvirt should _first of
all_ ensure that it completely abides by the allow_disk_format_probing
setting, including refusing to drive old QEMUs when format probing is
disabled.  Once libvirt is consistent within itself, we can talk about
what help QEMU can provide.

Perfect is not the enemy of good here.  Good is the enemy of secure.

> As to "near misses don't count": for me, what counts is actual users
> telling me about their difficulties using QEMU securely.  Secure usage
> shouldn't be hard.

The right answer for them is probably "use libvirt" or "use Boxes"
depending on the actual usecase.  Invoking QEMU manually is almost never
the right answer for random untrusted images download from the Internet.
 Also, I suspect any advice to QEMU users about adding
--no-format-probing would be quickly forgotten.

That said, if _humans_ have interest in secure use of QEMU, that's a
much better and more interesting use case than libvirt's, because
libvirt is itself providing a secure management layer.

We have other security options, for example seccomp and FIPS mode.
Format probing definitely falls in this category.  Let's add first of
all a -security grouping, where "-security [all=]on" enables all of them
but it's also possible to control the suboptions individually.  Then we
can add format probing to this category.  The same options can be added
to the utilities.

Let's iron out the kinks and do it for 2.4.  It's a very useful feature
indeed.

But it's something we do for _users_, not for libvirt.  If libvirt wants
to use those features as a parachute, better for them.  But I still
maintain that for libvirt this is basically security theater, and the
priorities are others.

Paolo



[Qemu-devel] [PATCH v5 27/28] qapi: Drop inline nested types in query-pci

2015-03-24 Thread Eric Blake
A future patch will be using a 'name':{dictionary} entry in the
QAPI schema to specify a default value for an optional argument;
but existing use of inline nested structs conflicts with that goal.
This patch fixes one of only two commands relying on nested
types, by breaking the nesting into an explicit type; it means
that the type is now boxed instead of unboxed in C code, but the
QMP wire format is unaffected by this change.

Prefer the safer g_new0() while making the conversion, and reduce
some long lines.

Signed-off-by: Eric Blake 
---
 hmp.c| 26 
 hw/pci/pci.c | 42 ++
 qapi-schema.json | 90 ++--
 3 files changed, 98 insertions(+), 60 deletions(-)

diff --git a/hmp.c b/hmp.c
index c59b823..dbc7fec 100644
--- a/hmp.c
+++ b/hmp.c
@@ -648,14 +648,14 @@ static void hmp_info_pci_device(Monitor *mon, const 
PciDeviceInfo *dev)
dev->slot, dev->function);
 monitor_printf(mon, "");

-if (dev->class_info.has_desc) {
-monitor_printf(mon, "%s", dev->class_info.desc);
+if (dev->class_info->has_desc) {
+monitor_printf(mon, "%s", dev->class_info->desc);
 } else {
-monitor_printf(mon, "Class %04" PRId64, dev->class_info.q_class);
+monitor_printf(mon, "Class %04" PRId64, dev->class_info->q_class);
 }

 monitor_printf(mon, ": PCI device %04" PRIx64 ":%04" PRIx64 "\n",
-   dev->id.vendor, dev->id.device);
+   dev->id->vendor, dev->id->device);

 if (dev->has_irq) {
 monitor_printf(mon, "  IRQ %" PRId64 ".\n", dev->irq);
@@ -663,25 +663,25 @@ static void hmp_info_pci_device(Monitor *mon, const 
PciDeviceInfo *dev)

 if (dev->has_pci_bridge) {
 monitor_printf(mon, "  BUS %" PRId64 ".\n",
-   dev->pci_bridge->bus.number);
+   dev->pci_bridge->bus->number);
 monitor_printf(mon, "  secondary bus %" PRId64 ".\n",
-   dev->pci_bridge->bus.secondary);
+   dev->pci_bridge->bus->secondary);
 monitor_printf(mon, "  subordinate bus %" PRId64 ".\n",
-   dev->pci_bridge->bus.subordinate);
+   dev->pci_bridge->bus->subordinate);

 monitor_printf(mon, "  IO range [0x%04"PRIx64", 0x%04"PRIx64"]\n",
-   dev->pci_bridge->bus.io_range->base,
-   dev->pci_bridge->bus.io_range->limit);
+   dev->pci_bridge->bus->io_range->base,
+   dev->pci_bridge->bus->io_range->limit);

 monitor_printf(mon,
"  memory range [0x%08"PRIx64", 0x%08"PRIx64"]\n",
-   dev->pci_bridge->bus.memory_range->base,
-   dev->pci_bridge->bus.memory_range->limit);
+   dev->pci_bridge->bus->memory_range->base,
+   dev->pci_bridge->bus->memory_range->limit);

 monitor_printf(mon, "  prefetchable memory range "
"[0x%08"PRIx64", 0x%08"PRIx64"]\n",
-   dev->pci_bridge->bus.prefetchable_range->base,
-   dev->pci_bridge->bus.prefetchable_range->limit);
+   dev->pci_bridge->bus->prefetchable_range->base,
+   dev->pci_bridge->bus->prefetchable_range->limit);
 }

 for (region = dev->regions; region; region = region->next) {
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 6941a82..c1d0068 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -1456,24 +1456,26 @@ static PciBridgeInfo *qmp_query_pci_bridge(PCIDevice 
*dev, PCIBus *bus,
int bus_num)
 {
 PciBridgeInfo *info;
+PciMemoryRange *range;

-info = g_malloc0(sizeof(*info));
+info = g_new0(PciBridgeInfo, 1);

-info->bus.number = dev->config[PCI_PRIMARY_BUS];
-info->bus.secondary = dev->config[PCI_SECONDARY_BUS];
-info->bus.subordinate = dev->config[PCI_SUBORDINATE_BUS];
+info->bus = g_new0(PciBusInfo, 1);
+info->bus->number = dev->config[PCI_PRIMARY_BUS];
+info->bus->secondary = dev->config[PCI_SECONDARY_BUS];
+info->bus->subordinate = dev->config[PCI_SUBORDINATE_BUS];

-info->bus.io_range = g_malloc0(sizeof(*info->bus.io_range));
-info->bus.io_range->base = pci_bridge_get_base(dev, 
PCI_BASE_ADDRESS_SPACE_IO);
-info->bus.io_range->limit = pci_bridge_get_limit(dev, 
PCI_BASE_ADDRESS_SPACE_IO);
+range = info->bus->io_range = g_new0(PciMemoryRange, 1);
+range->base = pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_IO);
+range->limit = pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_IO);

-info->bus.memory_range = g_malloc0(sizeof(*info->bus.memory_range));
-info->bus.memory_range->base = pci_bridge_get_base(dev, 
PCI_BASE_ADDRESS_SPACE_MEMORY);
-info->bus.memory_range->limit = pci_bridge_get_limit(dev, 

[Qemu-devel] [PATCH v5 05/28] qapi: Better error messages for bad enums

2015-03-24 Thread Eric Blake
The previous commit demonstrated that the generator had several
flaws with less-than-perfect enums:
- an enum that listed the same string twice (or two variant
strings that map to the same C enumerator) ended up generating
an invalid C enum
- because the generator adds a _MAX terminator to each enum,
the use of an enum member 'max' can also cause this clash
- if an enum omits 'data', the generator left a python stack
trace rather than a graceful message
- an enum that used a non-array 'data' was silently accepted by
the parser
- an enum that used non-string members in the 'data' member
was silently accepted by the parser

Add check_enum to cover these situations, and update testcases
to match.  While valid .json files won't trigger any of these
cases, we might as well be nicer to developers that make a typo
while trying to add new QAPI code.

Signed-off-by: Eric Blake 
---
 scripts/qapi.py  | 34 +++-
 tests/qapi-schema/enum-clash-member.err  |  1 +
 tests/qapi-schema/enum-clash-member.exit |  2 +-
 tests/qapi-schema/enum-clash-member.json |  2 +-
 tests/qapi-schema/enum-clash-member.out  |  3 ---
 tests/qapi-schema/enum-dict-member.err   |  1 +
 tests/qapi-schema/enum-dict-member.exit  |  2 +-
 tests/qapi-schema/enum-dict-member.json  |  2 +-
 tests/qapi-schema/enum-dict-member.out   |  3 ---
 tests/qapi-schema/enum-max-member.err|  1 +
 tests/qapi-schema/enum-max-member.exit   |  2 +-
 tests/qapi-schema/enum-max-member.json   |  4 ++--
 tests/qapi-schema/enum-max-member.out|  3 ---
 tests/qapi-schema/enum-missing-data.err  |  7 +--
 tests/qapi-schema/enum-missing-data.json |  2 +-
 tests/qapi-schema/enum-wrong-data.err|  1 +
 tests/qapi-schema/enum-wrong-data.exit   |  2 +-
 tests/qapi-schema/enum-wrong-data.json   |  2 +-
 tests/qapi-schema/enum-wrong-data.out|  3 ---
 19 files changed, 44 insertions(+), 33 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 20ee505..3ce8c33 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -311,13 +311,37 @@ def check_union(expr, expr_info):
 # Todo: add checking for values. Key is checked as above, value can be
 # also checked here, but we need more functions to handle array case.

+def check_enum(expr, expr_info):
+name = expr['enum']
+members = expr.get('data')
+values = { 'MAX': '(automatic)' }
+
+if not isinstance(members, list):
+raise QAPIExprError(expr_info,
+"Enum '%s' requires an array for 'data'" % name)
+for member in members:
+if not isinstance(member, str):
+raise QAPIExprError(expr_info,
+"Enum '%s' member '%s' is not a string"
+% (name, member))
+key = _generate_enum_string(member)
+if key in values:
+raise QAPIExprError(expr_info,
+"Enum '%s' member '%s' clashes with '%s'"
+% (name, member, values[key]))
+values[key] = member
+
 def check_exprs(schema):
 for expr_elem in schema.exprs:
 expr = expr_elem['expr']
-if expr.has_key('union'):
-check_union(expr, expr_elem['info'])
-if expr.has_key('event'):
-check_event(expr, expr_elem['info'])
+info = expr_elem['info']
+
+if expr.has_key('enum'):
+check_enum(expr, info)
+elif expr.has_key('union'):
+check_union(expr, info)
+elif expr.has_key('event'):
+check_event(expr, info)

 def parse_schema(input_file):
 try:
@@ -331,7 +355,7 @@ def parse_schema(input_file):
 for expr_elem in schema.exprs:
 expr = expr_elem['expr']
 if expr.has_key('enum'):
-add_enum(expr['enum'], expr['data'])
+add_enum(expr['enum'], expr.get('data'))
 elif expr.has_key('union'):
 add_union(expr)
 elif expr.has_key('type'):
diff --git a/tests/qapi-schema/enum-clash-member.err 
b/tests/qapi-schema/enum-clash-member.err
index e69de29..48bd136 100644
--- a/tests/qapi-schema/enum-clash-member.err
+++ b/tests/qapi-schema/enum-clash-member.err
@@ -0,0 +1 @@
+tests/qapi-schema/enum-clash-member.json:2: Enum 'MyEnum' member 'ONE' clashes 
with 'one'
diff --git a/tests/qapi-schema/enum-clash-member.exit 
b/tests/qapi-schema/enum-clash-member.exit
index 573541a..d00491f 100644
--- a/tests/qapi-schema/enum-clash-member.exit
+++ b/tests/qapi-schema/enum-clash-member.exit
@@ -1 +1 @@
-0
+1
diff --git a/tests/qapi-schema/enum-clash-member.json 
b/tests/qapi-schema/enum-clash-member.json
index 99d442a..b7dc02a 100644
--- a/tests/qapi-schema/enum-clash-member.json
+++ b/tests/qapi-schema/enum-clash-member.json
@@ -1,2 +1,2 @@
-# FIXME: we should reject enums where members will clash when mapped to C enum
+# we reject enums where members will clash when mapped to C enum
 { 'enum': 'MyEnum', 'data': [ 'one', 'ONE' ] }
diff

[Qemu-devel] [PATCH v5 21/28] qapi: Require valid names

2015-03-24 Thread Eric Blake
Previous commits demonstrated that the generator overlooked various
bad naming situations:
- types, commands, and events need a valid name
- union and alternate branches cannot be marked optional

The set of valid names includes [a-zA-Z0-9._-] (where '.' is
useful only in downstream extensions).

Signed-off-by: Eric Blake 
---
 scripts/qapi.py| 57 --
 tests/qapi-schema/bad-ident.err|  1 +
 tests/qapi-schema/bad-ident.exit   |  2 +-
 tests/qapi-schema/bad-ident.json   |  2 +-
 tests/qapi-schema/bad-ident.out|  3 --
 tests/qapi-schema/flat-union-bad-discriminator.err |  2 +-
 .../flat-union-optional-discriminator.err  |  1 +
 .../flat-union-optional-discriminator.exit |  2 +-
 .../flat-union-optional-discriminator.json |  2 +-
 .../flat-union-optional-discriminator.out  |  5 --
 tests/qapi-schema/union-optional-branch.err|  1 +
 tests/qapi-schema/union-optional-branch.exit   |  2 +-
 tests/qapi-schema/union-optional-branch.json   |  2 +-
 tests/qapi-schema/union-optional-branch.out|  3 --
 14 files changed, 53 insertions(+), 32 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index c42683b..ed5385a 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -15,6 +15,7 @@ import re
 from ordereddict import OrderedDict
 import os
 import sys
+import string

 builtin_types = {
 'str':  'QTYPE_QSTRING',
@@ -276,8 +277,27 @@ def discriminator_find_enum_define(expr):

 return find_enum(discriminator_type)

+valid_characters = set(string.ascii_letters + string.digits + '.' + '-' + '_')
+def check_name(expr_info, source, name, allow_optional = False):
+membername = name
+
+if not isinstance(name, str):
+raise QAPIExprError(expr_info,
+"%s requires a string name" % source)
+if name == '**':
+return
+if name.startswith('*'):
+membername = name[1:]
+if not allow_optional:
+raise QAPIExprError(expr_info,
+"%s does not allow optional name '%s'"
+% (source, name))
+if not set(membername) <= valid_characters:
+raise QAPIExprError(expr_info,
+"%s uses invalid name '%s'" % (source, name))
+
 def check_type(expr_info, source, data, allow_array = False,
-   allowed_metas = [], allow_dict = True):
+   allowed_metas = [], allow_dict = True, allow_optional = False):
 global all_names

 if data is None:
@@ -317,21 +337,23 @@ def check_type(expr_info, source, data, allow_array = 
False,
 raise QAPIExprError(expr_info,
 "%s should be a type name" % source)
 for (key, value) in data.items():
+check_name(expr_info, "Member of %s" % source, key,
+   allow_optional=allow_optional)
 check_type(expr_info, "Member '%s' of %s" % (key, source), value,
allow_array=True,
allowed_metas=['built-in', 'union', 'alternate', 'struct',
   'enum'],
-   allow_dict=True)
+   allow_dict=True, allow_optional=True)

 def check_command(expr, expr_info):
 name = expr['command']
 check_type(expr_info, "'data' for command '%s'" % name,
expr.get('data'),
-   allowed_metas=['union', 'struct'])
+   allowed_metas=['union', 'struct'], allow_optional=True)
 check_type(expr_info, "'returns' for command '%s'" % name,
expr.get('returns'), allow_array=True,
allowed_metas=['built-in', 'union', 'alternate', 'struct',
-  'enum'])
+  'enum'], allow_optional=True)

 def check_event(expr, expr_info):
 global events
@@ -345,7 +367,8 @@ def check_event(expr, expr_info):
 % name)
 events.append(name)
 check_type(expr_info, "'data' for event '%s'" % name,
-   expr.get('data'), allowed_metas=['union', 'struct'])
+   expr.get('data'), allowed_metas=['union', 'struct'],
+   allow_optional=True)
 if params:
 for argname, argentry, optional, structured in parse_args(params):
 if structured:
@@ -385,12 +408,10 @@ def check_union(expr, expr_info):
 "Base '%s' is not a valid base type"
 % base)

-# The value of member 'discriminator' must name a member of the
-# base type.
-if not isinstance(discriminator, str):
-raise QAPIExprError(expr_info,
-"Flat union '%s' must have a string "
-"discriminator field" % name)
+# The value of member 'discriminator' must name a non-optional
+# member

[Qemu-devel] [PATCH v5 17/28] qapi: Allow true, false and null in schema json

2015-03-24 Thread Eric Blake
From: Fam Zheng 

In the near term, we will use it for a sensible-looking
'gen':false inside command declarations, instead of the
current ugly 'gen':'no'.

In the long term, it will allow conversion from shorthand
with defaults mentioned only in side-band documentation:
 'data':{'*flag':'bool', '*string':'str'}
into an explicit default value documentation, as in:
 'data':{'flag':{'type':'bool', 'optional':true, 'default':true},
 'string':{'type':'str', 'optional':true, 'default':null}}

We still don't parse integer values (also necessary before
we can allow explicit defaults), but that can come in a later
series.

Update the testsuite to match an improved error message.

Signed-off-by: Fam Zheng 
Signed-off-by: Eric Blake 
---
 scripts/qapi.py  | 21 ++---
 tests/qapi-schema/bad-type-bool.err  |  2 +-
 tests/qapi-schema/bad-type-bool.json |  1 -
 3 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 5d0dc91..6ed6a34 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -158,6 +158,20 @@ class QAPISchema:
 return
 else:
 string += ch
+elif self.tok in "tfn":
+val = self.src[self.cursor - 1:]
+if val.startswith("true"):
+self.val = True
+self.cursor += 3
+return
+elif val.startswith("false"):
+self.val = False
+self.cursor += 4
+return
+elif val.startswith("null"):
+self.val = None
+self.cursor += 3
+return
 elif self.tok == '\n':
 if self.cursor == len(self.src):
 self.tok = None
@@ -197,8 +211,9 @@ class QAPISchema:
 if self.tok == ']':
 self.accept()
 return expr
-if not self.tok in [ '{', '[', "'" ]:
-raise QAPISchemaError(self, 'Expected "{", "[", "]" or string')
+if not self.tok in "{['tfn":
+raise QAPISchemaError(self, 'Expected "{", "[", "]", string, '
+  'boolean or "null"')
 while True:
 expr.append(self.get_expr(True))
 if self.tok == ']':
@@ -217,7 +232,7 @@ class QAPISchema:
 elif self.tok == '[':
 self.accept()
 expr = self.get_values()
-elif self.tok == "'":
+elif self.tok in "'tfn":
 expr = self.val
 self.accept()
 else:
diff --git a/tests/qapi-schema/bad-type-bool.err 
b/tests/qapi-schema/bad-type-bool.err
index badb7c2..de6168c 100644
--- a/tests/qapi-schema/bad-type-bool.err
+++ b/tests/qapi-schema/bad-type-bool.err
@@ -1 +1 @@
-tests/qapi-schema/bad-type-bool.json:3:11: Stray "t"
+tests/qapi-schema/bad-type-bool.json:2: 'type' key must have a string value
diff --git a/tests/qapi-schema/bad-type-bool.json 
b/tests/qapi-schema/bad-type-bool.json
index 22d6369..e1e9fb0 100644
--- a/tests/qapi-schema/bad-type-bool.json
+++ b/tests/qapi-schema/bad-type-bool.json
@@ -1,3 +1,2 @@
 # we reject an expression with a metatype that is not a string
-# FIXME: once the parser understands bool inputs, improve the error message
 { 'type': true, 'data': { } }
-- 
2.1.0




Re: [Qemu-devel] [PATCH for-2.3 0/3] Contain drive_get() misuse

2015-03-24 Thread Paolo Bonzini


On 24/03/2015 21:03, Markus Armbruster wrote:
> * Of the sysbus devices only "xlnx.xps-uartlite" seems to be available
>   with the machines that support -device for sysbus devices (ppce500 and
>   pseries-*).  When I try to -device it there, I get "Device
>   xlnx.xps-uartlite is not supported by this machine yet."  I'll ask
>   Alex to confirm.  I'll prepare a patch that sets
>   cannot_instantiate_with_device_add_yet for the unavailable ones to
>   keep them unavailable, just like for the drive_get() abusers.

Right, only specific sysbus devices can be added with -device, because
there is board-specific code to describe the device in the device tree.

Paolo



[Qemu-devel] [PATCH v5 25/28] qapi: Drop tests for inline nested structs

2015-03-24 Thread Eric Blake
A future patch will be using a 'name':{dictionary} entry in the
QAPI schema to specify a default value for an optional argument;
but existing use of inline nested structs conflicts with that goal.
This patch fixes the testsuite to avoid inline nested types, by
breaking the nesting into explicit types; it means that the type
is now boxed instead of unboxed in C code, but makes no difference
on the wire.  When touching code to add new allocations, also
convert existing allocations to consistently prefer typesafe
g_new0 over g_malloc0.

Signed-off-by: Eric Blake 
---
 tests/qapi-schema/qapi-schema-test.json | 12 ++--
 tests/qapi-schema/qapi-schema-test.out  |  8 +++--
 tests/test-qmp-commands.c   | 17 ++-
 tests/test-qmp-input-visitor.c  | 14 +
 tests/test-qmp-output-visitor.c | 44 +++
 tests/test-visitor-serialization.c  | 53 ++---
 6 files changed, 87 insertions(+), 61 deletions(-)

diff --git a/tests/qapi-schema/qapi-schema-test.json 
b/tests/qapi-schema/qapi-schema-test.json
index fb6a350..7aeb490 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -14,11 +14,17 @@
   'base': 'UserDefZero',
   'data': { 'string': 'str', '*enum1': 'EnumOne' } }

+{ 'type': 'UserDefTwoDictDict',
+  'data': { 'userdef': 'UserDefOne', 'string': 'str' } }
+
+{ 'type': 'UserDefTwoDict',
+  'data': { 'string1': 'str',
+'dict2': 'UserDefTwoDictDict',
+'*dict3': 'UserDefTwoDictDict' } }
+
 { 'type': 'UserDefTwo',
   'data': { 'string0': 'str',
-'dict1': { 'string1': 'str',
-   'dict2': { 'userdef': 'UserDefOne', 'string': 'str' },
-   '*dict3': { 'userdef': 'UserDefOne', 'string': 'str' } 
} } }
+'dict1': 'UserDefTwoDict' } }

 # for testing unions
 { 'type': 'UserDefA',
diff --git a/tests/qapi-schema/qapi-schema-test.out 
b/tests/qapi-schema/qapi-schema-test.out
index 4d73bc0..251f6f1 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -2,7 +2,9 @@
  OrderedDict([('type', 'NestedEnumsOne'), ('data', OrderedDict([('enum1', 
'EnumOne'), ('*enum2', 'EnumOne'), ('enum3', 'EnumOne'), ('*enum4', 
'EnumOne')]))]),
  OrderedDict([('type', 'UserDefZero'), ('data', OrderedDict([('integer', 
'int')]))]),
  OrderedDict([('type', 'UserDefOne'), ('base', 'UserDefZero'), ('data', 
OrderedDict([('string', 'str'), ('*enum1', 'EnumOne')]))]),
- OrderedDict([('type', 'UserDefTwo'), ('data', OrderedDict([('string0', 
'str'), ('dict1', OrderedDict([('string1', 'str'), ('dict2', 
OrderedDict([('userdef', 'UserDefOne'), ('string', 'str')])), ('*dict3', 
OrderedDict([('userdef', 'UserDefOne'), ('string', 'str')]))]))]))]),
+ OrderedDict([('type', 'UserDefTwoDictDict'), ('data', 
OrderedDict([('userdef', 'UserDefOne'), ('string', 'str')]))]),
+ OrderedDict([('type', 'UserDefTwoDict'), ('data', OrderedDict([('string1', 
'str'), ('dict2', 'UserDefTwoDictDict'), ('*dict3', 'UserDefTwoDictDict')]))]),
+ OrderedDict([('type', 'UserDefTwo'), ('data', OrderedDict([('string0', 
'str'), ('dict1', 'UserDefTwoDict')]))]),
  OrderedDict([('type', 'UserDefA'), ('data', OrderedDict([('boolean', 
'bool')]))]),
  OrderedDict([('type', 'UserDefB'), ('data', OrderedDict([('integer', 
'int')]))]),
  OrderedDict([('type', 'UserDefC'), ('data', OrderedDict([('string1', 'str'), 
('string2', 'str')]))]),
@@ -27,7 +29,9 @@
 [OrderedDict([('type', 'NestedEnumsOne'), ('data', OrderedDict([('enum1', 
'EnumOne'), ('*enum2', 'EnumOne'), ('enum3', 'EnumOne'), ('*enum4', 
'EnumOne')]))]),
  OrderedDict([('type', 'UserDefZero'), ('data', OrderedDict([('integer', 
'int')]))]),
  OrderedDict([('type', 'UserDefOne'), ('base', 'UserDefZero'), ('data', 
OrderedDict([('string', 'str'), ('*enum1', 'EnumOne')]))]),
- OrderedDict([('type', 'UserDefTwo'), ('data', OrderedDict([('string0', 
'str'), ('dict1', OrderedDict([('string1', 'str'), ('dict2', 
OrderedDict([('userdef', 'UserDefOne'), ('string', 'str')])), ('*dict3', 
OrderedDict([('userdef', 'UserDefOne'), ('string', 'str')]))]))]))]),
+ OrderedDict([('type', 'UserDefTwoDictDict'), ('data', 
OrderedDict([('userdef', 'UserDefOne'), ('string', 'str')]))]),
+ OrderedDict([('type', 'UserDefTwoDict'), ('data', OrderedDict([('string1', 
'str'), ('dict2', 'UserDefTwoDictDict'), ('*dict3', 'UserDefTwoDictDict')]))]),
+ OrderedDict([('type', 'UserDefTwo'), ('data', OrderedDict([('string0', 
'str'), ('dict1', 'UserDefTwoDict')]))]),
  OrderedDict([('type', 'UserDefA'), ('data', OrderedDict([('boolean', 
'bool')]))]),
  OrderedDict([('type', 'UserDefB'), ('data', OrderedDict([('integer', 
'int')]))]),
  OrderedDict([('type', 'UserDefC'), ('data', OrderedDict([('string1', 'str'), 
('string2', 'str')]))]),
diff --git a/tests/test-qmp-commands.c b/tests/test-qmp-commands.c
index 9189cd2..dc199d3 100644
--- a/tests/test-qmp-commands.c
+++ b/tests/test-qmp-commands.c
@@ 

Re: [Qemu-devel] [PATCH v5 20/45] Modify savevm handlers for postcopy

2015-03-24 Thread Dr. David Alan Gilbert
* David Gibson (da...@gibson.dropbear.id.au) wrote:
> On Fri, Mar 20, 2015 at 12:37:59PM +, Dr. David Alan Gilbert wrote:
> > * David Gibson (da...@gibson.dropbear.id.au) wrote:
> > > On Fri, Mar 13, 2015 at 10:19:54AM +, Dr. David Alan Gilbert wrote:
> > > > * David Gibson (da...@gibson.dropbear.id.au) wrote:
> > > > > On Wed, Feb 25, 2015 at 04:51:43PM +, Dr. David Alan Gilbert 
> > > > > (git) wrote:
> > > > > > From: "Dr. David Alan Gilbert" 
> > > > > > 
> > > > > > Modify save_live_pending to return separate postcopiable and
> > > > > > non-postcopiable counts.
> > > > > > 
> > > > > > Add 'can_postcopy' to allow a device to state if it can postcopy
> > > > > 
> > > > > What's the purpose of the can_postcopy callback?  There are no callers
> > > > > in this patch - is it still necessary with the change to
> > > > > save_live_pending?
> > > > 
> > > > The patch 'qemu_savevm_state_complete: Postcopy changes' uses
> > > > it in qemu_savevm_state_postcopy_complete and qemu_savevm_state_complete
> > > > to decide which devices must be completed at that point.
> > > 
> > > Couldn't they check for non-zero postcopiable state from
> > > save_live_pending instead?
> > 
> > That would be a bit weird.
> > 
> > At the moment for each device we call the:
> >save_live_setup method (from qemu_savevm_state_begin)
> > 
> >0...multiple times we call:
> >save_live_pending
> >save_live_iterate
> > 
> >and then we always call
> >save_live_complete
> > 
> > 
> > To my mind we have to call save_live_complete for any device
> > that we've called save_live_setup on (maybe it allocated something
> > in _setup that it clears up in _complete).
> > 
> > save_live_pending could perfectly well return 0 remaining at the end of
> > the migrate for our device, and thus if we used that then we wouldn't
> > call save_live_complete.
> 
> Um.. I don't follow.  I was suggesting that at the precopy->postcopy
> transition point you call save_live_complete for everything that
> reports 0 post-copiable state.
> 
> 
> Then again, a different approach would be to split the
> save_live_complete hook into (possibly NULL) "complete precopy" and
> "complete postcopy" hooks.  The core would ensure that every chunk of
> state has both completion hooks called (unless NULL).  That might also
> address my concerns about the no longer entirely accurate
> save_live_complete function name.

OK, that one I prefer.  Are you OK with:
qemu_savevm_state_complete_precopy
   calls -> save_live_complete_precopy

qemu_savevm_state_complete_postcopy
   calls -> save_live_complete_postcopy

?

Dave

> 
> -- 
> 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


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



[Qemu-devel] [PATCH v5 24/28] qapi: Merge UserDefTwo and UserDefNested in tests

2015-03-24 Thread Eric Blake
In the testsuite, UserDefTwo and UserDefNested were identical
types other than the member names.  Reduce code duplication by
having just one type, and choose names that also favor reuse.
This will also make it easier for a later patch to get rid of
inline nested types in QAPI; it means that the type is now boxed
instead of unboxed in C code, but has no difference to the QMP
wire protocol.  When touching code to add new allocations, also
convert existing allocations to consistently prefer typesafe
g_new0 over g_malloc0.

Ensure that 'make check-qapi-schema check-unit' still passes.

Signed-off-by: Eric Blake 
---
 tests/qapi-schema/qapi-schema-test.json | 10 +
 tests/qapi-schema/qapi-schema-test.out  |  6 +--
 tests/test-qmp-commands.c   | 32 +++
 tests/test-qmp-input-strict.c   | 17 
 tests/test-qmp-input-visitor.c  | 17 
 tests/test-qmp-output-visitor.c | 48 +++---
 tests/test-visitor-serialization.c  | 71 +
 7 files changed, 100 insertions(+), 101 deletions(-)

diff --git a/tests/qapi-schema/qapi-schema-test.json 
b/tests/qapi-schema/qapi-schema-test.json
index dec8a7c..fb6a350 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -15,16 +15,10 @@
   'data': { 'string': 'str', '*enum1': 'EnumOne' } }

 { 'type': 'UserDefTwo',
-  'data': { 'string': 'str',
-'dict': { 'string': 'str',
-  'dict': { 'userdef': 'UserDefOne', 'string': 'str' },
-  '*dict2': { 'userdef': 'UserDefOne', 'string': 'str' } } 
} }
-
-{ 'type': 'UserDefNested',
   'data': { 'string0': 'str',
 'dict1': { 'string1': 'str',
-   'dict2': { 'userdef1': 'UserDefOne', 'string2': 'str' },
-   '*dict3': { 'userdef2': 'UserDefOne', 'string3': 'str' 
} } } }
+   'dict2': { 'userdef': 'UserDefOne', 'string': 'str' },
+   '*dict3': { 'userdef': 'UserDefOne', 'string': 'str' } 
} } }

 # for testing unions
 { 'type': 'UserDefA',
diff --git a/tests/qapi-schema/qapi-schema-test.out 
b/tests/qapi-schema/qapi-schema-test.out
index 313ecf3..4d73bc0 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -2,8 +2,7 @@
  OrderedDict([('type', 'NestedEnumsOne'), ('data', OrderedDict([('enum1', 
'EnumOne'), ('*enum2', 'EnumOne'), ('enum3', 'EnumOne'), ('*enum4', 
'EnumOne')]))]),
  OrderedDict([('type', 'UserDefZero'), ('data', OrderedDict([('integer', 
'int')]))]),
  OrderedDict([('type', 'UserDefOne'), ('base', 'UserDefZero'), ('data', 
OrderedDict([('string', 'str'), ('*enum1', 'EnumOne')]))]),
- OrderedDict([('type', 'UserDefTwo'), ('data', OrderedDict([('string', 'str'), 
('dict', OrderedDict([('string', 'str'), ('dict', OrderedDict([('userdef', 
'UserDefOne'), ('string', 'str')])), ('*dict2', OrderedDict([('userdef', 
'UserDefOne'), ('string', 'str')]))]))]))]),
- OrderedDict([('type', 'UserDefNested'), ('data', OrderedDict([('string0', 
'str'), ('dict1', OrderedDict([('string1', 'str'), ('dict2', 
OrderedDict([('userdef1', 'UserDefOne'), ('string2', 'str')])), ('*dict3', 
OrderedDict([('userdef2', 'UserDefOne'), ('string3', 'str')]))]))]))]),
+ OrderedDict([('type', 'UserDefTwo'), ('data', OrderedDict([('string0', 
'str'), ('dict1', OrderedDict([('string1', 'str'), ('dict2', 
OrderedDict([('userdef', 'UserDefOne'), ('string', 'str')])), ('*dict3', 
OrderedDict([('userdef', 'UserDefOne'), ('string', 'str')]))]))]))]),
  OrderedDict([('type', 'UserDefA'), ('data', OrderedDict([('boolean', 
'bool')]))]),
  OrderedDict([('type', 'UserDefB'), ('data', OrderedDict([('integer', 
'int')]))]),
  OrderedDict([('type', 'UserDefC'), ('data', OrderedDict([('string1', 'str'), 
('string2', 'str')]))]),
@@ -28,8 +27,7 @@
 [OrderedDict([('type', 'NestedEnumsOne'), ('data', OrderedDict([('enum1', 
'EnumOne'), ('*enum2', 'EnumOne'), ('enum3', 'EnumOne'), ('*enum4', 
'EnumOne')]))]),
  OrderedDict([('type', 'UserDefZero'), ('data', OrderedDict([('integer', 
'int')]))]),
  OrderedDict([('type', 'UserDefOne'), ('base', 'UserDefZero'), ('data', 
OrderedDict([('string', 'str'), ('*enum1', 'EnumOne')]))]),
- OrderedDict([('type', 'UserDefTwo'), ('data', OrderedDict([('string', 'str'), 
('dict', OrderedDict([('string', 'str'), ('dict', OrderedDict([('userdef', 
'UserDefOne'), ('string', 'str')])), ('*dict2', OrderedDict([('userdef', 
'UserDefOne'), ('string', 'str')]))]))]))]),
- OrderedDict([('type', 'UserDefNested'), ('data', OrderedDict([('string0', 
'str'), ('dict1', OrderedDict([('string1', 'str'), ('dict2', 
OrderedDict([('userdef1', 'UserDefOne'), ('string2', 'str')])), ('*dict3', 
OrderedDict([('userdef2', 'UserDefOne'), ('string3', 'str')]))]))]))]),
+ OrderedDict([('type', 'UserDefTwo'), ('data', OrderedDict([('string0', 
'str'), ('dict1', OrderedDict([('string1', 'str'), ('dict2', 
OrderedDict([('userdef', 'UserDefO

[Qemu-devel] [PATCH v5 11/28] qapi: Rename anonymous union type in test

2015-03-24 Thread Eric Blake
Reduce churn in the future patch that replaces anonymous unions
with a new metatype 'alternate' by changing 'AnonUnion' to
'Alternate'.

Signed-off-by: Eric Blake 
---
 tests/qapi-schema/qapi-schema-test.json |  2 +-
 tests/qapi-schema/qapi-schema-test.out  |  4 ++--
 tests/test-qmp-input-strict.c   | 28 ++--
 tests/test-qmp-input-visitor.c  | 16 
 tests/test-qmp-output-visitor.c | 16 
 5 files changed, 33 insertions(+), 33 deletions(-)

diff --git a/tests/qapi-schema/qapi-schema-test.json 
b/tests/qapi-schema/qapi-schema-test.json
index b134f3f..e1d35e1 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -53,7 +53,7 @@
   'discriminator': 'enum1',
   'data': { 'value1' : 'UserDefC', 'value2' : 'UserDefB', 'value3' : 
'UserDefA' } }

-{ 'union': 'UserDefAnonUnion',
+{ 'union': 'UserDefAlternate',
   'discriminator': {},
   'data': { 'uda': 'UserDefA', 's': 'str', 'i': 'int' } }

diff --git a/tests/qapi-schema/qapi-schema-test.out 
b/tests/qapi-schema/qapi-schema-test.out
index 664ae7b..b55ab8d 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -10,7 +10,7 @@
  OrderedDict([('type', 'UserDefUnionBase'), ('data', OrderedDict([('string', 
'str'), ('enum1', 'EnumOne')]))]),
  OrderedDict([('union', 'UserDefFlatUnion'), ('base', 'UserDefUnionBase'), 
('discriminator', 'enum1'), ('data', OrderedDict([('value1', 'UserDefA'), 
('value2', 'UserDefB'), ('value3', 'UserDefB')]))]),
  OrderedDict([('union', 'UserDefFlatUnion2'), ('base', 'UserDefUnionBase'), 
('discriminator', 'enum1'), ('data', OrderedDict([('value1', 'UserDefC'), 
('value2', 'UserDefB'), ('value3', 'UserDefA')]))]),
- OrderedDict([('union', 'UserDefAnonUnion'), ('discriminator', OrderedDict()), 
('data', OrderedDict([('uda', 'UserDefA'), ('s', 'str'), ('i', 'int')]))]),
+ OrderedDict([('union', 'UserDefAlternate'), ('discriminator', OrderedDict()), 
('data', OrderedDict([('uda', 'UserDefA'), ('s', 'str'), ('i', 'int')]))]),
  OrderedDict([('union', 'UserDefNativeListUnion'), ('data', 
OrderedDict([('integer', ['int']), ('s8', ['int8']), ('s16', ['int16']), 
('s32', ['int32']), ('s64', ['int64']), ('u8', ['uint8']), ('u16', ['uint16']), 
('u32', ['uint32']), ('u64', ['uint64']), ('number', ['number']), ('boolean', 
['bool']), ('string', ['str']), ('sizes', ['size'])]))]),
  OrderedDict([('command', 'user_def_cmd'), ('data', OrderedDict())]),
  OrderedDict([('command', 'user_def_cmd1'), ('data', OrderedDict([('ud1a', 
'UserDefOne')]))]),
@@ -23,7 +23,7 @@
  OrderedDict([('event', 'EVENT_C'), ('data', OrderedDict([('*a', 'int'), 
('*b', 'UserDefOne'), ('c', 'str')]))]),
  OrderedDict([('event', 'EVENT_D'), ('data', OrderedDict([('a', 
'EventStructOne'), ('b', 'str'), ('*c', 'str'), ('*enum3', 'EnumOne')]))])]
 [{'enum_name': 'EnumOne', 'enum_values': ['value1', 'value2', 'value3']},
- {'enum_name': 'UserDefAnonUnionKind', 'enum_values': None},
+ {'enum_name': 'UserDefAlternateKind', 'enum_values': None},
  {'enum_name': 'UserDefNativeListUnionKind', 'enum_values': None}]
 [OrderedDict([('type', 'NestedEnumsOne'), ('data', OrderedDict([('enum1', 
'EnumOne'), ('*enum2', 'EnumOne'), ('enum3', 'EnumOne'), ('*enum4', 
'EnumOne')]))]),
  OrderedDict([('type', 'UserDefZero'), ('data', OrderedDict([('integer', 
'int')]))]),
diff --git a/tests/test-qmp-input-strict.c b/tests/test-qmp-input-strict.c
index 53134a1..4b53560 100644
--- a/tests/test-qmp-input-strict.c
+++ b/tests/test-qmp-input-strict.c
@@ -173,18 +173,18 @@ static void test_validate_union_flat(TestInputVisitorData 
*data,
 qapi_free_UserDefFlatUnion(tmp);
 }

-static void test_validate_union_anon(TestInputVisitorData *data,
- const void *unused)
+static void test_validate_alternate(TestInputVisitorData *data,
+const void *unused)
 {
-UserDefAnonUnion *tmp = NULL;
+UserDefAlternate *tmp = NULL;
 Visitor *v;
 Error *err = NULL;

 v = validate_test_init(data, "42");

-visit_type_UserDefAnonUnion(v, &tmp, NULL, &err);
+visit_type_UserDefAlternate(v, &tmp, NULL, &err);
 g_assert(!err);
-qapi_free_UserDefAnonUnion(tmp);
+qapi_free_UserDefAlternate(tmp);
 }

 static void test_validate_fail_struct(TestInputVisitorData *data,
@@ -276,18 +276,18 @@ static void 
test_validate_fail_union_flat_no_discrim(TestInputVisitorData *data,
 qapi_free_UserDefFlatUnion2(tmp);
 }

-static void test_validate_fail_union_anon(TestInputVisitorData *data,
-  const void *unused)
+static void test_validate_fail_alternate(TestInputVisitorData *data,
+ const void *unused)
 {
-UserDefAnonUnion *tmp = NULL;
+UserDefAlternate *tmp = NULL;
 Visitor *v;
 Error *err = NULL;

 v = validate_test_init(data, "3.14");

-visit_type_UserDefAnonUnio

[Qemu-devel] [PATCH v5 22/28] qapi: Whitelist commands that don't return dictionary

2015-03-24 Thread Eric Blake
...or an array of dictionaries.  Although we have to cater to
existing commands, returning a non-dictionary means the command
is not extensible (no new name/value pairs can be added if more
information must be returned in parallel).  By making the
whitelist explicit, any new command that falls foul of this
practice will have to be self-documenting, which will encourage
developers to either justify the action or rework the design to
use a dictionary after all.

Signed-off-by: Eric Blake 
---
 scripts/qapi.py  | 30 --
 tests/qapi-schema/returns-alternate.err  |  1 +
 tests/qapi-schema/returns-alternate.exit |  2 +-
 tests/qapi-schema/returns-alternate.json |  2 +-
 tests/qapi-schema/returns-alternate.out  |  4 
 tests/qapi-schema/returns-int.json   |  3 ++-
 tests/qapi-schema/returns-int.out|  2 +-
 tests/qapi-schema/returns-whitelist.err  |  1 +
 tests/qapi-schema/returns-whitelist.exit |  2 +-
 tests/qapi-schema/returns-whitelist.json |  2 +-
 tests/qapi-schema/returns-whitelist.out  |  7 ---
 11 files changed, 37 insertions(+), 19 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index ed5385a..9421431 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -33,6 +33,30 @@ builtin_types = {
 'size': 'QTYPE_QINT',
 }

+# Whitelist of commands allowed to return a non-dictionary
+returns_whitelist = [
+# From QMP:
+'human-monitor-command',
+'query-migrate-cache-size',
+'query-tpm-models',
+'query-tpm-types',
+'ringbuf-read',
+
+# From QGA:
+'guest-file-open',
+'guest-fsfreeze-freeze',
+'guest-fsfreeze-freeze-list',
+'guest-fsfreeze-status',
+'guest-fsfreeze-thaw',
+'guest-get-time',
+'guest-set-vcpus',
+'guest-sync',
+'guest-sync-delimited',
+
+# From qapi-schema-test:
+'user_def_cmd3',
+]
+
 enum_types = []
 struct_types = []
 union_types = []
@@ -350,10 +374,12 @@ def check_command(expr, expr_info):
 check_type(expr_info, "'data' for command '%s'" % name,
expr.get('data'),
allowed_metas=['union', 'struct'], allow_optional=True)
+returns_meta = ['union', 'struct']
+if name in returns_whitelist:
+returns_meta += ['built-in', 'alternate', 'enum']
 check_type(expr_info, "'returns' for command '%s'" % name,
expr.get('returns'), allow_array=True,
-   allowed_metas=['built-in', 'union', 'alternate', 'struct',
-  'enum'], allow_optional=True)
+   allowed_metas=returns_meta, allow_optional=True)

 def check_event(expr, expr_info):
 global events
diff --git a/tests/qapi-schema/returns-alternate.err 
b/tests/qapi-schema/returns-alternate.err
index e69de29..dfbb419 100644
--- a/tests/qapi-schema/returns-alternate.err
+++ b/tests/qapi-schema/returns-alternate.err
@@ -0,0 +1 @@
+tests/qapi-schema/returns-alternate.json:3: 'returns' for command 'oops' 
cannot use alternate type 'Alt'
diff --git a/tests/qapi-schema/returns-alternate.exit 
b/tests/qapi-schema/returns-alternate.exit
index 573541a..d00491f 100644
--- a/tests/qapi-schema/returns-alternate.exit
+++ b/tests/qapi-schema/returns-alternate.exit
@@ -1 +1 @@
-0
+1
diff --git a/tests/qapi-schema/returns-alternate.json 
b/tests/qapi-schema/returns-alternate.json
index b3b91fd..972390c 100644
--- a/tests/qapi-schema/returns-alternate.json
+++ b/tests/qapi-schema/returns-alternate.json
@@ -1,3 +1,3 @@
-# FIXME: we should reject returns if it is an alternate type
+# we reject returns if it is an alternate type
 { 'alternate': 'Alt', 'data': { 'a': 'int', 'b': 'str' } }
 { 'command': 'oops', 'returns': 'Alt' }
diff --git a/tests/qapi-schema/returns-alternate.out 
b/tests/qapi-schema/returns-alternate.out
index 8a03ed3..e69de29 100644
--- a/tests/qapi-schema/returns-alternate.out
+++ b/tests/qapi-schema/returns-alternate.out
@@ -1,4 +0,0 @@
-[OrderedDict([('alternate', 'Alt'), ('data', OrderedDict([('a', 'int'), ('b', 
'str')]))]),
- OrderedDict([('command', 'oops'), ('returns', 'Alt')])]
-[{'enum_name': 'AltKind', 'enum_values': None}]
-[]
diff --git a/tests/qapi-schema/returns-int.json 
b/tests/qapi-schema/returns-int.json
index 7888fb1..870ec63 100644
--- a/tests/qapi-schema/returns-int.json
+++ b/tests/qapi-schema/returns-int.json
@@ -1,2 +1,3 @@
 # It is okay (although not extensible) to return a non-dictionary
-{ 'command': 'okay', 'returns': 'int' }
+# But to make it work, the name must be in a whitelist
+{ 'command': 'guest-get-time', 'returns': 'int' }
diff --git a/tests/qapi-schema/returns-int.out 
b/tests/qapi-schema/returns-int.out
index 36b00a9..70b3ac5 100644
--- a/tests/qapi-schema/returns-int.out
+++ b/tests/qapi-schema/returns-int.out
@@ -1,3 +1,3 @@
-[OrderedDict([('command', 'okay'), ('returns', 'int')])]
+[OrderedDict([('command', 'guest-get-time'), ('returns', 'int')])]
 []
 []
diff --git a/tests/qapi-schema/returns-whitelist.err 
b/tests/qapi-schema/returns-whitelist.

[Qemu-devel] [PATCH v5 23/28] qapi: More rigorous checking for type safety bypass

2015-03-24 Thread Eric Blake
Now that we have a way to validate every type, we can also be
stricter about enforcing that callers that want to bypass
type safety in generated code.  Prior to this patch, it didn't
matter what value was associated with the key 'gen', but it
looked odd that 'gen':'yes' could result in bypassing the
generated code.  These changes also enforce the changes made
earlier in the series for documentation and consolidation of
using '**' as the wildcard type, as well as 'gen':false as the
canonical spelling for requesting type bypass.

Signed-off-by: Eric Blake 
---
 scripts/qapi.py| 23 ++-
 tests/qapi-schema/type-bypass-bad-gen.err  |  1 +
 tests/qapi-schema/type-bypass-bad-gen.exit |  2 +-
 tests/qapi-schema/type-bypass-bad-gen.json |  2 +-
 tests/qapi-schema/type-bypass-bad-gen.out  |  3 ---
 tests/qapi-schema/type-bypass-no-gen.err   |  1 +
 tests/qapi-schema/type-bypass-no-gen.exit  |  2 +-
 tests/qapi-schema/type-bypass-no-gen.json  |  2 +-
 tests/qapi-schema/type-bypass-no-gen.out   |  3 ---
 9 files changed, 24 insertions(+), 15 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 9421431..800e8e4 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -321,13 +321,14 @@ def check_name(expr_info, source, name, allow_optional = 
False):
 "%s uses invalid name '%s'" % (source, name))

 def check_type(expr_info, source, data, allow_array = False,
-   allowed_metas = [], allow_dict = True, allow_optional = False):
+   allowed_metas = [], allow_dict = True, allow_optional = False,
+   allow_star = False):
 global all_names

 if data is None:
 return

-if data == '**':
+if allow_star and data == '**':
 return

 # Check if array type for data is okay
@@ -343,6 +344,10 @@ def check_type(expr_info, source, data, allow_array = 
False,

 # Check if type name for data is okay
 if isinstance(data, str):
+if data == '**':
+raise QAPIExprError(expr_info,
+"%s uses '**' but did not request 'gen':false"
+% source)
 if not data in all_names:
 raise QAPIExprError(expr_info,
 "%s uses unknown type '%s'"
@@ -367,19 +372,23 @@ def check_type(expr_info, source, data, allow_array = 
False,
allow_array=True,
allowed_metas=['built-in', 'union', 'alternate', 'struct',
   'enum'],
-   allow_dict=True, allow_optional=True)
+   allow_dict=True, allow_optional=True, allow_star=allow_star)

 def check_command(expr, expr_info):
 name = expr['command']
+allow_star = expr.has_key('gen')
+
 check_type(expr_info, "'data' for command '%s'" % name,
expr.get('data'),
-   allowed_metas=['union', 'struct'], allow_optional=True)
+   allowed_metas=['union', 'struct'], allow_optional=True,
+   allow_star=allow_star)
 returns_meta = ['union', 'struct']
 if name in returns_whitelist:
 returns_meta += ['built-in', 'alternate', 'enum']
 check_type(expr_info, "'returns' for command '%s'" % name,
expr.get('returns'), allow_array=True,
-   allowed_metas=returns_meta, allow_optional=True)
+   allowed_metas=returns_meta, allow_optional=True,
+   allow_star=allow_star)

 def check_event(expr, expr_info):
 global events
@@ -574,6 +583,10 @@ def check_keys(expr_elem, meta, required, optional=[]):
 raise QAPIExprError(info,
 "%s '%s' has unknown key '%s'"
 % (meta, name, key))
+if (key == 'gen' or key == 'success-response') and value != False:
+raise QAPIExprError(info,
+"'%s' of %s '%s' should only use false value"
+% (key, meta, name))
 for key in required:
 if not expr.has_key(key):
 raise QAPIExprError(info,
diff --git a/tests/qapi-schema/type-bypass-bad-gen.err 
b/tests/qapi-schema/type-bypass-bad-gen.err
index e69de29..a83c3c6 100644
--- a/tests/qapi-schema/type-bypass-bad-gen.err
+++ b/tests/qapi-schema/type-bypass-bad-gen.err
@@ -0,0 +1 @@
+tests/qapi-schema/type-bypass-bad-gen.json:2: 'gen' of command 'foo' should 
only use false value
diff --git a/tests/qapi-schema/type-bypass-bad-gen.exit 
b/tests/qapi-schema/type-bypass-bad-gen.exit
index 573541a..d00491f 100644
--- a/tests/qapi-schema/type-bypass-bad-gen.exit
+++ b/tests/qapi-schema/type-bypass-bad-gen.exit
@@ -1 +1 @@
-0
+1
diff --git a/tests/qapi-schema/type-bypass-bad-gen.json 
b/tests/qapi-schema/type-bypass-bad-gen.json
index bb70bee..e8dec34 100644
--- a/tests/qapi-schema/type-bypass-bad-gen.json
+++ b/tests/qapi-schema/type-bypass-bad-gen.json
@@ -1,2 +1,2 @@
-# FIXME: 'gen' 

[Qemu-devel] [PATCH v5 12/28] qapi: Introduce 'alternate' to replace anonymous union

2015-03-24 Thread Eric Blake
Rather than special-casing "'union':'foo','alternate':{}" as an
unusual union that can represent a non-dictionary, it is nicer
to designate a separate meta-type "'alternate':'foo'" for the
purpose.  This involves a lot of documentation tweaks and fallout
from .json files, but I already split as much as possible into
earlier commits.

Signed-off-by: Eric Blake 
---
 docs/qapi-code-gen.txt | 63 +++---
 qapi/block-core.json   |  6 +--
 scripts/qapi-types.py  | 26 ++---
 scripts/qapi-visit.py  | 17 +++---
 scripts/qapi.py| 41 +++---
 tests/qapi-schema/alternate-array.err  |  2 +-
 tests/qapi-schema/alternate-array.json |  3 +-
 tests/qapi-schema/alternate-base.err   |  2 +-
 tests/qapi-schema/alternate-base.json  |  5 +-
 tests/qapi-schema/alternate-clash.err  |  2 +-
 tests/qapi-schema/alternate-clash.json |  5 +-
 tests/qapi-schema/alternate-conflict-dict.err  |  2 +-
 tests/qapi-schema/alternate-conflict-dict.json |  5 +-
 tests/qapi-schema/alternate-conflict-string.err|  2 +-
 tests/qapi-schema/alternate-conflict-string.json   |  3 +-
 tests/qapi-schema/alternate-good.json  |  5 +-
 tests/qapi-schema/alternate-good.out   |  4 +-
 tests/qapi-schema/alternate-nested.err |  2 +-
 tests/qapi-schema/alternate-nested.json|  8 ++-
 tests/qapi-schema/alternate-unknown.err|  2 +-
 tests/qapi-schema/alternate-unknown.json   |  3 +-
 tests/qapi-schema/flat-union-bad-base.err  |  2 +-
 tests/qapi-schema/flat-union-bad-discriminator.err |  2 +-
 .../qapi-schema/flat-union-bad-discriminator.json  |  5 +-
 tests/qapi-schema/flat-union-base-union.err|  2 +-
 tests/qapi-schema/flat-union-base-union.json   |  2 +-
 tests/qapi-schema/flat-union-no-base.err   |  2 +-
 tests/qapi-schema/qapi-schema-test.json|  3 +-
 tests/qapi-schema/qapi-schema-test.out |  2 +-
 tests/qapi-schema/union-invalid-base.err   |  2 +-
 30 files changed, 117 insertions(+), 113 deletions(-)

diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
index ce9c4b9..8792b94 100644
--- a/docs/qapi-code-gen.txt
+++ b/docs/qapi-code-gen.txt
@@ -79,16 +79,16 @@ the definition of complex structs that can have mutually 
recursive
 types, and allows for indefinite nesting of QMP that satisfies the
 schema.  A type name should not be defined more than once.

-There are six top-level expressions recognized by the parser:
-'include', 'command', 'type', 'enum', 'union', and 'event'.  There are
-several built-in types, such as 'int' and 'str'; additionally, the
-top-level expressions can define complex types, enumeration types, and
-several flavors of union types.  The 'command' expression can refer to
-existing types by name, or list an anonymous type as a dictionary.
-Listing a type name inside an array refers to a single-dimension array
-of that type; multi-dimension arrays are not directly supported
-(although an array of a complex struct that contains an array member
-is possible).
+There are seven top-level expressions recognized by the parser:
+'include', 'command', 'type', 'enum', 'union', 'alternate', and
+'event'.  There are several built-in types, such as 'int' and 'str';
+additionally, the top-level expressions can define complex types,
+enumeration types, two flavors of union types, and an alternate type.
+The 'command' expression can refer to existing types by name, or list
+an anonymous type as a dictionary.  Listing a type name inside an
+array refers to a single-dimension array of that type; multi-dimension
+arrays are not directly supported (although an array of a complex
+struct that contains an array member is possible).

 Types, commands, and events share a common namespace.  Therefore,
 generally speaking, type definitions should always use CamelCase for
@@ -159,8 +159,8 @@ Usage: { 'type': 'str', 'data': 'dict', '*base': 
'complex-type-name' }
 A complex type is a dictionary containing a single 'data' key whose
 value is a dictionary.  This corresponds to a struct in C or an Object
 in JSON. Each value of the 'data' dictionary must be the name of a
-complex, enum, union, or built-in type, or a one-element array
-containing a type name.  An example of a complex type is:
+complex, enum, union, alternate, or built-in type, or a one-element
+array containing a type name.  An example of a complex type is:

  { 'type': 'MyType',
'data': { 'member1': 'str', 'member2': 'int', '*member3': 'str' } }
@@ -246,14 +246,12 @@ open-coding the field to be type 'str'.
 Usage: { 'union': 'str', 'data': 'dict' }
 or:{ 'union': 'str', 'data': 'dict', 'base': 'complex-type-name',
  'discriminator': 'enum-member-of-base' }
-or:{ 'union': 'str', 'data': 'dict', '

[Qemu-devel] [PATCH v5 20/28] qapi: More rigourous checking of types

2015-03-24 Thread Eric Blake
Now that we know every expression is valid with regards to
its keys, we can add further tests that those keys refer to
valid types.  With this patch, all uses of a type (the 'data':
of command, type, union, alternate, and event; the 'returns':
of command; the 'base': of type and union) must resolve to an
appropriate subset of metatypes  declared by the current qapi
parse; this includes recursing into each member of a data
dictionary.  Dealing with '**' and nested anonymous structs
will be done in later patches.

Update the testsuite to match improved output.

Signed-off-by: Eric Blake 
---
 scripts/qapi.py  | 94 +---
 tests/qapi-schema/alternate-array.err|  2 +-
 tests/qapi-schema/alternate-nested.err   |  2 +-
 tests/qapi-schema/alternate-unknown.err  |  2 +-
 tests/qapi-schema/bad-base.err   |  1 +
 tests/qapi-schema/bad-base.exit  |  2 +-
 tests/qapi-schema/bad-base.json  |  2 +-
 tests/qapi-schema/bad-base.out   |  4 --
 tests/qapi-schema/data-array-empty.err   |  1 +
 tests/qapi-schema/data-array-empty.exit  |  2 +-
 tests/qapi-schema/data-array-empty.json  |  2 +-
 tests/qapi-schema/data-array-empty.out   |  3 -
 tests/qapi-schema/data-array-unknown.err |  1 +
 tests/qapi-schema/data-array-unknown.exit|  2 +-
 tests/qapi-schema/data-array-unknown.json|  2 +-
 tests/qapi-schema/data-array-unknown.out |  3 -
 tests/qapi-schema/data-int.err   |  1 +
 tests/qapi-schema/data-int.exit  |  2 +-
 tests/qapi-schema/data-int.json  |  2 +-
 tests/qapi-schema/data-int.out   |  3 -
 tests/qapi-schema/data-member-array-bad.err  |  1 +
 tests/qapi-schema/data-member-array-bad.exit |  2 +-
 tests/qapi-schema/data-member-array-bad.json |  2 +-
 tests/qapi-schema/data-member-array-bad.out  |  3 -
 tests/qapi-schema/data-member-unknown.err|  1 +
 tests/qapi-schema/data-member-unknown.exit   |  2 +-
 tests/qapi-schema/data-member-unknown.json   |  2 +-
 tests/qapi-schema/data-member-unknown.out|  3 -
 tests/qapi-schema/data-unknown.err   |  1 +
 tests/qapi-schema/data-unknown.exit  |  2 +-
 tests/qapi-schema/data-unknown.json  |  2 +-
 tests/qapi-schema/data-unknown.out   |  3 -
 tests/qapi-schema/returns-array-bad.err  |  1 +
 tests/qapi-schema/returns-array-bad.exit |  2 +-
 tests/qapi-schema/returns-array-bad.json |  2 +-
 tests/qapi-schema/returns-array-bad.out  |  3 -
 tests/qapi-schema/returns-unknown.err|  1 +
 tests/qapi-schema/returns-unknown.exit   |  2 +-
 tests/qapi-schema/returns-unknown.json   |  2 +-
 tests/qapi-schema/returns-unknown.out|  3 -
 tests/qapi-schema/union-unknown.err  |  1 +
 tests/qapi-schema/union-unknown.exit |  2 +-
 tests/qapi-schema/union-unknown.json |  2 +-
 tests/qapi-schema/union-unknown.out  |  3 -
 44 files changed, 118 insertions(+), 63 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 6ed6a34..c42683b 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -276,6 +276,63 @@ def discriminator_find_enum_define(expr):

 return find_enum(discriminator_type)

+def check_type(expr_info, source, data, allow_array = False,
+   allowed_metas = [], allow_dict = True):
+global all_names
+
+if data is None:
+return
+
+if data == '**':
+return
+
+# Check if array type for data is okay
+if isinstance(data, list):
+if not allow_array:
+raise QAPIExprError(expr_info,
+"%s cannot be an array" % source)
+if len(data) != 1 or not isinstance(data[0], str):
+raise QAPIExprError(expr_info,
+"%s: array type must contain single type name"
+% source)
+data = data[0]
+
+# Check if type name for data is okay
+if isinstance(data, str):
+if not data in all_names:
+raise QAPIExprError(expr_info,
+"%s uses unknown type '%s'"
+% (source, data))
+if not all_names[data] in allowed_metas:
+raise QAPIExprError(expr_info,
+"%s cannot use %s type '%s'"
+% (source, all_names[data], data))
+return
+
+# data is a dictionary, check that each member is okay
+if not isinstance(data, OrderedDict):
+raise QAPIExprError(expr_info,
+"%s should be a dictionary" % source)
+if not allow_dict:
+raise QAPIExprError(expr_info,
+"%s should be a type name" % source)
+for (key, value) in data.items():
+check_type(expr_info, "Member '%s' of %s" % (key, source), value,
+   allow_array=True,
+   allowed_metas=['built-in',

[Qemu-devel] [PATCH v5 26/28] qapi: Drop inline nested type in query-version

2015-03-24 Thread Eric Blake
A future patch will be using a 'name':{dictionary} entry in the
QAPI schema to specify a default value for an optional argument;
but existing use of inline nested structs conflicts with that goal.
This patch fixes one of only two commands relying on nested
types, by breaking the nesting into an explicit type; it means
that the type is now boxed instead of unboxed in C code, but the
QMP wire format is unaffected by this change.

Prefer the safer g_new0() while making the conversion.

Signed-off-by: Eric Blake 
---
 hmp.c|  2 +-
 qapi/common.json | 26 +++---
 qmp.c|  9 +
 3 files changed, 25 insertions(+), 12 deletions(-)

diff --git a/hmp.c b/hmp.c
index f31ae27..c59b823 100644
--- a/hmp.c
+++ b/hmp.c
@@ -60,7 +60,7 @@ void hmp_info_version(Monitor *mon, const QDict *qdict)
 info = qmp_query_version(NULL);

 monitor_printf(mon, "%" PRId64 ".%" PRId64 ".%" PRId64 "%s\n",
-   info->qemu.major, info->qemu.minor, info->qemu.micro,
+   info->qemu->major, info->qemu->minor, info->qemu->micro,
info->package);

 qapi_free_VersionInfo(info);
diff --git a/qapi/common.json b/qapi/common.json
index 63ef3b4..ed3aa57 100644
--- a/qapi/common.json
+++ b/qapi/common.json
@@ -29,15 +29,28 @@
 'DeviceNotActive', 'DeviceNotFound', 'KVMMissingCap' ] }

 ##
+# @VersionTriple
+#
+# A three-part version number.
+#
+# @qemu.major:  The major version number.
+#
+# @qemu.minor:  The minor version number.
+#
+# @qemu.micro:  The micro version number.
+#
+# Since: 2.4
+##
+{ 'type': 'VersionTriple',
+  'data': {'major': 'int', 'minor': 'int', 'micro': 'int'} }
+
+
+##
 # @VersionInfo:
 #
 # A description of QEMU's version.
 #
-# @qemu.major:  The major version of QEMU
-#
-# @qemu.minor:  The minor version of QEMU
-#
-# @qemu.micro:  The micro version of QEMU.  By current convention, a micro
+# @qemu:The version of QEMU.  By current convention, a micro
 #   version of 50 signifies a development branch.  A micro version
 #   greater than or equal to 90 signifies a release candidate for
 #   the next minor version.  A micro version of less than 50
@@ -51,8 +64,7 @@
 # Since: 0.14.0
 ##
 { 'type': 'VersionInfo',
-  'data': {'qemu': {'major': 'int', 'minor': 'int', 'micro': 'int'},
-   'package': 'str'} }
+  'data': {'qemu': 'VersionTriple', 'package': 'str'} }

 ##
 # @query-version:
diff --git a/qmp.c b/qmp.c
index c479e77..78a5c23 100644
--- a/qmp.c
+++ b/qmp.c
@@ -45,15 +45,16 @@ NameInfo *qmp_query_name(Error **errp)

 VersionInfo *qmp_query_version(Error **errp)
 {
-VersionInfo *info = g_malloc0(sizeof(*info));
+VersionInfo *info = g_new0(VersionInfo, 1);
 const char *version = QEMU_VERSION;
 char *tmp;

-info->qemu.major = strtol(version, &tmp, 10);
+info->qemu = g_new0(VersionTriple, 1);
+info->qemu->major = strtol(version, &tmp, 10);
 tmp++;
-info->qemu.minor = strtol(tmp, &tmp, 10);
+info->qemu->minor = strtol(tmp, &tmp, 10);
 tmp++;
-info->qemu.micro = strtol(tmp, &tmp, 10);
+info->qemu->micro = strtol(tmp, &tmp, 10);
 info->package = g_strdup(QEMU_PKGVERSION);

 return info;
-- 
2.1.0




[Qemu-devel] [PATCH v5 06/28] qapi: Add some union tests

2015-03-24 Thread Eric Blake
Demonstrate that the qapi generator doesn't deal well with unions
that aren't up to par. Later patches will update the expected
reseults as the generator is made stricter.

Of particular note, we currently allow 'base' without 'discriminator'
as a way to create a simple union with a base class.  However, none
of the existing QMP or QGA interfaces use it (it is exercised only
in the testsuite).  Meanwhile, it would be nice to allow
'discriminator':'EnumType' without 'base' for creating a simple union
that is type-safe rather than open-coded to a generated enum (right
now, we are only type-safe when using a flat union, but that uses
a different syntax of 'discriminator':'member-name' which requires
a base class containing a 'member-name' enum field).  If both 'base'
and 'discriminator' are optional, then converting a simple union
with base class to a type-safe simple union with an enum discriminator
would not be possible.  So my plan is to get rid of 'base' without
'discriminator' later in the series; this will be no real loss, as any
union that needs additional common fields can always use a flat
union.

Signed-off-by: Eric Blake 
---
 tests/Makefile   | 12 +---
 tests/qapi-schema/alternate-array.err|  0
 tests/qapi-schema/alternate-array.exit   |  1 +
 tests/qapi-schema/alternate-array.json   |  8 
 tests/qapi-schema/alternate-array.out|  4 
 tests/qapi-schema/alternate-base.err |  0
 tests/qapi-schema/alternate-base.exit|  1 +
 tests/qapi-schema/alternate-base.json|  7 +++
 tests/qapi-schema/alternate-base.out |  4 
 tests/qapi-schema/alternate-clash.err|  0
 tests/qapi-schema/alternate-clash.exit   |  1 +
 tests/qapi-schema/alternate-clash.json   |  4 
 tests/qapi-schema/alternate-clash.out|  3 +++
 tests/qapi-schema/alternate-conflict-dict.err|  0
 tests/qapi-schema/alternate-conflict-dict.exit   |  1 +
 tests/qapi-schema/alternate-conflict-dict.json   |  9 +
 tests/qapi-schema/alternate-conflict-dict.out|  6 ++
 tests/qapi-schema/alternate-conflict-string.err  |  0
 tests/qapi-schema/alternate-conflict-string.exit |  1 +
 tests/qapi-schema/alternate-conflict-string.json |  8 
 tests/qapi-schema/alternate-conflict-string.out  |  5 +
 tests/qapi-schema/alternate-good.err |  0
 tests/qapi-schema/alternate-good.exit|  1 +
 tests/qapi-schema/alternate-good.json| 10 ++
 tests/qapi-schema/alternate-good.out |  6 ++
 tests/qapi-schema/alternate-nested.err   |  0
 tests/qapi-schema/alternate-nested.exit  |  1 +
 tests/qapi-schema/alternate-nested.json  |  7 +++
 tests/qapi-schema/alternate-nested.out   |  5 +
 tests/qapi-schema/alternate-unknown.err  |  0
 tests/qapi-schema/alternate-unknown.exit |  1 +
 tests/qapi-schema/alternate-unknown.json |  4 
 tests/qapi-schema/alternate-unknown.out  |  3 +++
 tests/qapi-schema/flat-union-bad-base.err|  1 +
 tests/qapi-schema/flat-union-bad-base.exit   |  1 +
 tests/qapi-schema/flat-union-bad-base.json   | 13 +
 tests/qapi-schema/flat-union-bad-base.out|  0
 tests/qapi-schema/flat-union-bad-discriminator.err   |  0
 tests/qapi-schema/flat-union-bad-discriminator.exit  |  1 +
 tests/qapi-schema/flat-union-bad-discriminator.json  | 14 ++
 tests/qapi-schema/flat-union-bad-discriminator.out   | 10 ++
 tests/qapi-schema/flat-union-base-union.err  |  1 +
 tests/qapi-schema/flat-union-base-union.exit |  1 +
 tests/qapi-schema/flat-union-base-union.json | 15 +++
 tests/qapi-schema/flat-union-base-union.out  |  0
 tests/qapi-schema/flat-union-no-base.err |  2 +-
 tests/qapi-schema/flat-union-no-base.json|  7 ---
 tests/qapi-schema/flat-union-optional-discriminator.err  |  0
 tests/qapi-schema/flat-union-optional-discriminator.exit |  1 +
 tests/qapi-schema/flat-union-optional-discriminator.json |  9 +
 tests/qapi-schema/flat-union-optional-discriminator.out  |  5 +
 tests/qapi-schema/union-bad-branch.err   |  0
 tests/qapi-schema/union-bad-branch.exit  |  1 +
 tests/qapi-schema/union-bad-branch.json  |  8 
 tests/qapi-schema/union-bad-branch.out   |  6 ++
 tests/qapi-schema/union-base-no-discriminator.err|  0
 tests/qapi-schema/union-base-no-discriminator.exit   |  1 +
 te

[Qemu-devel] [PATCH v5 07/28] qapi: Simplify tests of simple unions

2015-03-24 Thread Eric Blake
None of the existing QMP or QGA interfaces uses a union with a
base type but no discriminator; it is easier to avoid this in
the generator to save room for other future extensions more likely
to be useful (the previous commit added the test
union-base-no-discriminator to ensure that we eventually give an
error message).  Meanwhile, the tests of UserDefNativeListUnion
serve to validate code generation of simple unions, except that it
did not have full coverage in the strict test.

Fix some indentation and long lines while at it.

Signed-off-by: Eric Blake 
---
 scripts/qapi-types.py   |  7 ++-
 scripts/qapi-visit.py   | 13 +++---
 tests/qapi-schema/qapi-schema-test.json |  4 --
 tests/qapi-schema/qapi-schema-test.out  |  2 -
 tests/test-qmp-input-strict.c   | 57 +++
 tests/test-qmp-input-visitor.c  | 80 +
 tests/test-qmp-output-visitor.c | 74 +++---
 7 files changed, 95 insertions(+), 142 deletions(-)

diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index e400b03..f6fb930 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -242,10 +242,9 @@ struct %(name)s
 ''')

 if base:
-base_fields = find_struct(base)['data']
-if discriminator:
-base_fields = base_fields.copy()
-del base_fields[discriminator]
+assert discriminator
+base_fields = find_struct(base)['data'].copy()
+del base_fields[discriminator]
 ret += generate_struct_fields(base_fields)
 else:
 assert not discriminator
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 4416677..3f82bd4 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -2,7 +2,7 @@
 # QAPI visitor generator
 #
 # Copyright IBM, Corp. 2011
-# Copyright (C) 2014 Red Hat, Inc.
+# Copyright (C) 2014-2015 Red Hat, Inc.
 #
 # Authors:
 #  Anthony Liguori 
@@ -310,16 +310,15 @@ def generate_visit_union(expr):
 ret = ""
 disc_type = enum_define['enum_name']
 else:
-# There will always be a discriminator in the C switch code, by 
default it
-# is an enum type generated silently as "'%sKind' % (name)"
+# There will always be a discriminator in the C switch code, by default
+# it is an enum type generated silently as "'%sKind' % (name)"
 ret = generate_visit_enum('%sKind' % name, members.keys())
 disc_type = '%sKind' % (name)

 if base:
-base_fields = find_struct(base)['data']
-if discriminator:
-base_fields = base_fields.copy()
-del base_fields[discriminator]
+assert discriminator
+base_fields = find_struct(base)['data'].copy()
+del base_fields[discriminator]
 ret += generate_visit_struct_fields(name, "", "", base_fields)

 if discriminator:
diff --git a/tests/qapi-schema/qapi-schema-test.json 
b/tests/qapi-schema/qapi-schema-test.json
index 84f0f07..b134f3f 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -36,10 +36,6 @@
 { 'type': 'UserDefC',
   'data': { 'string1': 'str', 'string2': 'str' } }

-{ 'union': 'UserDefUnion',
-  'base': 'UserDefZero',
-  'data': { 'a' : 'UserDefA', 'b' : 'UserDefB' } }
-
 { 'type': 'UserDefUnionBase',
   'data': { 'string': 'str', 'enum1': 'EnumOne' } }

diff --git a/tests/qapi-schema/qapi-schema-test.out 
b/tests/qapi-schema/qapi-schema-test.out
index 915a61b..664ae7b 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -7,7 +7,6 @@
  OrderedDict([('type', 'UserDefA'), ('data', OrderedDict([('boolean', 
'bool')]))]),
  OrderedDict([('type', 'UserDefB'), ('data', OrderedDict([('integer', 
'int')]))]),
  OrderedDict([('type', 'UserDefC'), ('data', OrderedDict([('string1', 'str'), 
('string2', 'str')]))]),
- OrderedDict([('union', 'UserDefUnion'), ('base', 'UserDefZero'), ('data', 
OrderedDict([('a', 'UserDefA'), ('b', 'UserDefB')]))]),
  OrderedDict([('type', 'UserDefUnionBase'), ('data', OrderedDict([('string', 
'str'), ('enum1', 'EnumOne')]))]),
  OrderedDict([('union', 'UserDefFlatUnion'), ('base', 'UserDefUnionBase'), 
('discriminator', 'enum1'), ('data', OrderedDict([('value1', 'UserDefA'), 
('value2', 'UserDefB'), ('value3', 'UserDefB')]))]),
  OrderedDict([('union', 'UserDefFlatUnion2'), ('base', 'UserDefUnionBase'), 
('discriminator', 'enum1'), ('data', OrderedDict([('value1', 'UserDefC'), 
('value2', 'UserDefB'), ('value3', 'UserDefA')]))]),
@@ -24,7 +23,6 @@
  OrderedDict([('event', 'EVENT_C'), ('data', OrderedDict([('*a', 'int'), 
('*b', 'UserDefOne'), ('c', 'str')]))]),
  OrderedDict([('event', 'EVENT_D'), ('data', OrderedDict([('a', 
'EventStructOne'), ('b', 'str'), ('*c', 'str'), ('*enum3', 'EnumOne')]))])]
 [{'enum_name': 'EnumOne', 'enum_values': ['value1', 'value2', 'value3']},
- {'enum_name': 'UserDefUnionKind', 'enum_values': None},
  {

[Qemu-devel] [PATCH v5 16/28] qapi: Better error messages for duplicated expressions

2015-03-24 Thread Eric Blake
The previous commit demonstrated that the generator overlooked
duplicate expressions:
- a complex type or command reusing a built-in type name
- redeclaration of a type name, whether by the same or different
metatype
- redeclaration of a command or event
- collision of a type with implicit 'Kind' enum for a union
- collision with an implicit MAX enum constant, or with various
case spellings of events

Since the c_type() function in the generator treats all names
as being in the same namespace, this patch adds a global array
to track all known names and their source, to prevent collisions
before it can cause further problems.  While valid .json files
won't trigger any of these cases, we might as well be nicer to
developers that make a typo while trying to add new QAPI code.

Signed-off-by: Eric Blake 
---
 scripts/qapi.py  | 68 +---
 tests/qapi-schema/bad-type-dict.err  |  2 +-
 tests/qapi-schema/command-int.err|  1 +
 tests/qapi-schema/command-int.exit   |  2 +-
 tests/qapi-schema/command-int.json   |  2 +-
 tests/qapi-schema/command-int.out|  3 --
 tests/qapi-schema/enum-union-clash.err   |  1 +
 tests/qapi-schema/enum-union-clash.exit  |  2 +-
 tests/qapi-schema/enum-union-clash.json  |  2 +-
 tests/qapi-schema/enum-union-clash.out   |  5 ---
 tests/qapi-schema/event-case.err |  1 +
 tests/qapi-schema/event-case.exit|  2 +-
 tests/qapi-schema/event-case.json|  2 +-
 tests/qapi-schema/event-case.out |  3 --
 tests/qapi-schema/event-max.err  |  1 +
 tests/qapi-schema/event-max.exit |  2 +-
 tests/qapi-schema/event-max.json |  2 +-
 tests/qapi-schema/event-max.out  |  3 --
 tests/qapi-schema/redefined-builtin.err  |  1 +
 tests/qapi-schema/redefined-builtin.exit |  2 +-
 tests/qapi-schema/redefined-builtin.json |  2 +-
 tests/qapi-schema/redefined-builtin.out  |  3 --
 tests/qapi-schema/redefined-command.err  |  1 +
 tests/qapi-schema/redefined-command.exit |  2 +-
 tests/qapi-schema/redefined-command.json |  2 +-
 tests/qapi-schema/redefined-command.out  |  4 --
 tests/qapi-schema/redefined-event.err|  1 +
 tests/qapi-schema/redefined-event.exit   |  2 +-
 tests/qapi-schema/redefined-event.json   |  2 +-
 tests/qapi-schema/redefined-event.out|  4 --
 tests/qapi-schema/redefined-type.err |  1 +
 tests/qapi-schema/redefined-type.exit|  2 +-
 tests/qapi-schema/redefined-type.json|  2 +-
 tests/qapi-schema/redefined-type.out |  4 --
 34 files changed, 78 insertions(+), 61 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 90eb3bc..5d0dc91 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -32,6 +32,12 @@ builtin_types = {
 'size': 'QTYPE_QINT',
 }

+enum_types = []
+struct_types = []
+union_types = []
+events = []
+all_names = {}
+
 def error_path(parent):
 res = ""
 while parent:
@@ -256,7 +262,17 @@ def discriminator_find_enum_define(expr):
 return find_enum(discriminator_type)

 def check_event(expr, expr_info):
+global events
+name = expr['event']
 params = expr.get('data')
+
+if name == 'MAX':
+raise QAPIExprError(expr_info, "Event name 'MAX' cannot be created")
+if name != name.upper():
+raise QAPIExprError(expr_info, "Event name '%s' should be upper case"
+% name)
+events.append(name)
+
 if params:
 for argname, argentry, optional, structured in parse_args(params):
 if structured:
@@ -408,7 +424,7 @@ def check_keys(expr_elem, meta, required, optional=[]):
 name = expr[meta]
 if not isinstance(name, str):
 raise QAPIExprError(info,
-"%s key must have a string value" % meta)
+"'%s' key must have a string value" % meta)
 required = required + [ meta ]
 for (key, value) in expr.items():
 if not key in required and not key in optional:
@@ -423,6 +439,9 @@ def check_keys(expr_elem, meta, required, optional=[]):


 def parse_schema(input_file):
+global all_names
+exprs = []
+
 # First pass: read entire file into memory
 try:
 schema = QAPISchema(open(input_file, "r"))
@@ -430,30 +449,34 @@ def parse_schema(input_file):
 print >>sys.stderr, e
 exit(1)

-exprs = []
-
 try:
 # Next pass: learn the types and check for valid expression keys. At
 # this point, top-level 'include' has already been flattened.
+for builtin in builtin_types.keys():
+all_names[builtin] = 'built-in'
 for expr_elem in schema.exprs:
 expr = expr_elem['expr']
+info = expr_elem['info']
 if expr.has_key('enum'):
 check_keys(expr_elem, 'enum', ['data'])
-add_enum(expr['enum'], expr['data'])
+add_enum(expr['enum'], info, expr['data'])
 elif expr.has_key('union'):
 c

[Qemu-devel] [PATCH v5 15/28] qapi: Add tests of redefined expressions

2015-03-24 Thread Eric Blake
Demonstrate that the qapi generator doesn't deal very well with
redefined expressions.  At the parse level, they are silently
accepted; and while the testsuite just stops at parsing, I've
further tested that many of them cause generator crashes or
invalid C code if they were appended to qapi-schema-test.json.
A later patch will tighten things up and adjust the testsuite
to match.

Signed-off-by: Eric Blake 
---
 tests/Makefile   | 2 ++
 tests/qapi-schema/command-int.err| 0
 tests/qapi-schema/command-int.exit   | 1 +
 tests/qapi-schema/command-int.json   | 3 +++
 tests/qapi-schema/command-int.out| 3 +++
 tests/qapi-schema/event-max.err  | 0
 tests/qapi-schema/event-max.exit | 1 +
 tests/qapi-schema/event-max.json | 2 ++
 tests/qapi-schema/event-max.out  | 3 +++
 tests/qapi-schema/redefined-builtin.err  | 0
 tests/qapi-schema/redefined-builtin.exit | 1 +
 tests/qapi-schema/redefined-builtin.json | 2 ++
 tests/qapi-schema/redefined-builtin.out  | 3 +++
 tests/qapi-schema/redefined-command.err  | 0
 tests/qapi-schema/redefined-command.exit | 1 +
 tests/qapi-schema/redefined-command.json | 3 +++
 tests/qapi-schema/redefined-command.out  | 4 
 tests/qapi-schema/redefined-event.err| 0
 tests/qapi-schema/redefined-event.exit   | 1 +
 tests/qapi-schema/redefined-event.json   | 3 +++
 tests/qapi-schema/redefined-event.out| 4 
 tests/qapi-schema/redefined-type.err | 0
 tests/qapi-schema/redefined-type.exit| 1 +
 tests/qapi-schema/redefined-type.json| 3 +++
 tests/qapi-schema/redefined-type.out | 4 
 25 files changed, 45 insertions(+)
 create mode 100644 tests/qapi-schema/command-int.err
 create mode 100644 tests/qapi-schema/command-int.exit
 create mode 100644 tests/qapi-schema/command-int.json
 create mode 100644 tests/qapi-schema/command-int.out
 create mode 100644 tests/qapi-schema/event-max.err
 create mode 100644 tests/qapi-schema/event-max.exit
 create mode 100644 tests/qapi-schema/event-max.json
 create mode 100644 tests/qapi-schema/event-max.out
 create mode 100644 tests/qapi-schema/redefined-builtin.err
 create mode 100644 tests/qapi-schema/redefined-builtin.exit
 create mode 100644 tests/qapi-schema/redefined-builtin.json
 create mode 100644 tests/qapi-schema/redefined-builtin.out
 create mode 100644 tests/qapi-schema/redefined-command.err
 create mode 100644 tests/qapi-schema/redefined-command.exit
 create mode 100644 tests/qapi-schema/redefined-command.json
 create mode 100644 tests/qapi-schema/redefined-command.out
 create mode 100644 tests/qapi-schema/redefined-event.err
 create mode 100644 tests/qapi-schema/redefined-event.exit
 create mode 100644 tests/qapi-schema/redefined-event.json
 create mode 100644 tests/qapi-schema/redefined-event.out
 create mode 100644 tests/qapi-schema/redefined-type.err
 create mode 100644 tests/qapi-schema/redefined-type.exit
 create mode 100644 tests/qapi-schema/redefined-type.json
 create mode 100644 tests/qapi-schema/redefined-type.out

diff --git a/tests/Makefile b/tests/Makefile
index cf9c42b..7079e2a 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -213,6 +213,8 @@ check-qapi-schema-y := $(addprefix tests/qapi-schema/, \
funny-char.json indented-expr.json missing-type.json bad-ident.json \
double-type.json bad-base.json bad-type-bool.json bad-type-int.json \
bad-type-dict.json double-data.json unknown-expr-key.json \
+   redefined-type.json redefined-command.json redefined-builtin.json \
+   redefined-event.json command-int.json event-max.json \
missing-colon.json missing-comma-list.json \
missing-comma-object.json non-objects.json \
qapi-schema-test.json quoted-structural-chars.json \
diff --git a/tests/qapi-schema/command-int.err 
b/tests/qapi-schema/command-int.err
new file mode 100644
index 000..e69de29
diff --git a/tests/qapi-schema/command-int.exit 
b/tests/qapi-schema/command-int.exit
new file mode 100644
index 000..573541a
--- /dev/null
+++ b/tests/qapi-schema/command-int.exit
@@ -0,0 +1 @@
+0
diff --git a/tests/qapi-schema/command-int.json 
b/tests/qapi-schema/command-int.json
new file mode 100644
index 000..fcbb643
--- /dev/null
+++ b/tests/qapi-schema/command-int.json
@@ -0,0 +1,3 @@
+# FIXME: we should reject collisions between commands and types
+{ 'command': 'int', 'data': { 'character': 'str' },
+  'returns': { 'value': 'int' } }
diff --git a/tests/qapi-schema/command-int.out 
b/tests/qapi-schema/command-int.out
new file mode 100644
index 000..d8e1854
--- /dev/null
+++ b/tests/qapi-schema/command-int.out
@@ -0,0 +1,3 @@
+[OrderedDict([('command', 'int'), ('data', OrderedDict([('character', 
'str')])), ('returns', OrderedDict([('value', 'int')]))])]
+[]
+[]
diff --git a/tests/qapi-schema/event-max.err b/tests/qapi-schema/event-max.err
new file mode 100644
index 000..e69de29
diff --git a/tests/qapi-schema/event-max.exit b/tests/qapi-schema/event-max.exit
new file

[Qemu-devel] [PATCH v5 18/28] qapi: Unify type bypass and add tests

2015-03-24 Thread Eric Blake
For a few QMP commands, we are forced to pass an arbitrary type
without tracking it properly in QAPI.  Among the existing clients,
this unnamed type was spelled 'dict', 'visitor', and '**'; this
patch standardizes on '**'.

Meanwhile, for both 'gen' and 'success-response' keys, we have been
ignoring the value, although the schema consistently used "'no'".
But now that we can support a literal "false" in the schema, we
might as well use that rather than ignoring the value or
special-casing a random string.

There is no difference to the generated code.  As these features
were previously undocumented before this series, add some tests
and documentation on what we'd like to guarantee, although it will
take later patches to clean up test results and actually enforce
the use of a bool parameter.

Signed-off-by: Eric Blake 
---
 qapi-schema.json   | 14 +++---
 qga/qapi-schema.json   |  8 
 tests/Makefile |  1 +
 tests/qapi-schema/type-bypass-bad-gen.err  |  0
 tests/qapi-schema/type-bypass-bad-gen.exit |  1 +
 tests/qapi-schema/type-bypass-bad-gen.json |  2 ++
 tests/qapi-schema/type-bypass-bad-gen.out  |  3 +++
 tests/qapi-schema/type-bypass-no-gen.err   |  0
 tests/qapi-schema/type-bypass-no-gen.exit  |  1 +
 tests/qapi-schema/type-bypass-no-gen.json  |  2 ++
 tests/qapi-schema/type-bypass-no-gen.out   |  3 +++
 tests/qapi-schema/type-bypass.err  |  0
 tests/qapi-schema/type-bypass.exit |  1 +
 tests/qapi-schema/type-bypass.json |  2 ++
 tests/qapi-schema/type-bypass.out  |  3 +++
 15 files changed, 30 insertions(+), 11 deletions(-)
 create mode 100644 tests/qapi-schema/type-bypass-bad-gen.err
 create mode 100644 tests/qapi-schema/type-bypass-bad-gen.exit
 create mode 100644 tests/qapi-schema/type-bypass-bad-gen.json
 create mode 100644 tests/qapi-schema/type-bypass-bad-gen.out
 create mode 100644 tests/qapi-schema/type-bypass-no-gen.err
 create mode 100644 tests/qapi-schema/type-bypass-no-gen.exit
 create mode 100644 tests/qapi-schema/type-bypass-no-gen.json
 create mode 100644 tests/qapi-schema/type-bypass-no-gen.out
 create mode 100644 tests/qapi-schema/type-bypass.err
 create mode 100644 tests/qapi-schema/type-bypass.exit
 create mode 100644 tests/qapi-schema/type-bypass.json
 create mode 100644 tests/qapi-schema/type-bypass.out

diff --git a/qapi-schema.json b/qapi-schema.json
index ac9594d..7f4cf86 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -1561,8 +1561,8 @@
 ##
 { 'command': 'qom-get',
   'data': { 'path': 'str', 'property': 'str' },
-  'returns': 'visitor',
-  'gen': 'no' }
+  'returns': '**',
+  'gen': false }

 ##
 # @qom-set:
@@ -1579,8 +1579,8 @@
 # Since: 1.2
 ##
 { 'command': 'qom-set',
-  'data': { 'path': 'str', 'property': 'str', 'value': 'visitor' },
-  'gen': 'no' }
+  'data': { 'path': 'str', 'property': 'str', 'value': '**' },
+  'gen': false }

 ##
 # @set_password:
@@ -1943,7 +1943,7 @@
 ##
 { 'command': 'netdev_add',
   'data': {'type': 'str', 'id': 'str', '*props': '**'},
-  'gen': 'no' }
+  'gen': false }

 ##
 # @netdev_del:
@@ -1976,8 +1976,8 @@
 # Since: 2.0
 ##
 { 'command': 'object-add',
-  'data': {'qom-type': 'str', 'id': 'str', '*props': 'dict'},
-  'gen': 'no' }
+  'data': {'qom-type': 'str', 'id': 'str', '*props': '**'},
+  'gen': false }

 ##
 # @object-del:
diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index 95f49e3..fe5be7e 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -195,7 +195,7 @@
 # Since: 0.15.0
 ##
 { 'command': 'guest-shutdown', 'data': { '*mode': 'str' },
-  'success-response': 'no' }
+  'success-response': false }

 ##
 # @guest-file-open:
@@ -470,7 +470,7 @@
 #
 # Since: 1.1
 ##
-{ 'command': 'guest-suspend-disk', 'success-response': 'no' }
+{ 'command': 'guest-suspend-disk', 'success-response': false }

 ##
 # @guest-suspend-ram
@@ -502,7 +502,7 @@
 #
 # Since: 1.1
 ##
-{ 'command': 'guest-suspend-ram', 'success-response': 'no' }
+{ 'command': 'guest-suspend-ram', 'success-response': false }

 ##
 # @guest-suspend-hybrid
@@ -529,7 +529,7 @@
 #
 # Since: 1.1
 ##
-{ 'command': 'guest-suspend-hybrid', 'success-response': 'no' }
+{ 'command': 'guest-suspend-hybrid', 'success-response': false }

 ##
 # @GuestIpAddressType:
diff --git a/tests/Makefile b/tests/Makefile
index 7079e2a..941e839 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -215,6 +215,7 @@ check-qapi-schema-y := $(addprefix tests/qapi-schema/, \
bad-type-dict.json double-data.json unknown-expr-key.json \
redefined-type.json redefined-command.json redefined-builtin.json \
redefined-event.json command-int.json event-max.json \
+   type-bypass.json type-bypass-no-gen.json type-bypass-bad-gen.json \
missing-colon.json missing-comma-list.json \
missing-comma-object.json non-objects.json \
qapi-schema-test.json quoted-structural-chars.json \
diff --git a/tests/qapi-schema/type-bypass-bad-gen

[Qemu-devel] [PATCH v5 10/28] qapi: Segregate anonymous unions into alternates in generator

2015-03-24 Thread Eric Blake
Special-casing 'discriminator == {}' for handling anonymous unions
is getting awkward; since this particular type is not always a
dictionary on the wire, it is easier to treat it as a completely
different class of type, "alternate", so that if a type is listed
in the union_types array, we know it is not an anonymous union.

This patch just further segregates union handling, to make sure that
anonymous unions are not stored in union_types, and splitting up
check_union() into separate functions.  A future patch will change
the qapi grammar, and having the segregation already in place will
make it easier to deal with the distinct meta-type.

Signed-off-by: Eric Blake 
---
 scripts/qapi-types.py |  6 ++--
 scripts/qapi-visit.py |  4 +--
 scripts/qapi.py   | 94 +--
 3 files changed, 58 insertions(+), 46 deletions(-)

diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 2390887..c9e0201 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -170,7 +170,7 @@ typedef enum %(name)s

 return lookup_decl + enum_decl

-def generate_anon_union_qtypes(expr):
+def generate_alternate_qtypes(expr):

 name = expr['union']
 members = expr['data']
@@ -181,7 +181,7 @@ const int %(name)s_qtypes[QTYPE_MAX] = {
 name=name)

 for key in members:
-qtype = find_anonymous_member_qtype(members[key])
+qtype = find_alternate_member_qtype(members[key])
 assert qtype, "Invalid anonymous union member"

 ret += mcgen('''
@@ -408,7 +408,7 @@ for expr in exprs:
 fdef.write(generate_enum_lookup('%sKind' % expr['union'],
 expr['data'].keys()))
 if expr.get('discriminator') == {}:
-fdef.write(generate_anon_union_qtypes(expr))
+fdef.write(generate_alternate_qtypes(expr))
 else:
 continue
 fdecl.write(ret)
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 3f82bd4..77b0a1f 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -237,7 +237,7 @@ void visit_type_%(name)s(Visitor *m, %(name)s *obj, const 
char *name, Error **er
 ''',
  name=name)

-def generate_visit_anon_union(name, members):
+def generate_visit_alternate(name, members):
 ret = mcgen('''

 void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error 
**errp)
@@ -302,7 +302,7 @@ def generate_visit_union(expr):

 if discriminator == {}:
 assert not base
-return generate_visit_anon_union(name, members)
+return generate_visit_alternate(name, members)

 enum_define = discriminator_find_enum_define(expr)
 if enum_define:
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 39cc88b..17252e9 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -224,21 +224,16 @@ def find_base_fields(base):
 return None
 return base_struct_define['data']

-# Return the qtype of an anonymous union branch, or None on error.
-def find_anonymous_member_qtype(qapi_type):
+# Return the qtype of an alternate branch, or None on error.
+def find_alternate_member_qtype(qapi_type):
 if builtin_types.has_key(qapi_type):
 return builtin_types[qapi_type]
 elif find_struct(qapi_type):
 return "QTYPE_QDICT"
 elif find_enum(qapi_type):
 return "QTYPE_QSTRING"
-else:
-union = find_union(qapi_type)
-if union:
-discriminator = union.get('discriminator')
-if discriminator == {}:
-return None
-return "QTYPE_QDICT"
+elif find_union(qapi_type):
+return "QTYPE_QDICT"
 return None

 # Return the discriminator enum define if discriminator is specified as an
@@ -276,22 +271,13 @@ def check_union(expr, expr_info):
 discriminator = expr.get('discriminator')
 members = expr['data']
 values = { 'MAX': '(automatic)' }
-types_seen = {}

-# Three types of unions, determined by discriminator.
+# Two types of unions, determined by discriminator.
+assert discriminator != {}

-# If the value of member 'discriminator' is {}, it's an
-# anonymous union, and must not have a base.
-if discriminator == {}:
-enum_define = None
-if base:
-raise QAPIExprError(expr_info,
-"Anonymous union '%s' must not have a base"
-% name)
-
-# Else if the union object has no member 'discriminator', it's an
+# If the union object has no member 'discriminator', it's an
 # ordinary union.  For now, it must not have a base.
-elif not discriminator:
+if not discriminator:
 enum_define = None
 if base:
 raise QAPIExprError(expr_info,
@@ -346,24 +332,46 @@ def check_union(expr, expr_info):
 % (name, key, values[c_key]))
 values[c_key] = key

-# Ensure anonymous unions have no type conflicts

[Qemu-devel] [PATCH v5 09/28] qapi: Prepare for catching more semantic parse errors

2015-03-24 Thread Eric Blake
This patch widens the scope of a try block (with the attending
reindentation required by Python) in preparation for a future
patch adding more instances of QAPIExprError inside the block.
It's easier to separate indentation from semantic changes, so
this patch has no real behavior change.

Signed-off-by: Eric Blake 
---
 scripts/qapi.py | 37 -
 1 file changed, 20 insertions(+), 17 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index fc7b7f1..39cc88b 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -398,6 +398,7 @@ def check_exprs(schema):
 check_event(expr, info)

 def parse_schema(input_file):
+# First pass: read entire file into memory
 try:
 schema = QAPISchema(open(input_file, "r"))
 except (QAPISchemaError, QAPIExprError), e:
@@ -406,24 +407,26 @@ def parse_schema(input_file):

 exprs = []

-for expr_elem in schema.exprs:
-expr = expr_elem['expr']
-if expr.has_key('enum'):
-add_enum(expr['enum'], expr.get('data'))
-elif expr.has_key('union'):
-add_union(expr)
-elif expr.has_key('type'):
-add_struct(expr)
-exprs.append(expr)
-
-# Try again for hidden UnionKind enum
-for expr_elem in schema.exprs:
-expr = expr_elem['expr']
-if expr.has_key('union'):
-if not discriminator_find_enum_define(expr):
-add_enum('%sKind' % expr['union'])
-
 try:
+# Next pass: learn the types.
+for expr_elem in schema.exprs:
+expr = expr_elem['expr']
+if expr.has_key('enum'):
+add_enum(expr['enum'], expr.get('data'))
+elif expr.has_key('union'):
+add_union(expr)
+elif expr.has_key('type'):
+add_struct(expr)
+exprs.append(expr)
+
+# Try again for hidden UnionKind enum
+for expr_elem in schema.exprs:
+expr = expr_elem['expr']
+if expr.has_key('union'):
+if not discriminator_find_enum_define(expr):
+add_enum('%sKind' % expr['union'])
+
+# Final pass - validate that exprs make sense
 check_exprs(schema)
 except QAPIExprError, e:
 print >>sys.stderr, e
-- 
2.1.0




[Qemu-devel] [PATCH v5 08/28] qapi: Better error messages for bad unions

2015-03-24 Thread Eric Blake
Previous commits demonstrated that the generator had several
flaws with less-than-perfect unions:
- make the use of a base without discriminator a hard error,
since the previous patch removed all remaining uses of it
- a simple union that listed the same branch twice (or two variant
names that map to the same C enumerator, including the implicit
MAX sentinel) ended up generating invalid C code
- checking 'if discriminator' prior to 'if discriminator == {}'
leads to dead code in python, and ended up processing anonymous
unions as if they were simple unions
- an anonymous union that listed two branches with the same qtype
ended up generating invalid C code
- the generator crashed on anonymous union attempts to use an
array type
- the generator was silently ignoring a base type for anonymous
unions
- the generator allowed unknown types or nested anonymous unions
as a branch in an anonymous union

Signed-off-by: Eric Blake 
---
 scripts/qapi-types.py  | 13 +--
 scripts/qapi.py| 96 +-
 tests/qapi-schema/alternate-array.err  |  1 +
 tests/qapi-schema/alternate-array.exit |  2 +-
 tests/qapi-schema/alternate-array.json |  1 -
 tests/qapi-schema/alternate-array.out  |  4 -
 tests/qapi-schema/alternate-base.err   |  1 +
 tests/qapi-schema/alternate-base.exit  |  2 +-
 tests/qapi-schema/alternate-base.json  |  2 +-
 tests/qapi-schema/alternate-base.out   |  4 -
 tests/qapi-schema/alternate-clash.err  |  1 +
 tests/qapi-schema/alternate-clash.exit |  2 +-
 tests/qapi-schema/alternate-clash.json |  2 +-
 tests/qapi-schema/alternate-clash.out  |  3 -
 tests/qapi-schema/alternate-conflict-dict.err  |  1 +
 tests/qapi-schema/alternate-conflict-dict.exit |  2 +-
 tests/qapi-schema/alternate-conflict-dict.json |  2 +-
 tests/qapi-schema/alternate-conflict-dict.out  |  6 --
 tests/qapi-schema/alternate-conflict-string.err|  1 +
 tests/qapi-schema/alternate-conflict-string.exit   |  2 +-
 tests/qapi-schema/alternate-conflict-string.json   |  2 +-
 tests/qapi-schema/alternate-conflict-string.out|  5 --
 tests/qapi-schema/alternate-nested.err |  1 +
 tests/qapi-schema/alternate-nested.exit|  2 +-
 tests/qapi-schema/alternate-nested.json|  2 +-
 tests/qapi-schema/alternate-nested.out |  5 --
 tests/qapi-schema/alternate-unknown.err|  1 +
 tests/qapi-schema/alternate-unknown.exit   |  2 +-
 tests/qapi-schema/alternate-unknown.json   |  2 +-
 tests/qapi-schema/alternate-unknown.out|  3 -
 tests/qapi-schema/flat-union-bad-discriminator.err |  1 +
 .../qapi-schema/flat-union-bad-discriminator.exit  |  2 +-
 tests/qapi-schema/flat-union-bad-discriminator.out | 10 ---
 tests/qapi-schema/union-bad-branch.err |  1 +
 tests/qapi-schema/union-bad-branch.exit|  2 +-
 tests/qapi-schema/union-bad-branch.json|  2 +-
 tests/qapi-schema/union-bad-branch.out |  6 --
 tests/qapi-schema/union-base-no-discriminator.err  |  1 +
 tests/qapi-schema/union-base-no-discriminator.exit |  2 +-
 tests/qapi-schema/union-base-no-discriminator.json |  3 +-
 tests/qapi-schema/union-base-no-discriminator.out  |  8 --
 tests/qapi-schema/union-max.err|  1 +
 tests/qapi-schema/union-max.exit   |  2 +-
 tests/qapi-schema/union-max.json   |  2 +-
 tests/qapi-schema/union-max.out|  3 -
 45 files changed, 109 insertions(+), 110 deletions(-)

diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index f6fb930..2390887 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -181,17 +181,8 @@ const int %(name)s_qtypes[QTYPE_MAX] = {
 name=name)

 for key in members:
-qapi_type = members[key]
-if builtin_types.has_key(qapi_type):
-qtype = builtin_types[qapi_type]
-elif find_struct(qapi_type):
-qtype = "QTYPE_QDICT"
-elif find_union(qapi_type):
-qtype = "QTYPE_QDICT"
-elif find_enum(qapi_type):
-qtype = "QTYPE_QSTRING"
-else:
-assert False, "Invalid anonymous union member"
+qtype = find_anonymous_member_qtype(members[key])
+assert qtype, "Invalid anonymous union member"

 ret += mcgen('''
 [ %(qtype)s ] = %(abbrev)s_KIND_%(enum)s,
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 3ce8c33..fc7b7f1 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -224,6 +224,23 @@ def find_base_fields(base):
 return None
 return base_struct_define['data']

+# Return the qtype of an anonymous union branch, or None on error.
+def find_anonymous_member_qtype(qapi_type):
+if builtin_types.has_key(qapi_type):
+return builtin_types[qapi_type]
+elif find_s

  1   2   3   >