Re: [Qemu-devel] [PATCH] kvmclock: Ensure time in migration never goes backward

2014-05-06 Thread Alexander Graf


On 06.05.14 01:27, Marcelo Tosatti wrote:

On Mon, May 05, 2014 at 08:26:04PM +0200, Marcin Gibuła wrote:

is it possible to have kvmclock jumping forward?

Because I've reproducible case when at about 1 per 20 vm restores, VM freezes 
for couple of hours and then resumes with date few hundreds years ahead. 
Happens only with kvmclock.

And this patch seems to fix very similar issue so maybe it's all the same bug.

I'm fairly sure it is the exact same bug. Jumping backward is like jumping 
forward by a big amount :)

Hi,

I've tested your path on my test VM... don't know if it's pure luck
or not, but it didn't hang with over 70 restores.

The message "KVM Clock migrated backwards, using later time" fires
every time, but VM is healthy after resume.

What is the host clocksource? (cat
/sys/devices/system/clocksource/clocksource0/current_clocksource).

And kernel version?


I've seen 3 different reports of this bug by now. One is Marcin where I 
don't have any details. One is running 3.0 plus patches and another one 
is running 3.14.


For the 3.0 case the host clock source is TSC.


Alex




Re: [Qemu-devel] [PATCH 20/35] acpi: memory hotplug ACPI hardware implementation

2014-05-06 Thread Igor Mammedov
On Mon, 5 May 2014 14:20:25 +0200
Vasilis Liaskovitis  wrote:

> Hi,
> 
> On Fri, Apr 04, 2014 at 03:36:45PM +0200, Igor Mammedov wrote:
> > - implements QEMU hardware part of memory hotplug protocol
> >   described at "docs/specs/acpi_mem_hotplug.txt"
> > - handles only memory add notification event for now
> >
> [...]
> > +  [0x4-0x7] OST event code reported by OSPM
> > +  [0x8-0xb] OST status code reported by OSPM
> > +case 0x4: /* _OST event  */
> > +mdev = &mem_st->devs[mem_st->selector];
> > +if (data == 1) {
> > +/* TODO: handle device insert OST event */
> > +} else if (data == 3) {
> > +/* TODO: handle device remove OST event */
> > +}
> 
> Are there any patches planned to report _OST notifications to upper management
> layers? E.g. some older patchseries implemented a queue for these 
> notifications
> that could be queried with an "info memhp" command.
I don't recall seeing patches "info memhp", could you point them to me, please?
But I have in mind to add corresponding commands for get OST and sending
corresponding QMP events.

> 
> As a more general question for the patchseries: How do we query 
> status/presence
> of dimms present? Some posssible options could be:
> 
> - info qtree: If links<> are implemented between dimms and an acpi machine
> adapter, would the dimms show up in the general device tree? Currently I 
> believe
> they don't.
> 
> - info dimm: We could have a new "info dimm" command that shows information 
> for
> present DIMMs: start-end guest physical address, last _OST notification 
> received
> for this DIMM, as well as backing memdev object for this dimm.
I'd prefer this one for hmp and from QMP side qom-get could be used to 
enumerate/get
properties.

> 
> (qemu) info dimm
> dimm0: range="start_address - end_address" memdev="obj0" _OST="last_OST 
> message"
> dimm1: range="start_address - end_address" memdev="obj1" _OST="last_OST 
> message"
> 
> where last_OST message could be "hot-add succesfull", "hot-add failed",
> "hot-remove failed". Not sure how "hot-remove successful" would be reported
> though, as the dimm device would be removed (or soon to be removed) from the
> machine. Unless we have a separate command for OST messages received/queued, 
> as
> mentioned above.
Not much could be done here except of sending QMP event. It's generic hot-unplug
issue.

> 
> If the guest does not support _OST, the OST entries would remain empty,
> at least giving management layer a hint that the guest may not have 
> succesfully
> completed the requested hot-operation.
> 
> The examples are all in hmp, but there should obviously be qmp support.
> Thoughts?
> 
> thanks,
> 
> - Vasilis
> 
> 




Re: [Qemu-devel] [PATCH] kvmclock: Ensure time in migration never goes backward

2014-05-06 Thread Alexander Graf


On 06.05.14 01:23, Marcelo Tosatti wrote:

Hi Alexander,

On Mon, May 05, 2014 at 03:51:22PM +0200, Alexander Graf wrote:

When we migrate we ask the kernel about its current belief on what the guest
time would be.

KVM_GET_CLOCK which returns the time in "struct kvm_clock_data".


Yes :)




However, I've seen cases where the kvmclock guest structure
indicates a time more recent than the kvm returned time.

More details please:

1) By what algorithm you retrieve
and compare time in kvmclock guest structure and KVM_GET_CLOCK.
What are the results of the comparison.
And whether and backwards time was visible in the guest.


I've managed to get my hands on a broken migration stream from Nick. 
There I looked at the curr_clocksource structure and saw that the last 
seen time on the kvmclock clock source was greater than the value that 
the kvmclock device migrated.



2) What is the host clocksource.

The test below is not a good one because:

T1) KVM_GET_CLOCK (save s->clock).
T2) save env->tsc.

The difference in scaled time between T1 and T2 is larger than 1
nanosecond, so the

(time_at_migration > s->clock)

check is almost always positive (what matters though is whether
time backwards event can be seen reading kvmclock in the guest).


Yeah, at first I was thinking it makes sense to just not use the 
KVM_GET_CLOCK value at all because it's redundant to the in-memory 
values. Maybe that is the better alternative after all.



Alex




Re: [Qemu-devel] [PATCH 34/35] pc: ACPI BIOS: make GPE.3 handle memory hotplug event on PIIX and Q35 machines

2014-05-06 Thread Igor Mammedov
On Mon, 05 May 2014 10:25:09 -0600
Eric Blake  wrote:

> On 04/04/2014 07:36 AM, Igor Mammedov wrote:
> > also make handler edge based to avoid loosing events, the same as
> 
> s/loosing/losing/
Thanks, I'll fix it.

> 
> (loose rhymes with goose and means the opposite of "tight"; lose rhymes
> with use and means the opposite of "gain" - it is a very frequent typo
> to see people put too many 'o's when they meant a variant of "lose")
> 
> > it has been done for PCI and CPU hotplug handlers.
> > 
> > Signed-off-by: Igor Mammedov 
> > ---
> >  hw/i386/acpi-dsdt.dsl | 5 -
> >  hw/i386/q35-acpi-dsdt.dsl | 5 -
> >  2 files changed, 8 insertions(+), 2 deletions(-)
> > 
> 




Re: [Qemu-devel] [PATCH] kvmclock: Ensure time in migration never goes backward

2014-05-06 Thread Alexander Graf


On 06.05.14 01:31, Marcelo Tosatti wrote:

On Mon, May 05, 2014 at 08:23:43PM -0300, Marcelo Tosatti wrote:

Hi Alexander,

On Mon, May 05, 2014 at 03:51:22PM +0200, Alexander Graf wrote:

When we migrate we ask the kernel about its current belief on what the guest
time would be.

KVM_GET_CLOCK which returns the time in "struct kvm_clock_data".


However, I've seen cases where the kvmclock guest structure
indicates a time more recent than the kvm returned time.

This should not happen because the value returned by KVM_GET_CLOCK
(get_kernel_ns() + kvmclock_offset) should be relatively in sync
with what is seen in the guest via kvmclock read.



Yes, and it isn't. Any ideas why it's not? This patch really just uses 
the guest visible kvmclock time rather than the host view of it on 
migration.


There is definitely something very broken on the host's side since it 
does return a smaller time than the guest exposed interface indicates.



Alex




Re: [Qemu-devel] [RFC 0/5] Allow object-add on X86CPU subclasses, for CPU model probing

2014-05-06 Thread Igor Mammedov
On Fri, 2 May 2014 11:43:05 -0300
Eduardo Habkost  wrote:

> On Fri, May 02, 2014 at 03:45:03PM +0200, Igor Mammedov wrote:
> > On Wed, 30 Apr 2014 17:29:28 -0300
> > Eduardo Habkost  wrote:
> > 
> > > This series allows management code to use object-add on X86CPU 
> > > subclasses, so it
> > Is there any reason why "device-add" couldn't be used?
> 
> It needs to work with "-machine none", device_add requires a bus to
> exist, and there is no icc-bus on machine_none.
The thing is that CPUID is a function of machine so using
"-machine none" will provide only approximately accurate data.
I'm not sure that retrieved possibly not accurate data are useful
for libvirt.

> 
> The first thing I considered was making icc-bus user-creatable. Then I
> noticed it wouldn't work because object-add always add objects to
> /objects, not inside the qdev hierarchy (that's where device_add looks
> for the bus).
> 
> So, allowing device_add could be possible, but would require changing
> more basic infrastructure: either allowing bus-less devices on
> device_add, or allowing device_add to add devices outside the qdev
> hierarchy, or allowing object-add to create objects outside /objects.
> 
> Simply making CPU objects work with object-add was much simpler and less
> intrusive. And it had the interesting side-effect of _not_ doing things
> that are not required for CPU model probing (like creating an actual
> VCPU thread).
> 
> > 
> > 
> > > can use it to probe for CPU model information without re-running QEMU. 
> > > The main
> > > use case for this is to allow management code to create CPU objects and 
> > > query
> > > the "feature-words" and "filtered-features" properties on the new 
> > > objects, to
> > > find out which features each CPU model needs, and to do the same using the
> > > "host" CPU model to check which features can be enabled in a given host.
> > > 
> > > There's experimental libvirt code to use the new command at:
> > > https://github.com/ehabkost/libvirt/tree/work/cpu-feature-word-query
> > > The experimental code just create the CPU objects to query for feature
> > > information, but doesn't do anything with that data.
> > > 
> > > Eduardo Habkost (5):
> > >   cpu: Initialize cpu->stopped=true earlier
> > >   cpu: Don't try to pause CPUs if they are already stopped
> > >   pc: Don't crash on apic_accept_pic_intr() if CPU has no apic_state
> > >   target-i386: Make CPU objects user-creatable
> > >   target-i386: Report QOM class name for CPU definitions
> > > 
> > >  cpus.c| 13 ++---
> > >  exec.c|  1 +
> > >  hw/i386/pc.c  |  2 +-
> > >  qapi-schema.json  |  6 +-
> > >  target-i386/cpu.c |  7 +++
> > >  5 files changed, 24 insertions(+), 5 deletions(-)
> > > 
> > 
> 




Re: [Qemu-devel] [PATCH] kvmclock: Ensure time in migration never goes backward

2014-05-06 Thread Marcin Gibuła

What is the host clocksource? (cat
/sys/devices/system/clocksource/clocksource0/current_clocksource).


tsc


And kernel version?


3.12.17
But I've seen this problem on earlier versions as well (3.8, 3.10).

--
mg



Re: [Qemu-devel] [PATCH v1 00/22] target-arm: Preparations for A64 EL2 and 3

2014-05-06 Thread Peter Maydell
On 6 May 2014 07:08, Edgar E. Iglesias  wrote:
> From: "Edgar E. Iglesias" 
>
> Hi,
>
> I've been doing some work on modeling parts of EL2 and 3 + some of
> the system-wide virtualization features for ARMv8. A lot is missing
> but I've got a series with enough to for example run KVM A64 guests
> on top of EL3 firmware inside emulated QEMU A64 VMs.
> I'm working on cleaning things up and plan to send patches and publish
> things as I go.

So before I start reviewing this, how does it relate to the
Samsung series for AArch32 trustzone (EL3) support that was
posted last year? In Linaro we've been planning to rework that
and integrate it upstream...

thanks
-- PMM



Re: [Qemu-devel] [Crucial bug] Qemu-2.0.0 do not support virtio-net hot plug/unplug exceed two times

2014-05-06 Thread Gonglei (Arei)
Hi,

> > > Il 26/04/2014 10:56, Gonglei (Arei) ha scritto:
> > > > Public bug reported:
> > > >
> > > > I want to repeated hot-plug/unplug the virtio-net in the latest qemu
> > > upstream
> > > > (commit 839a5547574e57cce62f49bfc50fe1f04b00589a), but I am failed
> at
> > > the
> > > > second time hot plug the virtio-net to guest.
> > > >
> > > > Then I tried to use Qemu-2.0.0 release version, but I got the error too.
> > > >
> > > > Cmdline for vm:
> > > >
> > > > /mnt/sdb/gonglei/qemu/x86_64-softmmu/qemu-system-x86_64
> -enable-kvm
> > > -m 4096 -smp 4 -name sles-et -boot c -drive file=/mnt/sdb/gonglei/image/
> > > sles-3.img -vnc 0.0.0.0:10 -monitor stdio
> > > > QEMU 1.7.50 monitor - type 'help' for more information
> > >
> > > For commit 839a5547574e57cce62f49bfc50fe1f04b00589a you should have
> > > gotten 1.7.90 as the version number.
> > >
> > Maybe just because Peter Maydell merge remote-tracking branch. But it
> doesn't matter.
> >
> > > > (qemu) device_add virtio-net-pci,id=net1
> > > > (qemu) device_del net1
> > > > (qemu) device_add virtio-net-pci,id=net1
> > > > Duplicate ID 'net1' for device
> > > > (qemu)
> > >
> > > I cannot reproduce this on Fedora running the 2.0.0 package from the
> > > virt-preview repository (qemu-system-x86-2.0.0-2.fc20.x86_64).
> > >
> > > For what it's worth, I get this for --version:
> > >
> > > $ qemu-system-x86_64 --version
> > > QEMU emulator version 2.0.0, Copyright (c) 2003-2008 Fabrice Bellard
> > >
> > > and likewise, when starting QEMU with "-monitor stdio":
> > >
> > > QEMU 2.0.0 monitor - type 'help' for more information
> > >
> > I got the QEMU 2.0.0 version from http://wiki.qemu.org/Download
> >
> > The issue was reproduced perforce:
> > UVP:/mnt/sdb/gonglei/code/qemu-2.0.0/x86_64-softmmu
> #./qemu-system-x86_64 -enable-kvm -m 4096 -smp 4 -name sles \
> >  -boot c -drive file=/mnt/sdb/gonglei/image/sles-3.img -vnc 0.0.0.0:10
> -monitor stdio
> > QEMU 2.0.0 monitor - type 'help' for more information
> > (qemu) device_add virtio-net-pci,id=net1
> > (qemu) device_del net1
> > (qemu)  device_add virtio-net-pci,id=net1
> > Duplicate ID 'net1' for device
> > (qemu)
> >
> > Anything wrong? Thanks!
> 
> Issue confirmed with both -monitor and qmp-shell with different other device
> models like e1000.

Thanks. This issue confused me two weeks now, any helps will be appreciated.

Cc'ing Peter and Michael for additional insights.


Best regards,
-Gonglei



Re: [Qemu-devel] [PATCH v3 00/12] block/json: Add JSON protocol driver

2014-05-06 Thread Stefan Hajnoczi
On Mon, May 05, 2014 at 06:19:07PM +0200, Max Reitz wrote:
> On 10.04.2014 20:43, Max Reitz wrote:
> >This series adds a passthrough JSON protocol block driver. Its filenames
> >are JSON objects prefixed by "json:". The objects are used as options
> >for opening another block device which will be the child of the JSON
> >device. Regarding this child device, the JSON driver behaves nearly the
> >same as raw_bsd in that it is just a passthrough driver. The only
> >difference is probably that the JSON driver identifies itself as a block
> >filter, in contrast to raw_bsd.
> >
> >The purpose of this driver is that it may sometimes be desirable to
> >specify options for a block device where only a filename can be given,
> >e.g., for backing files. Using this should obviously be the exception,
> >but it is nice to have if actually needed.
> 
> Ping – I do understand that Kevin has reservations against this
> series, but as long as he doesn't explicitly ask me to reimplement
> this in bdrv_open() without an own block driver (which I'd more or
> less gladly do), I do not see issues why this series should not be
> merged.

I haven't reviewed it further because it seems like a kludge (that we
have to keep supporting once it's merged).  Was hoping you and Kevin
will come up with a long-term fix instead.

Kevin: Any new ideas on this patch series?

Stefan



Re: [Qemu-devel] [PATCH 009/124] vmstate: Refactor opening of files

2014-05-06 Thread Amit Shah
On (Mon) 21 Apr 2014 [16:39:49], Juan Quintela wrote:
> Signed-off-by: Juan Quintela 
> ---
>  tests/test-vmstate.c | 38 +++---
>  1 file changed, 19 insertions(+), 19 deletions(-)

Reviewed-by: Amit Shah 

Amit



Re: [Qemu-devel] [PATCH v1 00/22] target-arm: Preparations for A64 EL2 and 3

2014-05-06 Thread Alexander Graf

On 05/06/2014 08:08 AM, Edgar E. Iglesias wrote:

From: "Edgar E. Iglesias" 

Hi,

I've been doing some work on modeling parts of EL2 and 3 + some of
the system-wide virtualization features for ARMv8. A lot is missing
but I've got a series with enough to for example run KVM A64 guests
on top of EL3 firmware inside emulated QEMU A64 VMs.
I'm working on cleaning things up and plan to send patches and publish
things as I go.

This series does a first round of preparations. Most of it has little
or no user visible impact as the EL2 and 3 features remain disabled.

For the arrayification of the various EL regs that do not exist for
EL0, I've used index macros. I don't really have a preference here,
so if you have better/less ugly ideas or preferences I'm happy to change
the pattern (getters/setters or whatever).

Happy to address any comments people may have.


I've only had a rough glimpse at the patches, but so far things look 
pretty sane.



Alex




Re: [Qemu-devel] [PATCH v5 0/3] Add common QEMU control functionality to qemu-iotests

2014-05-06 Thread Stefan Hajnoczi
On Mon, May 05, 2014 at 05:32:09PM +0200, Kevin Wolf wrote:
> Am 05.05.2014 um 17:21 hat Stefan Hajnoczi geschrieben:
> > On Wed, Apr 30, 2014 at 10:55:07AM -0400, Jeff Cody wrote:
> > > This adds some common functionality to control QEMU for qemu-iotests.
> > > 
> > > Additionally, test 085 is updated to use this new functionality.
> > > 
> > > Some minor fixups along the way, to clear up spaced pathname issues, 
> > > for common.rc, test 019, and test 086.
> > > 
> > > 
> > > Jeff Cody (3):
> > >   block: qemu-iotests - add common.qemu, for bash-controlled qemu tests
> > 
> > Once a test launches QEMU, it soon needs to parse QMP commands or wait
> > for QMP events.  That doesn't lend itself to the traditional
> > qemu-iotests shell model.  That is why iotests.py exists.
> > 
> > Shell script is a poor language for test cases that go beyond
> > pre-defined commands whose output is saved for diffing.  The string
> > manipulation is clumsy, JSON is not supported, tricks with fifos can
> > easily deadlock or break when a process terminates unexpectedly, etc.
> > 
> > If we go further in the direction of this patch series, we'll duplicate
> > existing iotests.py code and have complex shell tests that are hard to
> > extend.  I think it's time to draw the line and convert any test cases
> > that need to complexity to Python.
> > 
> > Why not use iotests.py?
> 
> Because it's hard to use. The "compare against reference output" thing
> is the first thing that you lose with iotests.py, and it's the most
> useful feature in qemu-iotests.
> 
> When a Python test case fails, you get into real debugging. When a shell
> script test case fails, you usually see immediately from the reference
> output diff what's wrong.
> 
> I accept iotest.py for anything that needs to evaluate QMP return
> values, reluctantly, because we have nothing better. But that's it, I
> don't actually _like_ using it.

I agree with what you say but we're arguing about different things.

I'm saying:
 * For command output diff tests, use shell.
 * For tests that interact dynamically with running QEMU, use
   iotests.py.

You're saying:
 * Command output diff tests are easy to understand and debug.
 * Tests that interact dynamically with QEMU are harder to debug.

Just because we like the simple shell tests better doesn't mean writing
complex interaction tests in shell will make them simple!

These test cases in this patch aren't simple shell tests.  Let's admit
they are complex and use iotests.py, which is a more appropriate tool
for managing a running QEMU process and interacting with it.

Stefan



Re: [Qemu-devel] [PATCH v5 0/3] Add common QEMU control functionality to qemu-iotests

2014-05-06 Thread Stefan Hajnoczi
On Mon, May 05, 2014 at 11:44:55AM -0400, Jeff Cody wrote:
> On Mon, May 05, 2014 at 05:32:09PM +0200, Kevin Wolf wrote:
> > Am 05.05.2014 um 17:21 hat Stefan Hajnoczi geschrieben:
> > > On Wed, Apr 30, 2014 at 10:55:07AM -0400, Jeff Cody wrote:
> > > > This adds some common functionality to control QEMU for qemu-iotests.
> > > > 
> > > > Additionally, test 085 is updated to use this new functionality.
> > > > 
> > > > Some minor fixups along the way, to clear up spaced pathname issues, 
> > > > for common.rc, test 019, and test 086.
> > > > 
> > > > 
> > > > Jeff Cody (3):
> > > >   block: qemu-iotests - add common.qemu, for bash-controlled qemu tests
> > > 
> > > Once a test launches QEMU, it soon needs to parse QMP commands or wait
> > > for QMP events.  That doesn't lend itself to the traditional
> > > qemu-iotests shell model.  That is why iotests.py exists.
> > > 
> > > Shell script is a poor language for test cases that go beyond
> > > pre-defined commands whose output is saved for diffing.  The string
> > > manipulation is clumsy, JSON is not supported, tricks with fifos can
> > > easily deadlock or break when a process terminates unexpectedly, etc.
> > > 
> > > If we go further in the direction of this patch series, we'll duplicate
> > > existing iotests.py code and have complex shell tests that are hard to
> > > extend.  I think it's time to draw the line and convert any test cases
> > > that need to complexity to Python.
> > > 
> > > Why not use iotests.py?
> > 
> > Because it's hard to use. The "compare against reference output" thing
> > is the first thing that you lose with iotests.py, and it's the most
> > useful feature in qemu-iotests.
> > 
> > When a Python test case fails, you get into real debugging. When a shell
> > script test case fails, you usually see immediately from the reference
> > output diff what's wrong.
> > 
> > I accept iotest.py for anything that needs to evaluate QMP return
> > values, reluctantly, because we have nothing better. But that's it, I
> > don't actually _like_ using it.
> >
> 
> I agree with Kevin.  
> 
> Also, for a test framework, having some language duplication is not
> necessarily a *bad* thing.  One, functionality may be tested in
> slightly different ways, due to architectural differences.  Second, it
> gives developers increased flexibility in writing test cases in a
> language they may be more comfortable in - and that hopefully leads to
> an increased number of tests being written.

It's duplicated effort for the test case authors.  It also requires that
people debugging broken tests switch between different frameworks
depending on the test case that's failing.  We already have two types of
test case (simple and QEMU interaction), now a third is being added that
duplicates QEMU interaction.

Regarding the language, you can get comfortable with Python in an
afternoon.  If you already know C++, Java, Perl, or Ruby then it's very
easy to pick up:
https://docs.python.org/2.7/tutorial/index.html

> And if you look at the actual tests (091 and 085, in this case), the
> framework is pretty simple to use. If you run into something
> unsupported (json parsing, etc.), then you can use iotests.py.

You can already do this stuff in iotests.py but you still wrote it in
shell :).  So I'm not sure I buy that.

Stefan



Re: [Qemu-devel] [PATCH 00/22] dataplane: use QEMU block layer

2014-05-06 Thread Stefan Hajnoczi
On Mon, May 05, 2014 at 02:46:09PM +0200, Christian Borntraeger wrote:
> On 05/05/14 14:05, Stefan Hajnoczi wrote:
> > On Mon, May 05, 2014 at 11:17:44AM +0200, Christian Borntraeger wrote:
> >> On 01/05/14 16:54, Stefan Hajnoczi wrote:
> >>> This patch series switches virtio-blk data-plane from a custom Linux AIO
> >>> request queue to the QEMU block layer.  The previous "raw files only"
> >>> limitation is lifted.  All image formats and protocols can now be used 
> >>> with
> >>> virtio-blk data-plane.
> >>
> >> Nice. Is there a git branch somewhere, so that we can test this on s390?
> > 
> > Hi Christian,
> > I'm getting to work on v2 but you can grab this v1 series from git in
> > the meantime:
> > 
> > https://github.com/stefanha/qemu.git bdrv_set_aio_context
> > 
> > Stefan
> > 
> 
> In general the main path seems to work fine.
> 
> With lots of devices (one qcow2, 23 raw scsi disks)
> I get a hang on shutdown. kvm_stat claims that nothing is going on any more, 
> but somehow threads are stuck in ppoll.
> 
> gdb tells me that 
> 
> all cpus have
> #0  0x03fffcde0ba0 in __lll_lock_wait () from /lib64/libpthread.so.0
> #1  0x03fffcde3c0c in __pthread_mutex_cond_lock () from 
> /lib64/libpthread.so.0
> #2  0x03fffcddc99a in pthread_cond_wait@@GLIBC_2.3.2 () from 
> /lib64/libpthread.so.0
> #3  0x801f183a in qemu_cond_wait (cond=, 
> mutex=mutex@entry=0x8072ba30 ) at 
> /home/cborntra/REPOS/qemu/util/qemu-thread-posix.c:135
> #4  0x801512f2 in qemu_kvm_wait_io_event (cpu=) at 
> /home/cborntra/REPOS/qemu/cpus.c:842
> #5  qemu_kvm_cpu_thread_fn (arg=0x80a53e10) at 
> /home/cborntra/REPOS/qemu/cpus.c:878
> 
> all iothreads have
> #0  0x03fffbc348e0 in ppoll () from /lib64/libc.so.6
> #1  0x800fcce6 in ppoll (__ss=0x0, __timeout=0x0, __nfds= out>, __fds=) at /usr/include/bits/poll2.h:77
> #2  qemu_poll_ns (fds=fds@entry=0x3fff4001b00, nfds=nfds@entry=3, timeout=-1) 
> at /home/cborntra/REPOS/qemu/qemu-timer.c:311
> #3  0x8001ae4c in aio_poll (ctx=0x807dd610, 
> blocking=blocking@entry=true) at /home/cborntra/REPOS/qemu/aio-posix.c:221
> #4  0x800b2f6c in iothread_run (opaque=0x807dd4c8) at 
> /home/cborntra/REPOS/qemu/iothread.c:41
> #5  0x03fffcdd8412 in start_thread () from /lib64/libpthread.so.0
> #6  0x03fffbc3f0ae in thread_start () from /lib64/libc.so.6
> 
> the main thread has
> Thread 1 (Thread 0x3fff9e5c9b0 (LWP 33684)):
> #0  0x03fffbc348e0 in ppoll () from /lib64/libc.so.6
> #1  0x800fcce6 in ppoll (__ss=0x0, __timeout=0x0, __nfds= out>, __fds=) at /usr/include/bits/poll2.h:77
> #2  qemu_poll_ns (fds=fds@entry=0x80ae8030, nfds=nfds@entry=4, timeout=-1) at 
> /home/cborntra/REPOS/qemu/qemu-timer.c:311
> #3  0x8001ae4c in aio_poll (ctx=ctx@entry=0x809a7ea0, 
> blocking=blocking@entry=true) at /home/cborntra/REPOS/qemu/aio-posix.c:221
> #4  0x80030c46 in bdrv_flush (bs=bs@entry=0x807e5900) at 
> /home/cborntra/REPOS/qemu/block.c:4904
> #5  0x80030ce8 in bdrv_flush_all () at 
> /home/cborntra/REPOS/qemu/block.c:3723
> #6  0x80152fe8 in do_vm_stop (state=) at 
> /home/cborntra/REPOS/qemu/cpus.c:538
> #7  vm_stop (state=) at /home/cborntra/REPOS/qemu/cpus.c:1219
> #8  0x in ?? ()
> 
> 
> How are the ppoll calls supposed to return if there is nothing going on?

The AioContext event loop has an event notifier to kick the AioContext.
This is how you can signal it from another thread.

> PS: I think I have seen this before recently during managedsave, so it might 
> have been introduced with the iothread rework instead of this one.

I suspect this is due to a race condition in bdrv_flush_all().  In this
series I added AioContext acquire/release for bdrv_close_all() so that
vl.c:main() shutdown works.  It's probably a similar issue.

Thanks for raising this issue, I'll investigate and send a fix.  I
suspect this is not the other issue which you saw during managedsave.

Stefan



Re: [Qemu-devel] [PATCH v5 0/3] Add common QEMU control functionality to qemu-iotests

2014-05-06 Thread Kevin Wolf
Am 06.05.2014 um 10:29 hat Stefan Hajnoczi geschrieben:
> On Mon, May 05, 2014 at 05:32:09PM +0200, Kevin Wolf wrote:
> > Am 05.05.2014 um 17:21 hat Stefan Hajnoczi geschrieben:
> > > On Wed, Apr 30, 2014 at 10:55:07AM -0400, Jeff Cody wrote:
> > > > This adds some common functionality to control QEMU for qemu-iotests.
> > > > 
> > > > Additionally, test 085 is updated to use this new functionality.
> > > > 
> > > > Some minor fixups along the way, to clear up spaced pathname issues, 
> > > > for common.rc, test 019, and test 086.
> > > > 
> > > > 
> > > > Jeff Cody (3):
> > > >   block: qemu-iotests - add common.qemu, for bash-controlled qemu tests
> > > 
> > > Once a test launches QEMU, it soon needs to parse QMP commands or wait
> > > for QMP events.  That doesn't lend itself to the traditional
> > > qemu-iotests shell model.  That is why iotests.py exists.
> > > 
> > > Shell script is a poor language for test cases that go beyond
> > > pre-defined commands whose output is saved for diffing.  The string
> > > manipulation is clumsy, JSON is not supported, tricks with fifos can
> > > easily deadlock or break when a process terminates unexpectedly, etc.
> > > 
> > > If we go further in the direction of this patch series, we'll duplicate
> > > existing iotests.py code and have complex shell tests that are hard to
> > > extend.  I think it's time to draw the line and convert any test cases
> > > that need to complexity to Python.
> > > 
> > > Why not use iotests.py?
> > 
> > Because it's hard to use. The "compare against reference output" thing
> > is the first thing that you lose with iotests.py, and it's the most
> > useful feature in qemu-iotests.
> > 
> > When a Python test case fails, you get into real debugging. When a shell
> > script test case fails, you usually see immediately from the reference
> > output diff what's wrong.
> > 
> > I accept iotest.py for anything that needs to evaluate QMP return
> > values, reluctantly, because we have nothing better. But that's it, I
> > don't actually _like_ using it.
> 
> I agree with what you say but we're arguing about different things.
> 
> I'm saying:
>  * For command output diff tests, use shell.
>  * For tests that interact dynamically with running QEMU, use
>iotests.py.

That's a false dichotomy to start with. What about test cases that
interact dynamically with running QEMU _and_ we want to use a command
output diff?

But, what this series is aiming at is not really "dynamic" interaction
at all. It is mostly just sending monitor commands and comparing the
return value to reference output. The only time it looks at the return
value is when it needs to wait for completion of something; and grep is
just fine for something like that.

Just have a look at the test cases that run qemu today. These shell
scripts turn out to be really simple. And as you can see in this series,
even things like migration are easy to do.

> You're saying:
>  * Command output diff tests are easy to understand and debug.
>  * Tests that interact dynamically with QEMU are harder to debug.

No. I'm specifically saying that iotests.py tests are harder to debug.
Even if they don't do much dynamic interaction.

> Just because we like the simple shell tests better doesn't mean writing
> complex interaction tests in shell will make them simple!
> 
> These test cases in this patch aren't simple shell tests.  Let's admit
> they are complex and use iotests.py, which is a more appropriate tool
> for managing a running QEMU process and interacting with it.

What's wrong with the tests in this series? I find them quite easy to
read and work with. But yes, I guess you can actually make them complex
by using iotest.py...

Kevin



Re: [Qemu-devel] [PATCH 1/3] s390x/helper: Fixed real-to-absolute address translation

2014-05-06 Thread Alexander Graf

On 05/05/2014 05:10 PM, Cornelia Huck wrote:

From: Thomas Huth 

The real-to-absolute address translation in mmu_translate() was
missing the second part for translating the page at the prefix
address back to the 0 page. And while we're at it, also moved the
code into a separate helper function since this might come in
handy for other parts of the code, too.

Signed-off-by: Thomas Huth 
Reviewed-by: David Hildenbrand 
Signed-off-by: Jens Freimann 
Signed-off-by: Cornelia Huck 


Reviewed-by: Alexander Graf 


Alex




Re: [Qemu-devel] [PATCH 0/5] glib thread interface and libcacard cleanups

2014-05-06 Thread Alon Levy
On 05/05/2014 07:36 PM, Michael Tokarev wrote:
> 05.05.2014 18:49, Alon Levy wrote:
>> On 04/29/2014 09:02 AM, Michael Tokarev wrote:
>>> Basically libgthread has been rewritten in glib version 2.31, and old ways
>>> to use thread primitives stopped working while new ways appeared.  The two
>>> interfaces were sufficiently different to warrant large ifdeffery across all
>>> code using it.
> [...]
> []
>> Reviewed-by: Alon Levy 
>> Tested-by: Alon Levy 
> 
> Hmm.  Now I'm a bit confused.  Which version did you test? :)
> 
> I posted a v2 patch which splits one of the changes into two
> (pstrcpy to memcpy conversion in libcacard), added some more
> (minor) changes (which should not affect libcacard code in
> any way), and adjusted commit messages.
> 
> The main code is not affected (or should not be), so Tested-by
> probably may stay, except of the pstrcpy to memcpy patch
> (http://patchwork.ozlabs.org/patch/345002/) which may affect
> libcacard.
> 
> Here's the v2: 
> http://lists.gnu.org/archive/html/qemu-devel/2014-05/msg00286.html
> 
> If you tested the git branch which I referred to, that's the
> v2, not original submission which you're replying to.

I've tested and reviewed 7191b2c43eecc52994924245720c534ea1a0dc84 so v2,
my bad.

> 
>> This would be nice to have too (it has nothing to do with your patchset,
>> but it would save me a pull request):
>>
>> commit 2fc95f8bc1912e2de243389d9d102a5a28267f31
>> Author: Alon Levy 
>> Date:   Mon May 5 17:41:32 2014 +0300
>>
>> libcacard: remove unnecessary EOL from debug prints
> 
> Well, this can easily go to -trivial, as I'm planning to send a pull
> request for it soon anyway.
> 
> Thank you!
> 
> /mjt
> 




[Qemu-devel] [PATCH v3.1 11/31] numa: introduce memory_region_allocate_system_memory

2014-05-06 Thread Hu Tao
From: Paolo Bonzini 

Signed-off-by: Paolo Bonzini 
Signed-off-by: Hu Tao 
---
 hw/i386/pc.c| 4 +---
 include/hw/boards.h | 6 +-
 include/sysemu/sysemu.h | 1 +
 numa.c  | 9 +
 4 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index d5fb884..571dc72 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1181,9 +1181,7 @@ FWCfgState *pc_memory_init(QEMUMachineInitArgs *args,
  * with older qemus that used qemu_ram_alloc().
  */
 ram = g_malloc(sizeof(*ram));
-memory_region_init_ram(ram, NULL, "pc.ram",
-   below_4g_mem_size + above_4g_mem_size);
-vmstate_register_ram_global(ram);
+memory_region_allocate_system_memory(ram, NULL, "pc.ram", args->ram_size);
 *ram_memory = ram;
 ram_below_4g = g_malloc(sizeof(*ram_below_4g));
 memory_region_init_alias(ram_below_4g, NULL, "ram-below-4g", ram,
diff --git a/include/hw/boards.h b/include/hw/boards.h
index dd2c70d..1ea52c0 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -50,9 +50,13 @@ struct QEMUMachine {
 const char *hw_version;
 };
 
-#define TYPE_MACHINE_SUFFIX "-machine"
+void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner,
+  const char *name,
+  uint64_t ram_size);
+
 int qemu_register_machine(QEMUMachine *m);
 
+#define TYPE_MACHINE_SUFFIX "-machine"
 #define TYPE_MACHINE "machine"
 #undef MACHINE  /* BSD defines it and QEMU does not use it */
 #define MACHINE(obj) \
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 423d49e..caf88dd 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -10,6 +10,7 @@
 #include "qemu/notify.h"
 #include "qemu/main-loop.h"
 #include "qemu/bitmap.h"
+#include "qom/object.h"
 
 /* vl.c */
 
diff --git a/numa.c b/numa.c
index 439df87..bcd7b04 100644
--- a/numa.c
+++ b/numa.c
@@ -33,6 +33,7 @@
 #include "qapi/opts-visitor.h"
 #include "qapi/dealloc-visitor.h"
 #include "qapi/qmp/qerror.h"
+#include "hw/boards.h"
 
 QemuOptsList qemu_numa_opts = {
 .name = "numa",
@@ -194,3 +195,11 @@ void set_numa_modes(void)
 }
 }
 }
+
+void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner,
+  const char *name,
+  uint64_t ram_size)
+{
+memory_region_init_ram(mr, owner, name, ram_size);
+vmstate_register_ram_global(mr);
+}
-- 
1.8.5.2.229.g4448466




[Qemu-devel] [PATCH v3.1 02/31] NUMA: check if the total numa memory size is equal to ram_size

2014-05-06 Thread Hu Tao
From: Wanlong Gao 

If the total number of the assigned numa nodes memory is not
equal to the assigned ram size, it will write the wrong data
to ACPI table, then the guest will ignore the wrong ACPI table
and recognize all memory to one node. It's buggy, we should
check it to ensure that we write the right data to ACPI table.

Signed-off-by: Wanlong Gao 
Reviewed-by: Eduardo Habkost 
Signed-off-by: Paolo Bonzini 
Signed-off-by: Hu Tao 
---
 numa.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/numa.c b/numa.c
index 395c14f..1d2f761 100644
--- a/numa.c
+++ b/numa.c
@@ -27,6 +27,8 @@
 #include "exec/cpu-common.h"
 #include "qemu/bitmap.h"
 #include "qom/cpu.h"
+#include "qemu/error-report.h"
+#include "include/exec/cpu-common.h" /* for RAM_ADDR_FMT */
 
 static void numa_node_parse_cpus(int nodenr, const char *cpus)
 {
@@ -127,6 +129,7 @@ void numa_add(const char *optarg)
 void set_numa_nodes(void)
 {
 if (nb_numa_nodes > 0) {
+uint64_t numa_total;
 int i;
 
 if (nb_numa_nodes > MAX_NODES) {
@@ -154,6 +157,17 @@ void set_numa_nodes(void)
 node_mem[i] = ram_size - usedmem;
 }
 
+numa_total = 0;
+for (i = 0; i < nb_numa_nodes; i++) {
+numa_total += node_mem[i];
+}
+if (numa_total != ram_size) {
+error_report("qemu: total memory size for NUMA nodes (%" PRIu64 ")"
+ " should equal to ram_size (" RAM_ADDR_FMT ")\n",
+ numa_total, ram_size);
+exit(1);
+}
+
 for (i = 0; i < nb_numa_nodes; i++) {
 if (!bitmap_empty(node_cpumask[i], MAX_CPUMASK_BITS)) {
 break;
-- 
1.8.5.2.229.g4448466




[Qemu-devel] [PATCH v3.1 00/31] NUMA series, and hostmem improvements

2014-05-06 Thread Hu Tao
This series includes work on QOMifying the memory backends.
the idea is to delegate all properties of the memory backend to
a new QOM class hierarchy, in which the concrete classes
are hostmem-ram and hostmem-file.  The backend is passed to the
machine via "-numa node,memdev=foo" where "foo" is the id of the
backend object.

Changes from v3:

 - address comment by Paolo
 - fix bugs in string input visitor
 - no conversion to memory_region_allocate_system_memory of all boards
   I had patch for it but don't know how to test it for all boards.

Hu Tao (7):
  hostmem: add properties for NUMA memory policy
  Introduce signed range.
  qapi: make string input visitor parse int list
  qapi: make string output visitor parse int list
  qom: introduce object_property_get_enum and
object_property_get_uint16List
  qmp: add query-memdev
  hmp: add info memdev

Igor Mammedov (2):
  qmp: allow object-add completion handler to get canonical path
  add memdev backend infrastructure

Luiz Capitulino (1):
  man: improve -numa doc

Paolo Bonzini (15):
  vl: redo -object parsing
  qmp: improve error reporting for -object and object-add
  pc: pass QEMUMachineInitArgs to pc_memory_init
  numa: introduce memory_region_allocate_system_memory
  numa: add -numa node,memdev= option
  memory: reorganize file-based allocation
  memory: move mem_path handling to memory_region_allocate_system_memory
  memory: add error propagation to file-based RAM allocation
  memory: move preallocation code out of exec.c
  memory: move RAM_PREALLOC_MASK to exec.c, rename
  hostmem: add file-based HostMemoryBackend
  hostmem: separate allocation from UserCreatable complete method
  hostmem: add merge and dump properties
  hostmem: allow preallocation of any memory region
  hostmem: add property to map memory with MAP_SHARED

Wanlong Gao (6):
  NUMA: move numa related code to new file numa.c
  NUMA: check if the total numa memory size is equal to ram_size
  NUMA: Add numa_info structure to contain numa nodes info
  NUMA: convert -numa option to use OptsVisitor
  NUMA: expand MAX_NODES from 64 to 128
  configure: add Linux libnuma detection

 Makefile.target|   2 +-
 backends/Makefile.objs |   3 +
 backends/hostmem-file.c| 134 ++
 backends/hostmem-ram.c |  53 ++
 backends/hostmem.c | 349 
 configure  |  33 
 cpus.c |  14 --
 exec.c | 211 +++---
 hmp.c  |  36 
 hmp.h  |   1 +
 hw/i386/pc.c   |  27 +--
 hw/i386/pc_piix.c  |   8 +-
 hw/i386/pc_q35.c   |   4 +-
 hw/ppc/spapr.c |  11 +-
 include/exec/cpu-all.h |   8 -
 include/exec/cpu-common.h  |   2 +
 include/exec/memory.h  |  33 
 include/exec/ram_addr.h|   4 +
 include/hw/boards.h|   6 +-
 include/hw/i386/pc.h   |   7 +-
 include/qemu/osdep.h   |  12 ++
 include/qemu/range.h   | 124 +
 include/qom/object.h   |  28 +++
 include/sysemu/cpus.h  |   1 -
 include/sysemu/hostmem.h   |  66 +++
 include/sysemu/sysemu.h|  18 +-
 memory.c   |  29 +++
 monitor.c  |   9 +-
 numa.c | 355 +
 qapi-schema.json   |  91 ++
 qapi/string-input-visitor.c| 181 ++-
 qapi/string-output-visitor.c   | 230 ++--
 qemu-options.hx|  16 +-
 qmp-commands.hx|  32 
 qmp.c  |  14 +-
 qom/object.c   |  35 
 tests/test-string-input-visitor.c  |  39 
 tests/test-string-output-visitor.c |  34 
 util/oslib-posix.c |  73 
 vl.c   | 238 +
 40 files changed, 2187 insertions(+), 384 deletions(-)
 create mode 100644 backends/hostmem-file.c
 create mode 100644 backends/hostmem-ram.c
 create mode 100644 backends/hostmem.c
 create mode 100644 include/sysemu/hostmem.h
 create mode 100644 numa.c

-- 
1.8.5.2.229.g4448466




[Qemu-devel] [PATCH v3.1 09/31] qmp: improve error reporting for -object and object-add

2014-05-06 Thread Hu Tao
From: Paolo Bonzini 

Use QERR_INVALID_PARAMETER_VALUE for consistency.

Signed-off-by: Paolo Bonzini 
Signed-off-by: Hu Tao 
---
 qmp.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/qmp.c b/qmp.c
index ee99d3a..636e6f2 100644
--- a/qmp.c
+++ b/qmp.c
@@ -546,7 +546,8 @@ void object_add(const char *type, const char *id, const 
QDict *qdict,
 
 klass = object_class_by_name(type);
 if (!klass) {
-error_setg(errp, "invalid class name");
+error_set(errp, QERR_INVALID_PARAMETER_VALUE,
+  "qom-type", "a valid class name");
 return;
 }
 
-- 
1.8.5.2.229.g4448466




[Qemu-devel] [PATCH v3.1 08/31] qmp: allow object-add completion handler to get canonical path

2014-05-06 Thread Hu Tao
From: Igor Mammedov 

Add object to /objects before calling user_creatable_complete()
handler, so that object might be able to call
object_get_canonical_path() in its completion handler.

Signed-off-by: Igor Mammedov 
Signed-off-by: Paolo Bonzini 
Signed-off-by: Hu Tao 
---
 qmp.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/qmp.c b/qmp.c
index 74107be..ee99d3a 100644
--- a/qmp.c
+++ b/qmp.c
@@ -571,13 +571,18 @@ void object_add(const char *type, const char *id, const 
QDict *qdict,
 }
 }
 
-user_creatable_complete(obj, &local_err);
+object_property_add_child(container_get(object_get_root(), "/objects"),
+  id, obj, &local_err);
 if (local_err) {
 goto out;
 }
 
-object_property_add_child(container_get(object_get_root(), "/objects"),
-  id, obj, &local_err);
+user_creatable_complete(obj, &local_err);
+if (local_err) {
+object_property_del(container_get(object_get_root(), "/objects"),
+id, &error_abort);
+goto out;
+}
 out:
 if (local_err) {
 error_propagate(errp, local_err);
-- 
1.8.5.2.229.g4448466




[Qemu-devel] [PATCH v3.1 15/31] memory: move mem_path handling to memory_region_allocate_system_memory

2014-05-06 Thread Hu Tao
From: Paolo Bonzini 

Like the previous patch did in exec.c, split memory_region_init_ram and
memory_region_init_ram_from_file, and push mem_path one step further up.
Other RAM regions than system memory will now be backed by regular RAM.

Also, boards that do not use memory_region_allocate_system_memory will
not support -mem-path anymore.  This can be changed before the patches
are merged by migrating boards to use the function.

Signed-off-by: Paolo Bonzini 
Signed-off-by: Hu Tao 
---
 exec.c| 10 ++
 include/exec/memory.h | 18 ++
 memory.c  | 21 -
 numa.c| 11 ++-
 4 files changed, 46 insertions(+), 14 deletions(-)

diff --git a/exec.c b/exec.c
index 8ae8b95..379472d 100644
--- a/exec.c
+++ b/exec.c
@@ -1130,14 +1130,6 @@ error:
 }
 return NULL;
 }
-#else
-static void *file_ram_alloc(RAMBlock *block,
-ram_addr_t memory,
-const char *path)
-{
-fprintf(stderr, "-mem-path not supported on this host\n");
-exit(1);
-}
 #endif
 
 static ram_addr_t find_ram_offset(ram_addr_t size)
@@ -1311,6 +1303,7 @@ static ram_addr_t ram_block_add(RAMBlock *new_block)
 return new_block->offset;
 }
 
+#ifdef __linux__
 ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
 const char *mem_path)
 {
@@ -1339,6 +1332,7 @@ ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, 
MemoryRegion *mr,
 new_block->host = file_ram_alloc(new_block, size, mem_path);
 return ram_block_add(new_block);
 }
+#endif
 
 ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
MemoryRegion *mr)
diff --git a/include/exec/memory.h b/include/exec/memory.h
index c084db2..75d4635 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -311,6 +311,24 @@ void memory_region_init_ram(MemoryRegion *mr,
 const char *name,
 uint64_t size);
 
+#ifdef __linux__
+/**
+ * memory_region_init_ram_from_file:  Initialize RAM memory region with a
+ *mmap-ed backend.
+ *
+ * @mr: the #MemoryRegion to be initialized.
+ * @owner: the object that tracks the region's reference count
+ * @name: the name of the region.
+ * @size: size of the region.
+ * @path: the path in which to allocate the RAM.
+ */
+void memory_region_init_ram_from_file(MemoryRegion *mr,
+  struct Object *owner,
+  const char *name,
+  uint64_t size,
+  const char *path);
+#endif
+
 /**
  * memory_region_init_ram_ptr:  Initialize RAM memory region from a
  *  user-provided pointer.  Accesses into the
diff --git a/memory.c b/memory.c
index daaeb7e..677b8f3 100644
--- a/memory.c
+++ b/memory.c
@@ -1017,13 +1017,24 @@ void memory_region_init_ram(MemoryRegion *mr,
 mr->ram = true;
 mr->terminates = true;
 mr->destructor = memory_region_destructor_ram;
-if (mem_path) {
-mr->ram_addr = qemu_ram_alloc_from_file(size, mr, mem_path);
-} else {
-mr->ram_addr = qemu_ram_alloc(size, mr);
-}
+mr->ram_addr = qemu_ram_alloc(size, mr);
 }
 
+#ifdef __linux__
+void memory_region_init_ram_from_file(MemoryRegion *mr,
+  struct Object *owner,
+  const char *name,
+  uint64_t size,
+  const char *path)
+{
+memory_region_init(mr, owner, name, size);
+mr->ram = true;
+mr->terminates = true;
+mr->destructor = memory_region_destructor_ram;
+mr->ram_addr = qemu_ram_alloc_from_file(size, mr, path);
+}
+#endif
+
 void memory_region_init_ram_ptr(MemoryRegion *mr,
 Object *owner,
 const char *name,
diff --git a/numa.c b/numa.c
index b9850d7..e136612 100644
--- a/numa.c
+++ b/numa.c
@@ -229,7 +229,16 @@ static void allocate_system_memory_nonnuma(MemoryRegion 
*mr, Object *owner,
const char *name,
uint64_t ram_size)
 {
-memory_region_init_ram(mr, owner, name, ram_size);
+if (mem_path) {
+#ifdef __linux__
+memory_region_init_ram_from_file(mr, owner, name, ram_size, mem_path);
+#else
+fprintf(stderr, "-mem-path not supported on this host\n");
+exit(1);
+#endif
+} else {
+memory_region_init_ram(mr, owner, name, ram_size);
+}
 vmstate_register_ram_global(mr);
 }
 
-- 
1.8.5.2.229.g4448466




[Qemu-devel] [PATCH v3.1 12/31] add memdev backend infrastructure

2014-05-06 Thread Hu Tao
From: Igor Mammedov 

Provides framework for splitting host RAM allocation/
policies into a separate backend that could be used
by devices.

Initially only legacy RAM backend is provided, which
uses memory_region_init_ram() allocator and compatible
with every CLI option that affects memory_region_init_ram().

Signed-off-by: Igor Mammedov 
Signed-off-by: Paolo Bonzini 
Signed-off-by: Hu Tao 
---
 backends/Makefile.objs   |   2 +
 backends/hostmem-ram.c   |  54 +++
 backends/hostmem.c   | 109 +++
 include/sysemu/hostmem.h |  58 +
 4 files changed, 223 insertions(+)
 create mode 100644 backends/hostmem-ram.c
 create mode 100644 backends/hostmem.c
 create mode 100644 include/sysemu/hostmem.h

diff --git a/backends/Makefile.objs b/backends/Makefile.objs
index 42557d5..e6bdc11 100644
--- a/backends/Makefile.objs
+++ b/backends/Makefile.objs
@@ -6,3 +6,5 @@ common-obj-$(CONFIG_BRLAPI) += baum.o
 $(obj)/baum.o: QEMU_CFLAGS += $(SDL_CFLAGS) 
 
 common-obj-$(CONFIG_TPM) += tpm.o
+
+common-obj-y += hostmem.o hostmem-ram.o
diff --git a/backends/hostmem-ram.c b/backends/hostmem-ram.c
new file mode 100644
index 000..cbf7e5a
--- /dev/null
+++ b/backends/hostmem-ram.c
@@ -0,0 +1,54 @@
+/*
+ * QEMU Host Memory Backend
+ *
+ * Copyright (C) 2013 Red Hat Inc
+ *
+ * Authors:
+ *   Igor Mammedov 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#include "sysemu/hostmem.h"
+#include "qom/object_interfaces.h"
+
+#define TYPE_MEMORY_BACKEND_RAM "memory-ram"
+
+
+static void
+ram_backend_memory_init(UserCreatable *uc, Error **errp)
+{
+HostMemoryBackend *backend = MEMORY_BACKEND(uc);
+char *path;
+
+if (!backend->size) {
+error_setg(errp, "can't create backend with size 0");
+return;
+}
+
+path = object_get_canonical_path_component(OBJECT(backend));
+memory_region_init_ram(&backend->mr, OBJECT(backend), path,
+   backend->size);
+g_free(path);
+}
+
+static void
+ram_backend_class_init(ObjectClass *oc, void *data)
+{
+UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
+
+ucc->complete = ram_backend_memory_init;
+}
+
+static const TypeInfo ram_backend_info = {
+.name = TYPE_MEMORY_BACKEND_RAM,
+.parent = TYPE_MEMORY_BACKEND,
+.class_init = ram_backend_class_init,
+};
+
+static void register_types(void)
+{
+type_register_static(&ram_backend_info);
+}
+
+type_init(register_types);
diff --git a/backends/hostmem.c b/backends/hostmem.c
new file mode 100644
index 000..6f26605
--- /dev/null
+++ b/backends/hostmem.c
@@ -0,0 +1,109 @@
+/*
+ * QEMU Host Memory Backend
+ *
+ * Copyright (C) 2013 Red Hat Inc
+ *
+ * Authors:
+ *   Igor Mammedov 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#include "sysemu/hostmem.h"
+#include "sysemu/sysemu.h"
+#include "qapi/visitor.h"
+#include "qapi/qmp/qerror.h"
+#include "qom/object_interfaces.h"
+
+static void
+host_memory_backend_get_size(Object *obj, Visitor *v, void *opaque,
+const char *name, Error **errp)
+{
+HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+uint64_t value = backend->size;
+
+visit_type_size(v, &value, name, errp);
+}
+
+static void
+host_memory_backend_set_size(Object *obj, Visitor *v, void *opaque,
+const char *name, Error **errp)
+{
+HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+uint64_t value;
+
+if (memory_region_size(&backend->mr)) {
+error_setg(errp, "cannot change property value\n");
+return;
+}
+
+visit_type_size(v, &value, name, errp);
+if (error_is_set(errp)) {
+return;
+}
+if (!value) {
+error_setg(errp, "Property '%s.%s' doesn't take value '%" PRIu64 "'",
+   object_get_typename(obj), name , value);
+return;
+}
+backend->size = value;
+}
+
+static void host_memory_backend_initfn(Object *obj)
+{
+object_property_add(obj, "size", "int",
+host_memory_backend_get_size,
+host_memory_backend_set_size, NULL, NULL, NULL);
+}
+
+static void host_memory_backend_finalize(Object *obj)
+{
+HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+
+if (memory_region_size(&backend->mr)) {
+memory_region_destroy(&backend->mr);
+}
+}
+
+static void
+host_memory_backend_memory_init(UserCreatable *uc, Error **errp)
+{
+error_setg(errp, "memory_init is not implemented for type [%s]",
+   object_get_typename(OBJECT(uc)));
+}
+
+MemoryRegion *
+host_memory_backend_get_memory(HostMemoryBackend *backend, Error **errp)
+{
+return memory_region_size(&backend->mr) ? &backend->mr : NULL;
+}
+
+static void
+host_memory_backend_class_init(ObjectClass *oc, void *data)
+{
+  

[Qemu-devel] [PATCH v3.1 03/31] NUMA: Add numa_info structure to contain numa nodes info

2014-05-06 Thread Hu Tao
From: Wanlong Gao 

Add the numa_info structure to contain the numa nodes memory,
VCPUs information and the future added numa nodes host memory
policies.

Reviewed-by: Eduardo Habkost 
Signed-off-by: Andre Przywara 
Signed-off-by: Wanlong Gao 
[Fix hw/ppc/spapr.c - Paolo]
Signed-off-by: Paolo Bonzini 

Signed-off-by: Hu Tao 
---
 hw/i386/pc.c| 12 
 hw/ppc/spapr.c  | 11 ++-
 include/sysemu/sysemu.h |  8 ++--
 monitor.c   |  2 +-
 numa.c  | 23 ---
 vl.c|  7 +++
 6 files changed, 36 insertions(+), 27 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 14f0d91..249e504 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -675,14 +675,14 @@ static FWCfgState *bochs_bios_init(void)
 unsigned int apic_id = x86_cpu_apic_id_from_index(i);
 assert(apic_id < apic_id_limit);
 for (j = 0; j < nb_numa_nodes; j++) {
-if (test_bit(i, node_cpumask[j])) {
+if (test_bit(i, numa_info[j].node_cpu)) {
 numa_fw_cfg[apic_id + 1] = cpu_to_le64(j);
 break;
 }
 }
 }
 for (i = 0; i < nb_numa_nodes; i++) {
-numa_fw_cfg[apic_id_limit + 1 + i] = cpu_to_le64(node_mem[i]);
+numa_fw_cfg[apic_id_limit + 1 + i] = 
cpu_to_le64(numa_info[i].node_mem);
 }
 fw_cfg_add_bytes(fw_cfg, FW_CFG_NUMA, numa_fw_cfg,
  (1 + apic_id_limit + nb_numa_nodes) *
@@ -1093,8 +1093,12 @@ PcGuestInfo *pc_guest_info_init(ram_addr_t 
below_4g_mem_size,
 guest_info->apic_id_limit = pc_apic_id_limit(max_cpus);
 guest_info->apic_xrupt_override = kvm_allows_irq0_override();
 guest_info->numa_nodes = nb_numa_nodes;
-guest_info->node_mem = g_memdup(node_mem, guest_info->numa_nodes *
+guest_info->node_mem = g_malloc0(guest_info->numa_nodes *
 sizeof *guest_info->node_mem);
+for (i = 0; i < nb_numa_nodes; i++) {
+guest_info->node_mem[i] = numa_info[i].node_mem;
+}
+
 guest_info->node_cpu = g_malloc0(guest_info->apic_id_limit *
  sizeof *guest_info->node_cpu);
 
@@ -1102,7 +1106,7 @@ PcGuestInfo *pc_guest_info_init(ram_addr_t 
below_4g_mem_size,
 unsigned int apic_id = x86_cpu_apic_id_from_index(i);
 assert(apic_id < guest_info->apic_id_limit);
 for (j = 0; j < nb_numa_nodes; j++) {
-if (test_bit(i, node_cpumask[j])) {
+if (test_bit(i, numa_info[j].node_cpu)) {
 guest_info->node_cpu[apic_id] = j;
 break;
 }
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index a11e121..89f71a8 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -538,8 +538,8 @@ static int spapr_populate_memory(sPAPREnvironment *spapr, 
void *fdt)
 int i, off;
 
 /* memory node(s) */
-if (nb_numa_nodes > 1 && node_mem[0] < ram_size) {
-node0_size = node_mem[0];
+if (nb_numa_nodes > 1 && numa_info[0].node_mem < ram_size) {
+node0_size = numa_info[0].node_mem;
 } else {
 node0_size = ram_size;
 }
@@ -577,7 +577,7 @@ static int spapr_populate_memory(sPAPREnvironment *spapr, 
void *fdt)
 if (mem_start >= ram_size) {
 node_size = 0;
 } else {
-node_size = node_mem[i];
+node_size = numa_info[i].node_mem;
 if (node_size > ram_size - mem_start) {
 node_size = ram_size - mem_start;
 }
@@ -722,7 +722,8 @@ static void spapr_reset_htab(sPAPREnvironment *spapr)
 
 /* Update the RMA size if necessary */
 if (spapr->vrma_adjust) {
-hwaddr node0_size = (nb_numa_nodes > 1) ? node_mem[0] : ram_size;
+hwaddr node0_size = (nb_numa_nodes > 1) ?
+numa_info[0].node_mem : ram_size;
 spapr->rma_size = kvmppc_rma_size(node0_size, spapr->htab_shift);
 }
 }
@@ -1155,7 +1156,7 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args)
 MemoryRegion *sysmem = get_system_memory();
 MemoryRegion *ram = g_new(MemoryRegion, 1);
 hwaddr rma_alloc_size;
-hwaddr node0_size = (nb_numa_nodes > 1) ? node_mem[0] : ram_size;
+hwaddr node0_size = (nb_numa_nodes > 1) ? numa_info[0].node_mem : ram_size;
 uint32_t initrd_base = 0;
 long kernel_size = 0, initrd_size = 0;
 long load_limit, rtas_limit, fw_size;
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 565c8f6..3a9308b 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -9,6 +9,7 @@
 #include "qapi-types.h"
 #include "qemu/notify.h"
 #include "qemu/main-loop.h"
+#include "qemu/bitmap.h"
 
 /* vl.c */
 
@@ -142,8 +143,11 @@ extern QEMUClockType rtc_clock;
 #define MAX_CPUMASK_BITS 255
 
 extern int nb_numa_nodes;
-extern uint64_t node_mem[MAX_NODES];
-extern unsigned long *node_cpumask[MAX_NODES];
+typedef struct node_info {
+uint64_t node_mem;
+DECLARE_BITMAP(node_cpu, MAX_CPUMA

[Qemu-devel] [PATCH v3.1 07/31] vl: redo -object parsing

2014-05-06 Thread Hu Tao
From: Paolo Bonzini 

Follow the lines of the HMP implementation, using OptsVisitor
to parse the options.  This gives access to OptsVisitor's
rich parsing of integer lists.

Signed-off-by: Paolo Bonzini 
Signed-off-by: Hu Tao 
---
 vl.c | 87 +++-
 1 file changed, 35 insertions(+), 52 deletions(-)

diff --git a/vl.c b/vl.c
index 78144c4..167856e 100644
--- a/vl.c
+++ b/vl.c
@@ -115,8 +115,7 @@ int main(int argc, char **argv)
 #include "qemu/osdep.h"
 
 #include "ui/qemu-spice.h"
-#include "qapi/string-input-visitor.h"
-#include "qom/object_interfaces.h"
+#include "qapi/opts-visitor.h"
 
 #define DEFAULT_RAM_SIZE 128
 
@@ -2768,69 +2767,53 @@ static void free_and_trace(gpointer mem)
 free(mem);
 }
 
-static int object_set_property(const char *name, const char *value, void 
*opaque)
-{
-Object *obj = OBJECT(opaque);
-StringInputVisitor *siv;
-Error *local_err = NULL;
-
-if (strcmp(name, "qom-type") == 0 || strcmp(name, "id") == 0) {
-return 0;
-}
-
-siv = string_input_visitor_new(value);
-object_property_set(obj, string_input_get_visitor(siv), name, &local_err);
-string_input_visitor_cleanup(siv);
-
-if (local_err) {
-qerror_report_err(local_err);
-error_free(local_err);
-return -1;
-}
-
-return 0;
-}
-
 static int object_create(QemuOpts *opts, void *opaque)
 {
-const char *type = qemu_opt_get(opts, "qom-type");
-const char *id = qemu_opts_id(opts);
-Error *local_err = NULL;
-Object *obj;
-
-g_assert(type != NULL);
-
-if (id == NULL) {
-qerror_report(QERR_MISSING_PARAMETER, "id");
-return -1;
+Error *err = NULL;
+char *type = NULL;
+char *id = NULL;
+void *dummy = NULL;
+OptsVisitor *ov;
+QDict *pdict;
+
+ov = opts_visitor_new(opts);
+pdict = qemu_opts_to_qdict(opts, NULL);
+
+visit_start_struct(opts_get_visitor(ov), &dummy, NULL, NULL, 0, &err);
+if (err) {
+goto out;
 }
 
-obj = object_new(type);
-if (qemu_opt_foreach(opts, object_set_property, obj, 1) < 0) {
-object_unref(obj);
-return -1;
+qdict_del(pdict, "qom-type");
+visit_type_str(opts_get_visitor(ov), &type, "qom-type", &err);
+if (err) {
+goto out;
 }
 
-if (!object_dynamic_cast(obj, TYPE_USER_CREATABLE)) {
-error_setg(&local_err, "object '%s' isn't supported by -object",
-   id);
+qdict_del(pdict, "id");
+visit_type_str(opts_get_visitor(ov), &id, "id", &err);
+if (err) {
 goto out;
 }
 
-user_creatable_complete(obj, &local_err);
-if (local_err) {
+object_add(type, id, pdict, opts_get_visitor(ov), &err);
+if (err) {
 goto out;
 }
-
-object_property_add_child(container_get(object_get_root(), "/objects"),
-  id, obj, &local_err);
+visit_end_struct(opts_get_visitor(ov), &err);
+if (err) {
+qmp_object_del(id, NULL);
+}
 
 out:
-object_unref(obj);
-if (local_err) {
-qerror_report_err(local_err);
-error_free(local_err);
-return -1;
+opts_visitor_cleanup(ov);
+
+QDECREF(pdict);
+g_free(id);
+g_free(type);
+g_free(dummy);
+if (err) {
+qerror_report_err(err);
 }
 return 0;
 }
-- 
1.8.5.2.229.g4448466




[Qemu-devel] [PATCH v3.1 18/31] memory: move RAM_PREALLOC_MASK to exec.c, rename

2014-05-06 Thread Hu Tao
From: Paolo Bonzini 

Prepare for adding more flags.  The "_MASK" suffix is unique, kill it.

Signed-off-by: Paolo Bonzini 
Signed-off-by: Hu Tao 
---
 exec.c | 9 ++---
 include/exec/cpu-all.h | 3 ---
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/exec.c b/exec.c
index 710e025..691d216 100644
--- a/exec.c
+++ b/exec.c
@@ -70,6 +70,9 @@ AddressSpace address_space_memory;
 MemoryRegion io_mem_rom, io_mem_notdirty;
 static MemoryRegion io_mem_unassigned;
 
+/* RAM is pre-allocated and passed into qemu_ram_alloc_from_ptr */
+#define RAM_PREALLOC   (1 << 0)
+
 #endif
 
 struct CPUTailQ cpus = QTAILQ_HEAD_INITIALIZER(cpus);
@@ -1316,7 +1319,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void 
*host,
 new_block->fd = -1;
 new_block->host = host;
 if (host) {
-new_block->flags |= RAM_PREALLOC_MASK;
+new_block->flags |= RAM_PREALLOC;
 }
 return ram_block_add(new_block);
 }
@@ -1355,7 +1358,7 @@ void qemu_ram_free(ram_addr_t addr)
 QTAILQ_REMOVE(&ram_list.blocks, block, next);
 ram_list.mru_block = NULL;
 ram_list.version++;
-if (block->flags & RAM_PREALLOC_MASK) {
+if (block->flags & RAM_PREALLOC) {
 ;
 } else if (xen_enabled()) {
 xen_invalidate_map_cache_entry(block->host);
@@ -1387,7 +1390,7 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length)
 offset = addr - block->offset;
 if (offset < block->length) {
 vaddr = block->host + offset;
-if (block->flags & RAM_PREALLOC_MASK) {
+if (block->flags & RAM_PREALLOC) {
 ;
 } else if (xen_enabled()) {
 abort();
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index dfdd071..6960544 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -414,9 +414,6 @@ CPUArchState *cpu_copy(CPUArchState *env);
 
 /* memory API */
 
-/* RAM is pre-allocated and passed into qemu_ram_alloc_from_ptr */
-#define RAM_PREALLOC_MASK   (1 << 0)
-
 typedef struct RAMBlock {
 struct MemoryRegion *mr;
 uint8_t *host;
-- 
1.8.5.2.229.g4448466




[Qemu-devel] [PATCH v3.1 06/31] man: improve -numa doc

2014-05-06 Thread Hu Tao
From: Luiz Capitulino 

The -numa option documentation in qemu's manpage lacks the command-line
options and some information regarding how it relates to options -m and
-smp. This commit fills in the missing text.

Signed-off-by: Luiz Capitulino 
Signed-off-by: Paolo Bonzini 
Signed-off-by: Hu Tao 
---
 qemu-options.hx | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/qemu-options.hx b/qemu-options.hx
index 781af14..c676397 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -97,10 +97,14 @@ ETEXI
 DEF("numa", HAS_ARG, QEMU_OPTION_numa,
 "-numa node[,mem=size][,cpus=cpu[-cpu]][,nodeid=node]\n", QEMU_ARCH_ALL)
 STEXI
-@item -numa @var{opts}
+@item -numa node[,mem=@var{size}][,cpus=@var{cpu[-cpu]}][,nodeid=@var{node}]
 @findex -numa
-Simulate a multi node NUMA system. If mem and cpus are omitted, resources
-are split equally.
+Simulate a multi node NUMA system. If @samp{mem}
+and @samp{cpus} are omitted, resources are split equally. Also, note
+that the -@option{numa} option doesn't allocate any of the specified
+resources. That is, it just assigns existing resources to NUMA nodes. This
+means that one still has to use the @option{-m}, @option{-smp} options
+to respectively allocate RAM and vCPUs.
 ETEXI
 
 DEF("add-fd", HAS_ARG, QEMU_OPTION_add_fd,
-- 
1.8.5.2.229.g4448466




[Qemu-devel] [PATCH v3.1 28/31] qapi: make string output visitor parse int list

2014-05-06 Thread Hu Tao
Signed-off-by: Hu Tao 
---
 qapi/string-output-visitor.c   | 230 +++--
 tests/test-string-output-visitor.c |  34 ++
 2 files changed, 254 insertions(+), 10 deletions(-)

diff --git a/qapi/string-output-visitor.c b/qapi/string-output-visitor.c
index fb1d2e8..ccebc7a 100644
--- a/qapi/string-output-visitor.c
+++ b/qapi/string-output-visitor.c
@@ -16,32 +16,173 @@
 #include "qapi/qmp/qerror.h"
 #include "qemu/host-utils.h"
 #include 
+#include "qemu/range.h"
+
+enum ListMode {
+LM_NONE, /* not traversing a list of repeated options */
+LM_STARTED,  /* start_list() succeeded */
+
+LM_IN_PROGRESS,  /* next_list() has been called.
+  *
+  * Generating the next list link will consume the most
+  * recently parsed QemuOpt instance of the repeated
+  * option.
+  *
+  * Parsing a value into the list link will examine the
+  * next QemuOpt instance of the repeated option, and
+  * possibly enter LM_SIGNED_INTERVAL or
+  * LM_UNSIGNED_INTERVAL.
+  */
+
+LM_SIGNED_INTERVAL,  /* next_list() has been called.
+  *
+  * Generating the next list link will consume the most
+  * recently stored element from the signed interval,
+  * parsed from the most recent QemuOpt instance of the
+  * repeated option. This may consume QemuOpt itself
+  * and return to LM_IN_PROGRESS.
+  *
+  * Parsing a value into the list link will store the
+  * next element of the signed interval.
+  */
+
+LM_UNSIGNED_INTERVAL,/* Same as above, only for an unsigned interval. */
+
+LM_END
+};
+
+typedef enum ListMode ListMode;
 
 struct StringOutputVisitor
 {
 Visitor visitor;
 bool human;
-char *string;
+GString *string;
+bool head;
+ListMode list_mode;
+union {
+int64_t s;
+uint64_t u;
+} range_start, range_end;
+SignedRangeList *ranges;
 };
 
 static void string_output_set(StringOutputVisitor *sov, char *string)
 {
-g_free(sov->string);
-sov->string = string;
+if (sov->string) {
+g_string_free(sov->string, true);
+}
+sov->string = g_string_new(string);
+g_free(string);
+}
+
+static void string_output_append(StringOutputVisitor *sov, int64_t a)
+{
+range_list_add(sov->ranges, a, 1);
+}
+
+static void string_output_append_range(StringOutputVisitor *sov,
+   int64_t s, int64_t e)
+{
+range_list_add(sov->ranges, s, e);
 }
 
 static void print_type_int(Visitor *v, int64_t *obj, const char *name,
Error **errp)
 {
 StringOutputVisitor *sov = DO_UPCAST(StringOutputVisitor, visitor, v);
-char *out;
+SignedRange *r;
+
+if (!sov->ranges) {
+sov->ranges = g_malloc0(sizeof(*sov->ranges));
+QTAILQ_INIT(sov->ranges);
+}
+
+switch (sov->list_mode) {
+case LM_NONE:
+string_output_append(sov, *obj);
+break;
+
+case LM_STARTED:
+sov->range_start.s = *obj;
+sov->range_end.s = *obj;
+sov->list_mode = LM_IN_PROGRESS;
+return;
+
+case LM_IN_PROGRESS:
+if (sov->range_end.s + 1 == *obj) {
+sov->range_end.s++;
+} else {
+if (sov->range_start.s == sov->range_end.s) {
+string_output_append(sov, sov->range_end.s);
+} else {
+assert(sov->range_start.s < sov->range_end.s);
+string_output_append_range(sov, sov->range_start.s,
+   sov->range_end.s -
+   sov->range_start.s + 1);
+}
+
+sov->range_start.s = *obj;
+sov->range_end.s = *obj;
+}
+return;
+
+case LM_END:
+if (sov->range_end.s + 1 == *obj) {
+sov->range_end.s++;
+assert(sov->range_start.s < sov->range_end.s);
+string_output_append_range(sov, sov->range_start.s,
+   sov->range_end.s -
+   sov->range_start.s + 1);
+} else {
+if (sov->range_start.s == sov->range_end.s) {
+string_output_append(sov, sov->range_end.s);
+} else {
+assert(sov->range_start.s < sov->range_end.s);
+
+string_output_append_range(sov, sov->range_start.s,
+   sov->range_end.s -
+   sov->range_start.s + 1);
+}
+string_outpu

[Qemu-devel] [PATCH v3.1 10/31] pc: pass QEMUMachineInitArgs to pc_memory_init

2014-05-06 Thread Hu Tao
From: Paolo Bonzini 

Signed-off-by: Paolo Bonzini 
Signed-off-by: Hu Tao 
---
 hw/i386/pc.c | 11 +--
 hw/i386/pc_piix.c|  8 +++-
 hw/i386/pc_q35.c |  4 +---
 include/hw/i386/pc.h |  7 +++
 4 files changed, 12 insertions(+), 18 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 249e504..d5fb884 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1161,10 +1161,8 @@ void pc_acpi_init(const char *default_dsdt)
 }
 }
 
-FWCfgState *pc_memory_init(MemoryRegion *system_memory,
-   const char *kernel_filename,
-   const char *kernel_cmdline,
-   const char *initrd_filename,
+FWCfgState *pc_memory_init(QEMUMachineInitArgs *args,
+   MemoryRegion *system_memory,
ram_addr_t below_4g_mem_size,
ram_addr_t above_4g_mem_size,
MemoryRegion *rom_memory,
@@ -1176,7 +1174,7 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory,
 MemoryRegion *ram_below_4g, *ram_above_4g;
 FWCfgState *fw_cfg;
 
-linux_boot = (kernel_filename != NULL);
+linux_boot = (args->kernel_filename != NULL);
 
 /* Allocate RAM.  We allocate it as a single memory region and use
  * aliases to address portions of it, mostly for backwards compatibility
@@ -1217,7 +1215,8 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory,
 rom_set_fw(fw_cfg);
 
 if (linux_boot) {
-load_linux(fw_cfg, kernel_filename, initrd_filename, kernel_cmdline, 
below_4g_mem_size);
+load_linux(fw_cfg, args->kernel_filename, args->initrd_filename,
+   args->kernel_cmdline, below_4g_mem_size);
 }
 
 for (i = 0; i < nb_option_roms; i++) {
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 7930a26..3bd8821 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -151,11 +151,9 @@ static void pc_init1(QEMUMachineInitArgs *args,
 
 /* allocate ram and load rom/bios */
 if (!xen_enabled()) {
-fw_cfg = pc_memory_init(system_memory,
-   args->kernel_filename, args->kernel_cmdline,
-   args->initrd_filename,
-   below_4g_mem_size, above_4g_mem_size,
-   rom_memory, &ram_memory, guest_info);
+fw_cfg = pc_memory_init(args, system_memory,
+below_4g_mem_size, above_4g_mem_size,
+rom_memory, &ram_memory, guest_info);
 }
 
 gsi_state = g_malloc0(sizeof(*gsi_state));
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index c844dc2..01794fc 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -138,9 +138,7 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
 
 /* allocate ram and load rom/bios */
 if (!xen_enabled()) {
-pc_memory_init(get_system_memory(),
-   args->kernel_filename, args->kernel_cmdline,
-   args->initrd_filename,
+pc_memory_init(args, get_system_memory(),
below_4g_mem_size, above_4g_mem_size,
rom_memory, &ram_memory, guest_info);
 }
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 9010246..8fc0527 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -3,6 +3,7 @@
 
 #include "qemu-common.h"
 #include "exec/memory.h"
+#include "hw/boards.h"
 #include "hw/isa/isa.h"
 #include "hw/block/fdc.h"
 #include "net/net.h"
@@ -134,10 +135,8 @@ PcGuestInfo *pc_guest_info_init(ram_addr_t 
below_4g_mem_size,
 void pc_pci_as_mapping_init(Object *owner, MemoryRegion *system_memory,
 MemoryRegion *pci_address_space);
 
-FWCfgState *pc_memory_init(MemoryRegion *system_memory,
-   const char *kernel_filename,
-   const char *kernel_cmdline,
-   const char *initrd_filename,
+FWCfgState *pc_memory_init(QEMUMachineInitArgs *args,
+   MemoryRegion *system_memory,
ram_addr_t below_4g_mem_size,
ram_addr_t above_4g_mem_size,
MemoryRegion *rom_memory,
-- 
1.8.5.2.229.g4448466




[Qemu-devel] [PATCH v3.1 14/31] memory: reorganize file-based allocation

2014-05-06 Thread Hu Tao
From: Paolo Bonzini 

Split the internal interface in exec.c to a separate function, and
push the check on mem_path up to memory_region_init_ram.

Signed-off-by: Paolo Bonzini 
Signed-off-by: Hu Tao 
---
 exec.c  | 105 +---
 include/exec/cpu-all.h  |   3 --
 include/exec/ram_addr.h |   2 +
 include/sysemu/sysemu.h |   2 +
 memory.c|   7 +++-
 5 files changed, 73 insertions(+), 46 deletions(-)

diff --git a/exec.c b/exec.c
index 91513c6..8ae8b95 100644
--- a/exec.c
+++ b/exec.c
@@ -1247,56 +1247,30 @@ static int memory_try_enable_merging(void *addr, size_t 
len)
 return qemu_madvise(addr, len, QEMU_MADV_MERGEABLE);
 }
 
-ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
-   MemoryRegion *mr)
+static ram_addr_t ram_block_add(RAMBlock *new_block)
 {
-RAMBlock *block, *new_block;
+RAMBlock *block;
 ram_addr_t old_ram_size, new_ram_size;
 
 old_ram_size = last_ram_offset() >> TARGET_PAGE_BITS;
 
-size = TARGET_PAGE_ALIGN(size);
-new_block = g_malloc0(sizeof(*new_block));
-new_block->fd = -1;
-
 /* This assumes the iothread lock is taken here too.  */
 qemu_mutex_lock_ramlist();
-new_block->mr = mr;
-new_block->offset = find_ram_offset(size);
-if (host) {
-new_block->host = host;
-new_block->flags |= RAM_PREALLOC_MASK;
-} else if (xen_enabled()) {
-if (mem_path) {
-fprintf(stderr, "-mem-path not supported with Xen\n");
-exit(1);
-}
-xen_ram_alloc(new_block->offset, size, mr);
-} else {
-if (mem_path) {
-if (phys_mem_alloc != qemu_anon_ram_alloc) {
-/*
- * file_ram_alloc() needs to allocate just like
- * phys_mem_alloc, but we haven't bothered to provide
- * a hook there.
- */
-fprintf(stderr,
-"-mem-path not supported with this accelerator\n");
-exit(1);
-}
-new_block->host = file_ram_alloc(new_block, size, mem_path);
-}
-if (!new_block->host) {
-new_block->host = phys_mem_alloc(size);
+new_block->offset = find_ram_offset(new_block->length);
+
+if (!new_block->host) {
+if (xen_enabled()) {
+xen_ram_alloc(new_block->offset, new_block->length, new_block->mr);
+} else {
+new_block->host = phys_mem_alloc(new_block->length);
 if (!new_block->host) {
 fprintf(stderr, "Cannot set up guest memory '%s': %s\n",
 new_block->mr->name, strerror(errno));
 exit(1);
 }
-memory_try_enable_merging(new_block->host, size);
+memory_try_enable_merging(new_block->host, new_block->length);
 }
 }
-new_block->length = size;
 
 /* Keep the list sorted from biggest to smallest block.  */
 QTAILQ_FOREACH(block, &ram_list.blocks, next) {
@@ -1324,18 +1298,65 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, 
void *host,
old_ram_size, new_ram_size);
}
 }
-cpu_physical_memory_set_dirty_range(new_block->offset, size);
+cpu_physical_memory_set_dirty_range(new_block->offset, new_block->length);
 
-qemu_ram_setup_dump(new_block->host, size);
-qemu_madvise(new_block->host, size, QEMU_MADV_HUGEPAGE);
-qemu_madvise(new_block->host, size, QEMU_MADV_DONTFORK);
+qemu_ram_setup_dump(new_block->host, new_block->length);
+qemu_madvise(new_block->host, new_block->length, QEMU_MADV_HUGEPAGE);
+qemu_madvise(new_block->host, new_block->length, QEMU_MADV_DONTFORK);
 
-if (kvm_enabled())
-kvm_setup_guest_memory(new_block->host, size);
+if (kvm_enabled()) {
+kvm_setup_guest_memory(new_block->host, new_block->length);
+}
 
 return new_block->offset;
 }
 
+ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
+const char *mem_path)
+{
+RAMBlock *new_block;
+
+if (xen_enabled()) {
+fprintf(stderr, "-mem-path not supported with Xen\n");
+exit(1);
+}
+
+if (phys_mem_alloc != qemu_anon_ram_alloc) {
+/*
+ * file_ram_alloc() needs to allocate just like
+ * phys_mem_alloc, but we haven't bothered to provide
+ * a hook there.
+ */
+fprintf(stderr,
+"-mem-path not supported with this accelerator\n");
+exit(1);
+}
+
+size = TARGET_PAGE_ALIGN(size);
+new_block = g_malloc0(sizeof(*new_block));
+new_block->mr = mr;
+new_block->length = size;
+new_block->host = file_ram_alloc(new_block, size, mem_path);
+return ram_block_add(new_block);
+}
+
+ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
+   MemoryRegion *mr)
+{
+  

[Qemu-devel] [PATCH v3.1 25/31] hostmem: add properties for NUMA memory policy

2014-05-06 Thread Hu Tao
Signed-off-by: Hu Tao 
[Raise errors on setting properties if !CONFIG_NUMA.  Add BUILD_BUG_ON
 checks. - Paolo]
Signed-off-by: Paolo Bonzini 

Signed-off-by: Hu Tao 
---
 backends/hostmem.c   | 109 ++-
 include/sysemu/hostmem.h |   4 ++
 qapi-schema.json |  20 +
 3 files changed, 132 insertions(+), 1 deletion(-)

diff --git a/backends/hostmem.c b/backends/hostmem.c
index 738bb31..d3f8476 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -10,11 +10,20 @@
  * See the COPYING file in the top-level directory.
  */
 #include "sysemu/hostmem.h"
-#include "sysemu/sysemu.h"
 #include "qapi/visitor.h"
+#include "qapi-types.h"
+#include "qapi-visit.h"
 #include "qapi/qmp/qerror.h"
 #include "qom/object_interfaces.h"
 
+#ifdef CONFIG_NUMA
+#include 
+QEMU_BUILD_BUG_ON(HOST_MEM_POLICY_DEFAULT != MPOL_DEFAULT);
+QEMU_BUILD_BUG_ON(HOST_MEM_POLICY_PREFERRED != MPOL_PREFERRED);
+QEMU_BUILD_BUG_ON(HOST_MEM_POLICY_BIND != MPOL_BIND);
+QEMU_BUILD_BUG_ON(HOST_MEM_POLICY_INTERLEAVE != MPOL_INTERLEAVE);
+#endif
+
 static void
 host_memory_backend_get_size(Object *obj, Visitor *v, void *opaque,
 const char *name, Error **errp)
@@ -49,6 +58,84 @@ host_memory_backend_set_size(Object *obj, Visitor *v, void 
*opaque,
 backend->size = value;
 }
 
+static void
+get_host_nodes(Object *obj, Visitor *v, void *opaque, const char *name,
+   Error **errp)
+{
+HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+uint16List *host_nodes = NULL;
+uint16List **node = &host_nodes;
+unsigned long value;
+
+value = find_first_bit(backend->host_nodes, MAX_NODES);
+if (value == MAX_NODES) {
+return;
+}
+
+*node = g_malloc0(sizeof(**node));
+(*node)->value = value;
+node = &(*node)->next;
+
+do {
+value = find_next_bit(backend->host_nodes, MAX_NODES, value + 1);
+if (value == MAX_NODES) {
+break;
+}
+
+*node = g_malloc0(sizeof(**node));
+(*node)->value = value;
+node = &(*node)->next;
+} while (true);
+
+visit_type_uint16List(v, &host_nodes, name, errp);
+}
+
+static void
+set_host_nodes(Object *obj, Visitor *v, void *opaque, const char *name,
+   Error **errp)
+{
+#ifdef CONFIG_NUMA
+HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+uint16List *l = NULL;
+
+visit_type_uint16List(v, &l, name, errp);
+
+while (l) {
+bitmap_set(backend->host_nodes, l->value, 1);
+l = l->next;
+}
+#else
+error_setg(errp, "NUMA node binding are not supported by this QEMU");
+#endif
+}
+
+static void
+get_policy(Object *obj, Visitor *v, void *opaque, const char *name,
+   Error **errp)
+{
+HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+int policy = backend->policy;
+
+visit_type_enum(v, &policy, HostMemPolicy_lookup, NULL, name, errp);
+}
+
+static void
+set_policy(Object *obj, Visitor *v, void *opaque, const char *name,
+   Error **errp)
+{
+HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+int policy;
+
+visit_type_enum(v, &policy, HostMemPolicy_lookup, NULL, name, errp);
+backend->policy = policy;
+
+#ifndef CONFIG_NUMA
+if (policy != HOST_MEM_POLICY_DEFAULT) {
+error_setg(errp, "NUMA policies are not supported by this QEMU");
+}
+#endif
+}
+
 static bool host_memory_backend_get_merge(Object *obj, Error **errp)
 {
 HostMemoryBackend *backend = MEMORY_BACKEND(obj);
@@ -159,6 +246,12 @@ static void host_memory_backend_initfn(Object *obj)
 object_property_add(obj, "size", "int",
 host_memory_backend_get_size,
 host_memory_backend_set_size, NULL, NULL, NULL);
+object_property_add(obj, "host-nodes", "int",
+get_host_nodes,
+set_host_nodes, NULL, NULL, NULL);
+object_property_add(obj, "policy", "str",
+get_policy,
+set_policy, NULL, NULL, NULL);
 }
 
 static void host_memory_backend_finalize(Object *obj)
@@ -203,6 +296,20 @@ host_memory_backend_memory_init(UserCreatable *uc, Error 
**errp)
 if (backend->prealloc) {
 os_mem_prealloc(memory_region_get_fd(&backend->mr), ptr, sz);
 }
+
+#ifdef CONFIG_NUMA
+unsigned long maxnode = find_last_bit(backend->host_nodes, MAX_NODES);
+
+/* This is a workaround for a long standing bug in Linux'
+ * mbind implementation, which cuts off the last specified
+ * node.
+ */
+if (mbind(ptr, sz, backend->policy, backend->host_nodes, maxnode + 2, 0)) {
+error_setg_errno(errp, errno,
+ "cannot bind memory to host NUMA nodes");
+return;
+}
+#endif
 }
 
 MemoryRegion *
diff --git a/include/sysemu/hostmem.h b/include/sysemu/hostmem.h
index 819b72d..4e96298 100644
--- a/include/sysemu/hostmem.h
+++ b/include/sysemu/hostmem.h
@@ -12,8 +12,10 @@
 #ifndef QEMU_HOSTMEM_

Re: [Qemu-devel] [PULL 28/31] curl: Remove unnecessary explicit calls to internal event handler

2014-05-06 Thread Laurent Desnogues
Hello,

sorry for another late detection of the use of too recent features.

On Wed, Apr 30, 2014 at 8:24 PM, Kevin Wolf  wrote:
> From: Matthew Booth 
>
> Remove calls to curl_multi_do where the relevant handles are already
> registered to the event loop.
>
> Ensure that we kick off socket handling with CURL_SOCKET_TIMEOUT after
> adding a new handle.
>
> Signed-off-by: Matthew Booth 
> Tested-by: Richard W.M. Jones 
> Signed-off-by: Kevin Wolf 
> ---
>  block/curl.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/block/curl.c b/block/curl.c
> index 50bd05f..fd2756e 100644
> --- a/block/curl.c
> +++ b/block/curl.c
> @@ -535,7 +535,6 @@ static int curl_open(BlockDriverState *bs, QDict 
> *options, int flags,
>  curl_multi_setopt(s->multi, CURLMOPT_TIMERDATA, s);
>  curl_multi_setopt(s->multi, CURLMOPT_TIMERFUNCTION, curl_timer_cb);
>  #endif
> -curl_multi_do(s);
>
>  qemu_opts_del(opts);
>  return 0;
> @@ -564,6 +563,7 @@ static const AIOCBInfo curl_aiocb_info = {
>  static void curl_readv_bh_cb(void *p)
>  {
>  CURLState *state;
> +int running;
>
>  CURLAIOCB *acb = p;
>  BDRVCURLState *s = acb->common.bs->opaque;
> @@ -612,8 +612,9 @@ static void curl_readv_bh_cb(void *p)
>  curl_easy_setopt(state->curl, CURLOPT_RANGE, state->range);
>
>  curl_multi_add_handle(s->multi, state->curl);
> -curl_multi_do(s);
>
> +/* Tell curl it needs to kick things off */
> +curl_multi_socket_action(s->multi, CURL_SOCKET_TIMEOUT, 0, &running);

curl_multi_socket_action isn't available on the CURL lib used
by CentOS 5.6.  The obvious workaround is to disable CURL
when calling configure.

Thanks,

Laurent

>  }
>
>  static BlockDriverAIOCB *curl_aio_readv(BlockDriverState *bs,
> --
> 1.8.3.1
>
>



[Qemu-devel] [PATCH v3.1 16/31] memory: add error propagation to file-based RAM allocation

2014-05-06 Thread Hu Tao
From: Paolo Bonzini 

Right now, -mem-path will fall back to RAM-based allocation in some
cases.  This should never happen with "-object memory-file", prepare
the code by adding correct error propagation.

Signed-off-by: Paolo Bonzini 
Signed-off-by: Hu Tao 
---
 exec.c  | 36 
 include/exec/memory.h   |  5 -
 include/exec/ram_addr.h |  2 +-
 memory.c|  5 +++--
 numa.c  | 13 -
 5 files changed, 44 insertions(+), 17 deletions(-)

diff --git a/exec.c b/exec.c
index 379472d..1e51b2f 100644
--- a/exec.c
+++ b/exec.c
@@ -1021,7 +1021,8 @@ static void sigbus_handler(int signal)
 
 static void *file_ram_alloc(RAMBlock *block,
 ram_addr_t memory,
-const char *path)
+const char *path,
+Error **errp)
 {
 char *filename;
 char *sanitized_name;
@@ -1040,7 +1041,8 @@ static void *file_ram_alloc(RAMBlock *block,
 }
 
 if (kvm_enabled() && !kvm_has_sync_mmu()) {
-fprintf(stderr, "host lacks kvm mmu notifiers, -mem-path 
unsupported\n");
+error_setg(errp,
+   "host lacks kvm mmu notifiers, -mem-path unsupported\n");
 goto error;
 }
 
@@ -1057,7 +1059,8 @@ static void *file_ram_alloc(RAMBlock *block,
 
 fd = mkstemp(filename);
 if (fd < 0) {
-perror("unable to create backing store for hugepages");
+error_setg_errno(errp, errno,
+ "unable to create backing store for hugepages");
 g_free(filename);
 goto error;
 }
@@ -1072,12 +1075,14 @@ static void *file_ram_alloc(RAMBlock *block,
  * If anything goes wrong with it under other filesystems,
  * mmap will fail.
  */
-if (ftruncate(fd, memory))
+if (ftruncate(fd, memory)) {
 perror("ftruncate");
+}
 
 area = mmap(0, memory, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
 if (area == MAP_FAILED) {
-perror("file_ram_alloc: can't mmap RAM pages");
+error_setg_errno(errp, errno,
+ "unable to map backing store for hugepages");
 close(fd);
 goto error;
 }
@@ -1305,13 +1310,14 @@ static ram_addr_t ram_block_add(RAMBlock *new_block)
 
 #ifdef __linux__
 ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
-const char *mem_path)
+const char *mem_path,
+Error **errp)
 {
 RAMBlock *new_block;
 
 if (xen_enabled()) {
-fprintf(stderr, "-mem-path not supported with Xen\n");
-exit(1);
+error_setg(errp, "-mem-path not supported with Xen\n");
+return -1;
 }
 
 if (phys_mem_alloc != qemu_anon_ram_alloc) {
@@ -1320,16 +1326,22 @@ ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, 
MemoryRegion *mr,
  * phys_mem_alloc, but we haven't bothered to provide
  * a hook there.
  */
-fprintf(stderr,
-"-mem-path not supported with this accelerator\n");
-exit(1);
+error_setg(errp,
+   "-mem-path not supported with this accelerator\n");
+return -1;
 }
 
 size = TARGET_PAGE_ALIGN(size);
 new_block = g_malloc0(sizeof(*new_block));
 new_block->mr = mr;
 new_block->length = size;
-new_block->host = file_ram_alloc(new_block, size, mem_path);
+new_block->host = file_ram_alloc(new_block, size,
+ mem_path, errp);
+if (!new_block->host) {
+g_free(new_block);
+return -1;
+}
+
 return ram_block_add(new_block);
 }
 #endif
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 75d4635..4e606dd 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -31,6 +31,7 @@
 #include "qemu/queue.h"
 #include "qemu/int128.h"
 #include "qemu/notify.h"
+#include "qapi/error.h"
 
 #define MAX_PHYS_ADDR_SPACE_BITS 62
 #define MAX_PHYS_ADDR(((hwaddr)1 << MAX_PHYS_ADDR_SPACE_BITS) - 1)
@@ -321,12 +322,14 @@ void memory_region_init_ram(MemoryRegion *mr,
  * @name: the name of the region.
  * @size: size of the region.
  * @path: the path in which to allocate the RAM.
+ * @errp: pointer to Error*, to store an error if it happens.
  */
 void memory_region_init_ram_from_file(MemoryRegion *mr,
   struct Object *owner,
   const char *name,
   uint64_t size,
-  const char *path);
+  const char *path,
+  Error **errp);
 #endif
 
 /**
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index dedb258..f9518a6 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -23,7 +23,7 @@
 #include "hw/xen/xen.

[Qemu-devel] [PATCH v3.1 19/31] hostmem: add file-based HostMemoryBackend

2014-05-06 Thread Hu Tao
From: Paolo Bonzini 

Signed-off-by: Paolo Bonzini 
Signed-off-by: Hu Tao 
---
 backends/Makefile.objs  |   1 +
 backends/hostmem-file.c | 108 
 2 files changed, 109 insertions(+)
 create mode 100644 backends/hostmem-file.c

diff --git a/backends/Makefile.objs b/backends/Makefile.objs
index e6bdc11..509e4a3 100644
--- a/backends/Makefile.objs
+++ b/backends/Makefile.objs
@@ -8,3 +8,4 @@ $(obj)/baum.o: QEMU_CFLAGS += $(SDL_CFLAGS)
 common-obj-$(CONFIG_TPM) += tpm.o
 
 common-obj-y += hostmem.o hostmem-ram.o
+common-obj-$(CONFIG_LINUX) += hostmem-file.o
diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c
new file mode 100644
index 000..e22bcef
--- /dev/null
+++ b/backends/hostmem-file.c
@@ -0,0 +1,108 @@
+/*
+ * QEMU Host Memory Backend for hugetlbfs
+ *
+ * Copyright (C) 2013 Red Hat Inc
+ *
+ * Authors:
+ *   Paolo Bonzini 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#include "sysemu/hostmem.h"
+#include "qom/object_interfaces.h"
+
+/* hostmem-file.c */
+/**
+ * @TYPE_MEMORY_BACKEND_FILE:
+ * name of backend that uses mmap on a file descriptor
+ */
+#define TYPE_MEMORY_BACKEND_FILE "memory-file"
+
+#define MEMORY_BACKEND_FILE(obj) \
+OBJECT_CHECK(HostMemoryBackendFile, (obj), TYPE_MEMORY_BACKEND_FILE)
+
+typedef struct HostMemoryBackendFile HostMemoryBackendFile;
+
+struct HostMemoryBackendFile {
+HostMemoryBackend parent_obj;
+char *mem_path;
+};
+
+static void
+file_backend_memory_init(UserCreatable *uc, Error **errp)
+{
+HostMemoryBackend *backend = MEMORY_BACKEND(uc);
+HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(uc);
+
+if (!backend->size) {
+error_setg(errp, "can't create backend with size 0");
+return;
+}
+if (!fb->mem_path) {
+error_setg(errp, "mem-path property not set");
+return;
+}
+#ifndef CONFIG_LINUX
+error_setg(errp, "-mem-path not supported on this host");
+#else
+if (!memory_region_size(&backend->mr)) {
+memory_region_init_ram_from_file(&backend->mr, OBJECT(backend),
+ object_get_canonical_path(OBJECT(backend)),
+ backend->size,
+ fb->mem_path, errp);
+}
+#endif
+}
+
+static void
+file_backend_class_init(ObjectClass *oc, void *data)
+{
+UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
+
+ucc->complete = file_backend_memory_init;
+}
+
+static char *get_mem_path(Object *o, Error **errp)
+{
+HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
+
+return g_strdup(fb->mem_path);
+}
+
+static void set_mem_path(Object *o, const char *str, Error **errp)
+{
+HostMemoryBackend *backend = MEMORY_BACKEND(o);
+HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
+
+if (memory_region_size(&backend->mr)) {
+error_setg(errp, "cannot change property value");
+return;
+}
+if (fb->mem_path) {
+g_free(fb->mem_path);
+}
+fb->mem_path = g_strdup(str);
+}
+
+static void
+file_backend_instance_init(Object *o)
+{
+object_property_add_str(o, "mem-path", get_mem_path,
+set_mem_path, NULL);
+}
+
+static const TypeInfo file_backend_info = {
+.name = TYPE_MEMORY_BACKEND_FILE,
+.parent = TYPE_MEMORY_BACKEND,
+.class_init = file_backend_class_init,
+.instance_init = file_backend_instance_init,
+.instance_size = sizeof(HostMemoryBackendFile),
+};
+
+static void register_types(void)
+{
+type_register_static(&file_backend_info);
+}
+
+type_init(register_types);
-- 
1.8.5.2.229.g4448466




[Qemu-devel] [PATCH v3.1 24/31] configure: add Linux libnuma detection

2014-05-06 Thread Hu Tao
From: Wanlong Gao 

Add detection of libnuma (mostly contained in the numactl package)
to the configure script. Can be enabled or disabled on the command
line, default is use if available.

Signed-off-by: Andre Przywara 
Signed-off-by: Wanlong Gao 
Signed-off-by: Paolo Bonzini 
Signed-off-by: Hu Tao 
---
 configure | 33 +
 1 file changed, 33 insertions(+)

diff --git a/configure b/configure
index 870c939..c3df5e6 100755
--- a/configure
+++ b/configure
@@ -324,6 +324,7 @@ tpm="no"
 libssh2=""
 vhdx=""
 quorum="no"
+numa=""
 
 # parse CC options first
 for opt do
@@ -1087,6 +1088,10 @@ for opt do
   ;;
   --enable-quorum) quorum="yes"
   ;;
+  --disable-numa) numa="no"
+  ;;
+  --enable-numa) numa="yes"
+  ;;
   *)
   echo "ERROR: unknown option $opt"
   echo "Try '$0 --help' for more information"
@@ -1354,6 +1359,8 @@ Advanced options (experts only):
   --enable-vhdxenable support for the Microsoft VHDX image format
   --disable-quorum disable quorum block filter support
   --enable-quorum  enable quorum block filter support
+  --disable-numa   disable libnuma support
+  --enable-numaenable libnuma support
 
 NOTE: The object files are built at the place where configure is launched
 EOF
@@ -3113,6 +3120,27 @@ if compile_prog "" "" ; then
 fi
 
 ##
+# libnuma probe
+
+if test "$numa" != "no" ; then
+  numa=no
+  cat > $TMPC << EOF
+#include 
+int main(void) { return numa_available(); }
+EOF
+
+  if compile_prog "" "-lnuma" ; then
+numa=yes
+libs_softmmu="-lnuma $libs_softmmu"
+  else
+if test "$numa" = "yes" ; then
+  feature_not_found "linux NUMA (install numactl?)"
+fi
+numa=no
+  fi
+fi
+
+##
 # signalfd probe
 signalfd="no"
 cat > $TMPC << EOF
@@ -4186,6 +4214,7 @@ echo "vhdx  $vhdx"
 echo "Quorum$quorum"
 echo "lzo support   $lzo"
 echo "snappy support$snappy"
+echo "NUMA host support $numa"
 
 if test "$sdl_too_old" = "yes"; then
 echo "-> Your SDL version is too old - please upgrade to have SDL support"
@@ -5153,6 +5182,10 @@ if [ "$dtc_internal" = "yes" ]; then
   echo "config-host.h: subdir-dtc" >> $config_host_mak
 fi
 
+if test "$numa" = "yes"; then
+  echo "CONFIG_NUMA=y" >> $config_host_mak
+fi
+
 # build tree in object directory in case the source is not in the current 
directory
 DIRS="tests tests/tcg tests/tcg/cris tests/tcg/lm32 tests/libqos 
tests/qapi-schema tests/tcg/xtensa tests/qemu-iotests"
 DIRS="$DIRS fsdev"
-- 
1.8.5.2.229.g4448466




[Qemu-devel] [PATCH v3.1 27/31] qapi: make string input visitor parse int list

2014-05-06 Thread Hu Tao
Signed-off-by: Hu Tao 
---
 qapi/string-input-visitor.c   | 181 --
 tests/test-string-input-visitor.c |  39 
 2 files changed, 212 insertions(+), 8 deletions(-)

diff --git a/qapi/string-input-visitor.c b/qapi/string-input-visitor.c
index 793548a..0f6add7 100644
--- a/qapi/string-input-visitor.c
+++ b/qapi/string-input-visitor.c
@@ -15,31 +15,182 @@
 #include "qapi/visitor-impl.h"
 #include "qapi/qmp/qerror.h"
 #include "qemu/option.h"
+#include "qemu/queue.h"
+#include "qemu/range.h"
+
 
 struct StringInputVisitor
 {
 Visitor visitor;
+
+bool head;
+
+SignedRangeList *ranges;
+SignedRange *cur_range;
+int64_t cur;
+
 const char *string;
 };
 
+static void parse_str(StringInputVisitor *siv, Error **errp)
+{
+char *str = (char *) siv->string;
+long long start, end;
+SignedRange *r, *next;
+char *endptr;
+
+if (siv->ranges) {
+return;
+}
+
+siv->ranges = g_malloc0(sizeof(*siv->ranges));
+QTAILQ_INIT(siv->ranges);
+errno = 0;
+do {
+start = strtoll(str, &endptr, 0);
+if (errno == 0 && endptr > str && INT64_MIN <= start &&
+start <= INT64_MAX) {
+if (*endptr == '\0') {
+if (!range_list_add(siv->ranges, start, 1)) {
+goto error;
+}
+str = NULL;
+} else if (*endptr == '-') {
+str = endptr + 1;
+end = strtoll(str, &endptr, 0);
+if (errno == 0 && endptr > str &&
+INT64_MIN <= end && end <= INT64_MAX && start <= end &&
+(start > INT64_MAX - 65536 ||
+ end < start + 65536)) {
+if (*endptr == '\0') {
+if (!range_list_add(siv->ranges, start,
+end - start + 1)) {
+goto error;
+}
+str = NULL;
+} else if (*endptr == ',') {
+str = endptr + 1;
+if (!range_list_add(siv->ranges, start,
+end - start + 1)) {
+goto error;
+}
+} else {
+goto error;
+}
+} else {
+goto error;
+}
+} else if (*endptr == ',') {
+str = endptr + 1;
+if (!range_list_add(siv->ranges, start, 1)) {
+goto error;
+}
+} else {
+goto error;
+}
+} else {
+goto error;
+}
+} while (str);
+
+return;
+error:
+if (siv->ranges) {
+QTAILQ_FOREACH_SAFE(r, siv->ranges, entry, next) {
+QTAILQ_REMOVE(siv->ranges, r, entry);
+g_free(r);
+}
+g_free(siv->ranges);
+siv->ranges = NULL;
+}
+}
+
+static void
+start_list(Visitor *v, const char *name, Error **errp)
+{
+StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v);
+
+parse_str(siv, errp);
+
+if (siv->ranges) {
+siv->cur_range = QTAILQ_FIRST(siv->ranges);
+if (siv->cur_range) {
+siv->cur = siv->cur_range->start;
+}
+}
+}
+
+static GenericList *
+next_list(Visitor *v, GenericList **list, Error **errp)
+{
+StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v);
+GenericList **link;
+
+if (!siv->ranges || !siv->cur_range) {
+return NULL;
+}
+
+if (siv->cur < siv->cur_range->start ||
+siv->cur >= (siv->cur_range->start + siv->cur_range->length)) {
+siv->cur_range = QTAILQ_NEXT(siv->cur_range, entry);
+if (siv->cur_range) {
+siv->cur = siv->cur_range->start;
+} else {
+return NULL;
+}
+}
+
+if (siv->head) {
+link = list;
+siv->head = false;
+} else {
+link = &(*list)->next;
+}
+
+*link = g_malloc0(sizeof **link);
+return *link;
+}
+
+static void
+end_list(Visitor *v, Error **errp)
+{
+StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v);
+siv->head = true;
+}
+
 static void parse_type_int(Visitor *v, int64_t *obj, const char *name,
Error **errp)
 {
 StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v);
-char *endp = (char *) siv->string;
-long long val;
 
-errno = 0;
-if (siv->string) {
-val = strtoll(siv->string, &endp, 0);
-}
-if (!siv->string || errno || endp == siv->string || *endp) {
+if (!siv->string) {
 error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
   "integer");
 return;
 }
 
-*obj = val;
+parse_str(siv, errp);
+
+if (!siv->ranges) {
+  

[Qemu-devel] [PATCH v3.1 31/31] hmp: add info memdev

2014-05-06 Thread Hu Tao
This is the hmp counterpart of qmp query-memdev.

Signed-off-by: Hu Tao 
---
 hmp.c | 36 
 hmp.h |  1 +
 monitor.c |  7 +++
 3 files changed, 44 insertions(+)

diff --git a/hmp.c b/hmp.c
index ca869ba..bde0df9 100644
--- a/hmp.c
+++ b/hmp.c
@@ -22,6 +22,8 @@
 #include "qemu/sockets.h"
 #include "monitor/monitor.h"
 #include "qapi/opts-visitor.h"
+#include "qapi/string-output-visitor.h"
+#include "qapi-visit.h"
 #include "ui/console.h"
 #include "block/qapi.h"
 #include "qemu-io.h"
@@ -1666,3 +1668,37 @@ void hmp_object_del(Monitor *mon, const QDict *qdict)
 qmp_object_del(id, &err);
 hmp_handle_error(mon, &err);
 }
+
+void hmp_info_memdev(Monitor *mon, const QDict *qdict)
+{
+Error *err = NULL;
+MemdevList *memdev_list = qmp_query_memdev(&err);
+MemdevList *m = memdev_list;
+StringOutputVisitor *ov;
+int i = 0;
+
+
+while (m) {
+ov = string_output_visitor_new(false);
+visit_type_uint16List(string_output_get_visitor(ov),
+  &m->value->host_nodes, NULL, NULL);
+monitor_printf(mon, "memory device %d\n", i);
+monitor_printf(mon, "  size: %ld\n", m->value->size);
+monitor_printf(mon, "  merge: %s\n",
+   m->value->merge ? "true" : "false");
+monitor_printf(mon, "  dump: %s\n",
+   m->value->dump ? "true" : "false");
+monitor_printf(mon, "  prealloc: %s\n",
+   m->value->prealloc ? "true" : "false");
+monitor_printf(mon, "  policy: %s\n",
+   HostMemPolicy_lookup[m->value->policy]);
+monitor_printf(mon, "  host nodes: %s\n",
+   string_output_get_string(ov));
+
+string_output_visitor_cleanup(ov);
+m = m->next;
+i++;
+}
+
+monitor_printf(mon, "\n");
+}
diff --git a/hmp.h b/hmp.h
index 20ef454..bc13aae 100644
--- a/hmp.h
+++ b/hmp.h
@@ -97,5 +97,6 @@ void object_add_completion(ReadLineState *rs, int nb_args, 
const char *str);
 void object_del_completion(ReadLineState *rs, int nb_args, const char *str);
 void device_add_completion(ReadLineState *rs, int nb_args, const char *str);
 void device_del_completion(ReadLineState *rs, int nb_args, const char *str);
+void hmp_info_memdev(Monitor *mon, const QDict *qdict);
 
 #endif
diff --git a/monitor.c b/monitor.c
index db17a31..d9cc6b9 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2941,6 +2941,13 @@ static mon_cmd_t info_cmds[] = {
 .mhandler.cmd = hmp_info_tpm,
 },
 {
+.name   = "memdev",
+.args_type  = "",
+.params = "",
+.help   = "show the memory device",
+.mhandler.cmd = hmp_info_memdev,
+},
+{
 .name   = NULL,
 },
 };
-- 
1.8.5.2.229.g4448466




[Qemu-devel] [PATCH v3.1 30/31] qmp: add query-memdev

2014-05-06 Thread Hu Tao
Add qmp command query-memdev to query for information
of memory devices

Signed-off-by: Hu Tao 
---
 numa.c   | 72 
 qapi-schema.json | 34 ++
 qmp-commands.hx  | 32 +
 3 files changed, 138 insertions(+)

diff --git a/numa.c b/numa.c
index fa117f0..77b6ca1 100644
--- a/numa.c
+++ b/numa.c
@@ -32,9 +32,14 @@
 #include "qapi-visit.h"
 #include "qapi/opts-visitor.h"
 #include "qapi/dealloc-visitor.h"
+#include "qapi/qmp-output-visitor.h"
+#include "qapi/qmp-input-visitor.h"
+#include "qapi/string-output-visitor.h"
+#include "qapi/string-input-visitor.h"
 #include "qapi/qmp/qerror.h"
 #include "hw/boards.h"
 #include "sysemu/hostmem.h"
+#include "qmp-commands.h"
 
 QemuOptsList qemu_numa_opts = {
 .name = "numa",
@@ -281,3 +286,70 @@ void memory_region_allocate_system_memory(MemoryRegion 
*mr, Object *owner,
 addr += size;
 }
 }
+
+MemdevList *qmp_query_memdev(Error **errp)
+{
+MemdevList *list = NULL, *m;
+HostMemoryBackend *backend;
+Error *err = NULL;
+int i;
+
+for (i = 0; i < nb_numa_nodes; i++) {
+backend = numa_info[i].node_memdev;
+
+m = g_malloc0(sizeof(*m));
+m->value = g_malloc0(sizeof(*m->value));
+m->value->size = object_property_get_int(OBJECT(backend), "size",
+ &err);
+if (err) {
+goto error;
+}
+
+m->value->merge = object_property_get_bool(OBJECT(backend), "merge",
+   &err);
+if (err) {
+goto error;
+}
+
+m->value->dump = object_property_get_bool(OBJECT(backend), "dump",
+  &err);
+if (err) {
+goto error;
+}
+
+m->value->prealloc = object_property_get_bool(OBJECT(backend),
+  "prealloc", &err);
+if (err) {
+goto error;
+}
+
+m->value->policy = object_property_get_enum(OBJECT(backend),
+"policy",
+HostMemPolicy_lookup,
+&err);
+if (err) {
+goto error;
+}
+
+object_property_get_uint16List(OBJECT(backend), "host-nodes",
+   &m->value->host_nodes, &err);
+if (err) {
+goto error;
+}
+
+m->next = list;
+list = m;
+}
+
+return list;
+
+error:
+while (list) {
+m = list;
+list = list->next;
+g_free(m->value);
+g_free(m);
+}
+qerror_report_err(err);
+return NULL;
+}
diff --git a/qapi-schema.json b/qapi-schema.json
index bea3476..bd0d6c1 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -4752,3 +4752,37 @@
 ##
 { 'enum': 'HostMemPolicy',
   'data': [ 'default', 'preferred', 'bind', 'interleave' ] }
+
+##
+# @Memdev:
+#
+# Information of memory device
+#
+# @size: memory device size
+#
+# @host-nodes: host nodes for its memory policy
+#
+# @policy: memory policy of memory device
+#
+# Since: 2.1
+##
+
+{ 'type': 'Memdev',
+  'data': {
+'size':   'size',
+'merge':  'bool',
+'dump':   'bool',
+'prealloc':   'bool',
+'host-nodes': ['uint16'],
+'policy': 'HostMemPolicy' }}
+
+##
+# @query-memdev:
+#
+# Returns information for all memory devices.
+#
+# Returns: a list of @Memdev.
+#
+# Since: 2.1
+##
+{ 'command': 'query-memdev', 'returns': ['Memdev'] }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index ed3ab92..5a5b37f 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -3562,3 +3562,35 @@ Example:
} } ] }
 
 EQMP
+
+{
+.name   = "query-memdev",
+.args_type  = "",
+.mhandler.cmd_new = qmp_marshal_input_query_memdev,
+},
+
+SQMP
+query-memdev
+
+
+Show memory devices information.
+
+
+Example (1):
+
+-> { "execute": "query-memdev" }
+<- { "return": [
+   {
+ "size": 536870912,
+ "host-nodes": [0, 1],
+ "policy": "bind"
+   },
+   {
+ "size": 536870912,
+ "host-nodes": [2, 3],
+ "policy": "preferred"
+   }
+ ]
+   }
+
+EQMP
-- 
1.8.5.2.229.g4448466




[Qemu-devel] [PATCH v3.1 20/31] hostmem: separate allocation from UserCreatable complete method

2014-05-06 Thread Hu Tao
From: Paolo Bonzini 

This allows the superclass to set various policies on the memory
region that the subclass creates.

Signed-off-by: Paolo Bonzini 
Signed-off-by: Hu Tao 
---
 backends/hostmem-file.c  |  9 -
 backends/hostmem-ram.c   |  7 +++
 backends/hostmem.c   | 12 ++--
 include/sysemu/hostmem.h |  2 ++
 4 files changed, 19 insertions(+), 11 deletions(-)

diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c
index e22bcef..75a165a 100644
--- a/backends/hostmem-file.c
+++ b/backends/hostmem-file.c
@@ -30,10 +30,9 @@ struct HostMemoryBackendFile {
 };
 
 static void
-file_backend_memory_init(UserCreatable *uc, Error **errp)
+file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
 {
-HostMemoryBackend *backend = MEMORY_BACKEND(uc);
-HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(uc);
+HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(backend);
 
 if (!backend->size) {
 error_setg(errp, "can't create backend with size 0");
@@ -58,9 +57,9 @@ file_backend_memory_init(UserCreatable *uc, Error **errp)
 static void
 file_backend_class_init(ObjectClass *oc, void *data)
 {
-UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
+HostMemoryBackendClass *bc = MEMORY_BACKEND_CLASS(oc);
 
-ucc->complete = file_backend_memory_init;
+bc->alloc = file_backend_memory_alloc;
 }
 
 static char *get_mem_path(Object *o, Error **errp)
diff --git a/backends/hostmem-ram.c b/backends/hostmem-ram.c
index cbf7e5a..7cbc051 100644
--- a/backends/hostmem-ram.c
+++ b/backends/hostmem-ram.c
@@ -16,9 +16,8 @@
 
 
 static void
-ram_backend_memory_init(UserCreatable *uc, Error **errp)
+ram_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
 {
-HostMemoryBackend *backend = MEMORY_BACKEND(uc);
 char *path;
 
 if (!backend->size) {
@@ -35,9 +34,9 @@ ram_backend_memory_init(UserCreatable *uc, Error **errp)
 static void
 ram_backend_class_init(ObjectClass *oc, void *data)
 {
-UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
+HostMemoryBackendClass *bc = MEMORY_BACKEND_CLASS(oc);
 
-ucc->complete = ram_backend_memory_init;
+bc->alloc = ram_backend_memory_alloc;
 }
 
 static const TypeInfo ram_backend_info = {
diff --git a/backends/hostmem.c b/backends/hostmem.c
index 6f26605..5b2117d 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -68,8 +68,16 @@ static void host_memory_backend_finalize(Object *obj)
 static void
 host_memory_backend_memory_init(UserCreatable *uc, Error **errp)
 {
-error_setg(errp, "memory_init is not implemented for type [%s]",
-   object_get_typename(OBJECT(uc)));
+HostMemoryBackend *backend = MEMORY_BACKEND(uc);
+HostMemoryBackendClass *bc = MEMORY_BACKEND_GET_CLASS(uc);
+
+if (!bc->alloc) {
+error_setg(errp, "memory_alloc is not implemented for type [%s]",
+   object_get_typename(OBJECT(uc)));
+return;
+}
+
+bc->alloc(backend, errp);
 }
 
 MemoryRegion *
diff --git a/include/sysemu/hostmem.h b/include/sysemu/hostmem.h
index d396fd8..42c98bd 100644
--- a/include/sysemu/hostmem.h
+++ b/include/sysemu/hostmem.h
@@ -32,6 +32,8 @@ typedef struct HostMemoryBackendClass HostMemoryBackendClass;
  */
 struct HostMemoryBackendClass {
 ObjectClass parent_class;
+
+void (*alloc)(HostMemoryBackend *backend, Error **errp);
 };
 
 /**
-- 
1.8.5.2.229.g4448466




[Qemu-devel] [PATCH v3.1 22/31] hostmem: allow preallocation of any memory region

2014-05-06 Thread Hu Tao
From: Paolo Bonzini 

And allow preallocation of file-based memory even without -mem-prealloc.
Some care is necessary because -mem-prealloc does not allow disabling
preallocation for hostmem-file.

Signed-off-by: Paolo Bonzini 
Signed-off-by: Hu Tao 
---
 backends/hostmem-file.c  |  3 +++
 backends/hostmem.c   | 42 ++
 exec.c   |  7 +++
 include/exec/memory.h| 10 ++
 include/exec/ram_addr.h  |  1 +
 include/sysemu/hostmem.h |  1 +
 memory.c | 11 +++
 7 files changed, 75 insertions(+)

diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c
index 75a165a..67328b9 100644
--- a/backends/hostmem-file.c
+++ b/backends/hostmem-file.c
@@ -9,7 +9,9 @@
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
  */
+#include "qemu-common.h"
 #include "sysemu/hostmem.h"
+#include "sysemu/sysemu.h"
 #include "qom/object_interfaces.h"
 
 /* hostmem-file.c */
@@ -46,6 +48,7 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error 
**errp)
 error_setg(errp, "-mem-path not supported on this host");
 #else
 if (!memory_region_size(&backend->mr)) {
+backend->force_prealloc = mem_prealloc;
 memory_region_init_ram_from_file(&backend->mr, OBJECT(backend),
  object_get_canonical_path(OBJECT(backend)),
  backend->size,
diff --git a/backends/hostmem.c b/backends/hostmem.c
index 3e5ebfc..738bb31 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -101,6 +101,41 @@ static void host_memory_backend_set_dump(Object *obj, bool 
value, Error **errp)
 }
 }
 
+static bool host_memory_backend_get_prealloc(Object *obj, Error **errp)
+{
+HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+
+return backend->prealloc || backend->force_prealloc;
+}
+
+static void host_memory_backend_set_prealloc(Object *obj, bool value,
+ Error **errp)
+{
+HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+
+if (backend->force_prealloc) {
+if (value) {
+error_setg(errp,
+   "remove -mem-prealloc to use the prealloc property");
+return;
+}
+}
+
+if (!memory_region_size(&backend->mr)) {
+backend->prealloc = value;
+return;
+}
+
+if (value && !backend->prealloc) {
+int fd = memory_region_get_fd(&backend->mr);
+void *ptr = memory_region_get_ram_ptr(&backend->mr);
+uint64_t sz = memory_region_size(&backend->mr);
+
+os_mem_prealloc(fd, ptr, sz);
+backend->prealloc = true;
+}
+}
+
 
 static void host_memory_backend_initfn(Object *obj)
 {
@@ -110,6 +145,7 @@ static void host_memory_backend_initfn(Object *obj)
"mem-merge", true);
 backend->dump = qemu_opt_get_bool(qemu_get_machine_opts(),
   "dump-guest-core", true);
+backend->prealloc = mem_prealloc;
 
 object_property_add_bool(obj, "merge",
 host_memory_backend_get_merge,
@@ -117,6 +153,9 @@ static void host_memory_backend_initfn(Object *obj)
 object_property_add_bool(obj, "dump",
 host_memory_backend_get_dump,
 host_memory_backend_set_dump, NULL);
+object_property_add_bool(obj, "prealloc",
+host_memory_backend_get_prealloc,
+host_memory_backend_set_prealloc, NULL);
 object_property_add(obj, "size", "int",
 host_memory_backend_get_size,
 host_memory_backend_set_size, NULL, NULL, NULL);
@@ -161,6 +200,9 @@ host_memory_backend_memory_init(UserCreatable *uc, Error 
**errp)
 if (!backend->dump) {
 qemu_madvise(ptr, sz, QEMU_MADV_DONTDUMP);
 }
+if (backend->prealloc) {
+os_mem_prealloc(memory_region_get_fd(&backend->mr), ptr, sz);
+}
 }
 
 MemoryRegion *
diff --git a/exec.c b/exec.c
index 691d216..fab45b5 100644
--- a/exec.c
+++ b/exec.c
@@ -1433,6 +1433,13 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length)
 }
 #endif /* !_WIN32 */
 
+int qemu_get_ram_fd(ram_addr_t addr)
+{
+RAMBlock *block = qemu_get_ram_block(addr);
+
+return block->fd;
+}
+
 /* Return a host pointer to ram allocated with qemu_ram_alloc.
With the exception of the softmmu code in this file, this should
only be used for local memory (e.g. video ram) that the device owns,
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 4e606dd..846834e 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -534,6 +534,16 @@ bool memory_region_is_logging(MemoryRegion *mr);
 bool memory_region_is_rom(MemoryRegion *mr);
 
 /**
+ * memory_region_get_fd: Get a file descriptor backing a RAM memory region.
+ *
+ * Returns a file descriptor backing a file-based RAM

[Qemu-devel] [PATCH v3.1 29/31] qom: introduce object_property_get_enum and object_property_get_uint16List

2014-05-06 Thread Hu Tao
Signed-off-by: Hu Tao 
---
 include/qom/object.h | 28 
 qom/object.c | 35 +++
 2 files changed, 63 insertions(+)

diff --git a/include/qom/object.h b/include/qom/object.h
index a641dcd..b882ccc 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -917,6 +917,34 @@ int64_t object_property_get_int(Object *obj, const char 
*name,
 Error **errp);
 
 /**
+ * object_property_get_enum:
+ * @obj: the object
+ * @name: the name of the property
+ * @strings: strings corresponding to enums
+ * @errp: returns an error if this function fails
+ *
+ * Returns: the value of the property, converted to an integer, or
+ * undefined if an error occurs (including when the property value is not
+ * an enum).
+ */
+int object_property_get_enum(Object *obj, const char *name,
+ const char *strings[], Error **errp);
+
+/**
+ * object_property_get_uint16List:
+ * @obj: the object
+ * @name: the name of the property
+ * @list: the returned int list
+ * @errp: returns an error if this function fails
+ *
+ * Returns: the value of the property, converted to integers, or
+ * undefined if an error occurs (including when the property value is not
+ * an list of integers).
+ */
+void object_property_get_uint16List(Object *obj, const char *name,
+uint16List **list, Error **errp);
+
+/**
  * object_property_set:
  * @obj: the object
  * @v: the visitor that will be used to write the property value.  This should
diff --git a/qom/object.c b/qom/object.c
index e42b254..3876618 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -13,6 +13,7 @@
 #include "qom/object.h"
 #include "qemu-common.h"
 #include "qapi/visitor.h"
+#include "qapi-visit.h"
 #include "qapi/string-input-visitor.h"
 #include "qapi/string-output-visitor.h"
 #include "qapi/qmp/qerror.h"
@@ -938,6 +939,40 @@ int64_t object_property_get_int(Object *obj, const char 
*name,
 return retval;
 }
 
+int object_property_get_enum(Object *obj, const char *name,
+ const char *strings[], Error **errp)
+{
+StringOutputVisitor *sov;
+StringInputVisitor *siv;
+int ret;
+
+sov = string_output_visitor_new(false);
+object_property_get(obj, string_output_get_visitor(sov), name, errp);
+siv = string_input_visitor_new(string_output_get_string(sov));
+string_output_visitor_cleanup(sov);
+visit_type_enum(string_input_get_visitor(siv),
+&ret, strings, NULL, name, errp);
+string_input_visitor_cleanup(siv);
+
+return ret;
+}
+
+void object_property_get_uint16List(Object *obj, const char *name,
+uint16List **list, Error **errp)
+{
+StringOutputVisitor *ov;
+StringInputVisitor *iv;
+
+ov = string_output_visitor_new(false);
+object_property_get(obj, string_output_get_visitor(ov),
+name, errp);
+iv = string_input_visitor_new(string_output_get_string(ov));
+visit_type_uint16List(string_input_get_visitor(iv),
+  list, NULL, errp);
+string_output_visitor_cleanup(ov);
+string_input_visitor_cleanup(iv);
+}
+
 void object_property_parse(Object *obj, const char *string,
const char *name, Error **errp)
 {
-- 
1.8.5.2.229.g4448466




[Qemu-devel] [PATCH v3.1 26/31] Introduce signed range.

2014-05-06 Thread Hu Tao
Signed-off-by: Hu Tao 
---
 include/qemu/range.h | 124 +++
 1 file changed, 124 insertions(+)

diff --git a/include/qemu/range.h b/include/qemu/range.h
index aae9720..8879f8a 100644
--- a/include/qemu/range.h
+++ b/include/qemu/range.h
@@ -3,6 +3,7 @@
 
 #include 
 #include 
+#include "qemu/queue.h"
 
 /*
  * Operations on 64 bit address ranges.
@@ -60,4 +61,127 @@ static inline int ranges_overlap(uint64_t first1, uint64_t 
len1,
 return !(last2 < first1 || last1 < first2);
 }
 
+typedef struct SignedRangeList SignedRangeList;
+
+typedef struct SignedRange {
+int64_t start;
+int64_t length;
+
+QTAILQ_ENTRY(SignedRange) entry;
+} SignedRange;
+
+QTAILQ_HEAD(SignedRangeList, SignedRange);
+
+static inline int64_t s_range_end(int64_t start, int64_t length)
+{
+return start + length - 1;
+}
+
+/* negative length or overflow */
+static inline bool s_range_overflow(int64_t start, int64_t length)
+{
+return s_range_end(start, length) < start;
+}
+
+static inline SignedRange *s_range_new(int64_t start, int64_t length)
+{
+SignedRange *range = NULL;
+
+if (s_range_overflow(start, length)) {
+return NULL;
+}
+
+range = g_malloc0(sizeof(*range));
+range->start = start;
+range->length = length;
+
+return range;
+}
+
+static inline void s_range_free(SignedRange *range)
+{
+g_free(range);
+}
+
+static inline bool s_range_overlap(int64_t start1, int64_t length1,
+   int64_t start2, int64_t length2)
+{
+return !((start1 + length1) < start2 || (start2 + length2) < start1);
+}
+
+static inline int s_range_join(SignedRange *range,
+   int64_t start, int64_t length)
+{
+if (s_range_overflow(start, length)) {
+return -1;
+}
+
+if (s_range_overlap(range->start, range->length, start, length)) {
+int64_t end = s_range_end(range->start, range->length);
+if (end < s_range_end(start, length)) {
+end = s_range_end(start, length);
+}
+if (range->start > start) {
+range->start = start;
+}
+range->length = end - range->start + 1;
+return 0;
+}
+
+return -1;
+}
+
+static inline int s_range_compare(int64_t start1, int64_t length1,
+  int64_t start2, int64_t length2)
+{
+if (start1 == start2 && length1 == length2) {
+return 0;
+} else if (s_range_end(start1, length1) <
+   s_range_end(start2, length2)) {
+return -1;
+} else {
+return 1;
+}
+}
+
+/* Add range to list. Keep them sorted, and merge ranges whenever possible */
+static inline bool range_list_add(SignedRangeList *list,
+  int64_t start, int64_t length)
+{
+SignedRange *r, *next, *new_range = NULL, *cur = NULL;
+
+if (s_range_overflow(start, length)) {
+return false;
+}
+
+QTAILQ_FOREACH_SAFE(r, list, entry, next) {
+if (s_range_overlap(r->start, r->length, start, length)) {
+s_range_join(r, start, length);
+break;
+} else if (s_range_compare(start, length, r->start, r->length) < 0) {
+cur = r;
+break;
+}
+}
+
+if (!r) {
+new_range = s_range_new(start, length);
+QTAILQ_INSERT_TAIL(list, new_range, entry);
+} else if (cur) {
+new_range = s_range_new(start, length);
+QTAILQ_INSERT_BEFORE(cur, new_range, entry);
+} else {
+SignedRange *next = QTAILQ_NEXT(r, entry);
+while (next && s_range_overlap(r->start, r->length,
+   next->start, next->length)) {
+s_range_join(r, next->start, next->length);
+QTAILQ_REMOVE(list, next, entry);
+s_range_free(next);
+next = QTAILQ_NEXT(r, entry);
+}
+}
+
+return true;
+}
+
 #endif
-- 
1.8.5.2.229.g4448466




[Qemu-devel] [PATCH v3.1 23/31] hostmem: add property to map memory with MAP_SHARED

2014-05-06 Thread Hu Tao
From: Paolo Bonzini 

A new "share" property can be used with the "memory-file" backend to
map memory with MAP_SHARED instead of MAP_PRIVATE.

Signed-off-by: Paolo Bonzini 
Signed-off-by: Hu Tao 
---
 backends/hostmem-file.c | 26 +-
 exec.c  | 18 ++
 include/exec/memory.h   |  2 ++
 include/exec/ram_addr.h |  3 ++-
 memory.c|  3 ++-
 numa.c  |  2 +-
 6 files changed, 42 insertions(+), 12 deletions(-)

diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c
index 67328b9..7f30011 100644
--- a/backends/hostmem-file.c
+++ b/backends/hostmem-file.c
@@ -28,6 +28,8 @@ typedef struct HostMemoryBackendFile HostMemoryBackendFile;
 
 struct HostMemoryBackendFile {
 HostMemoryBackend parent_obj;
+
+bool share;
 char *mem_path;
 };
 
@@ -51,7 +53,7 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error 
**errp)
 backend->force_prealloc = mem_prealloc;
 memory_region_init_ram_from_file(&backend->mr, OBJECT(backend),
  object_get_canonical_path(OBJECT(backend)),
- backend->size,
+ backend->size, fb->share,
  fb->mem_path, errp);
 }
 #endif
@@ -87,9 +89,31 @@ static void set_mem_path(Object *o, const char *str, Error 
**errp)
 fb->mem_path = g_strdup(str);
 }
 
+static bool file_memory_backend_get_share(Object *o, Error **errp)
+{
+HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
+
+return fb->share;
+}
+
+static void file_memory_backend_set_share(Object *o, bool value, Error **errp)
+{
+HostMemoryBackend *backend = MEMORY_BACKEND(o);
+HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
+
+if (memory_region_size(&backend->mr)) {
+error_setg(errp, "cannot change property value");
+return;
+}
+fb->share = value;
+}
+
 static void
 file_backend_instance_init(Object *o)
 {
+object_property_add_bool(o, "share",
+file_memory_backend_get_share,
+file_memory_backend_set_share, NULL);
 object_property_add_str(o, "mem-path", get_mem_path,
 set_mem_path, NULL);
 }
diff --git a/exec.c b/exec.c
index fab45b5..85fb85c 100644
--- a/exec.c
+++ b/exec.c
@@ -73,6 +73,9 @@ static MemoryRegion io_mem_unassigned;
 /* RAM is pre-allocated and passed into qemu_ram_alloc_from_ptr */
 #define RAM_PREALLOC   (1 << 0)
 
+/* RAM is mmap-ed with MAP_SHARED */
+#define RAM_SHARED (1 << 1)
+
 #endif
 
 struct CPUTailQ cpus = QTAILQ_HEAD_INITIALIZER(cpus);
@@ -1075,7 +1078,9 @@ static void *file_ram_alloc(RAMBlock *block,
 perror("ftruncate");
 }
 
-area = mmap(0, memory, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+area = mmap(0, memory, PROT_READ | PROT_WRITE,
+(block->flags & RAM_SHARED ? MAP_SHARED : MAP_PRIVATE),
+fd, 0);
 if (area == MAP_FAILED) {
 error_setg_errno(errp, errno,
  "unable to map backing store for hugepages");
@@ -1271,7 +1276,7 @@ static ram_addr_t ram_block_add(RAMBlock *new_block)
 
 #ifdef __linux__
 ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
-const char *mem_path,
+bool share, const char *mem_path,
 Error **errp)
 {
 RAMBlock *new_block;
@@ -1296,6 +1301,7 @@ ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, 
MemoryRegion *mr,
 new_block = g_malloc0(sizeof(*new_block));
 new_block->mr = mr;
 new_block->length = size;
+new_block->flags = share ? RAM_SHARED : 0;
 new_block->host = file_ram_alloc(new_block, size,
  mem_path, errp);
 if (!new_block->host) {
@@ -1398,12 +1404,8 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length)
 flags = MAP_FIXED;
 munmap(vaddr, length);
 if (block->fd >= 0) {
-#ifdef MAP_POPULATE
-flags |= mem_prealloc ? MAP_POPULATE | MAP_SHARED :
-MAP_PRIVATE;
-#else
-flags |= MAP_PRIVATE;
-#endif
+flags |= (block->flags & RAM_SHARED ?
+  MAP_SHARED : MAP_PRIVATE);
 area = mmap(vaddr, length, PROT_READ | PROT_WRITE,
 flags, block->fd, offset);
 } else {
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 846834e..21443bc 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -321,6 +321,7 @@ void memory_region_init_ram(MemoryRegion *mr,
  * @owner: the object that tracks the region's reference count
  * @name: the name of the region.
  * @size: size of the region.
+ * @share: %true if memory must be mmaped with the MAP_SHARED flag
  * @path: the path in which to allocate the R

Re: [Qemu-devel] [Crucial bug] Qemu-2.0.0 do not support virtio-net hot plug/unplug exceed two times

2014-05-06 Thread Markus Armbruster
"Gonglei (Arei)"  writes:

> Hi,
>
>> > > Il 26/04/2014 10:56, Gonglei (Arei) ha scritto:
>> > > > Public bug reported:
>> > > >
>> > > > I want to repeated hot-plug/unplug the virtio-net in the latest qemu
>> > > upstream
>> > > > (commit 839a5547574e57cce62f49bfc50fe1f04b00589a), but I am failed
>> at
>> > > the
>> > > > second time hot plug the virtio-net to guest.
>> > > >
>> > > > Then I tried to use Qemu-2.0.0 release version, but I got the error 
>> > > > too.
>> > > >
>> > > > Cmdline for vm:
>> > > >
>> > > > /mnt/sdb/gonglei/qemu/x86_64-softmmu/qemu-system-x86_64
>> -enable-kvm
>> > > -m 4096 -smp 4 -name sles-et -boot c -drive file=/mnt/sdb/gonglei/image/
>> > > sles-3.img -vnc 0.0.0.0:10 -monitor stdio
>> > > > QEMU 1.7.50 monitor - type 'help' for more information
>> > >
>> > > For commit 839a5547574e57cce62f49bfc50fe1f04b00589a you should have
>> > > gotten 1.7.90 as the version number.
>> > >
>> > Maybe just because Peter Maydell merge remote-tracking branch. But it
>> doesn't matter.
>> >
>> > > > (qemu) device_add virtio-net-pci,id=net1
>> > > > (qemu) device_del net1
>> > > > (qemu) device_add virtio-net-pci,id=net1
>> > > > Duplicate ID 'net1' for device
>> > > > (qemu)
>> > >
>> > > I cannot reproduce this on Fedora running the 2.0.0 package from the
>> > > virt-preview repository (qemu-system-x86-2.0.0-2.fc20.x86_64).
>> > >
>> > > For what it's worth, I get this for --version:
>> > >
>> > > $ qemu-system-x86_64 --version
>> > > QEMU emulator version 2.0.0, Copyright (c) 2003-2008 Fabrice Bellard
>> > >
>> > > and likewise, when starting QEMU with "-monitor stdio":
>> > >
>> > > QEMU 2.0.0 monitor - type 'help' for more information
>> > >
>> > I got the QEMU 2.0.0 version from http://wiki.qemu.org/Download
>> >
>> > The issue was reproduced perforce:
>> > UVP:/mnt/sdb/gonglei/code/qemu-2.0.0/x86_64-softmmu
>> #./qemu-system-x86_64 -enable-kvm -m 4096 -smp 4 -name sles \
>> >  -boot c -drive file=/mnt/sdb/gonglei/image/sles-3.img -vnc 0.0.0.0:10
>> -monitor stdio
>> > QEMU 2.0.0 monitor - type 'help' for more information
>> > (qemu) device_add virtio-net-pci,id=net1
>> > (qemu) device_del net1
>> > (qemu)  device_add virtio-net-pci,id=net1
>> > Duplicate ID 'net1' for device
>> > (qemu)
>> >
>> > Anything wrong? Thanks!
>> 
>> Issue confirmed with both -monitor and qmp-shell with different other device
>> models like e1000.
>
> Thanks. This issue confused me two weeks now, any helps will be appreciated.
>
> Cc'ing Peter and Michael for additional insights.

I suspect your second device_add fails because the unplug initiated by
device_del hasn't completed, yet.

More detailed explanation of the ACPI unplug dance:
https://lists.nongnu.org/archive/html/qemu-devel/2013-03/msg01362.html

Please verify the device is gone with "info pci", "info qtree" or
similar before you try device_del.

In QMP, you get a DEVICE_DELETED event when the unplug completes.  See
qmp/qmp-events.txt.



Re: [Qemu-devel] [PATCH v2 2/2] qapi: Allow setting default values for optional parameters

2014-05-06 Thread Markus Armbruster
Eric Blake  writes:

> On 05/05/2014 11:34 AM, Markus Armbruster wrote:
>>>
>>> Or, putting the question in reverse, you are asking if:
>>>
>>> data: { '*foo': 'str' }
>>>
>>> can blindly be rewritten into:
>>>
>>> data: { 'foo': { 'type': 'str', 'default': null } }
>>>
>>> and the rest of the introspection use the fact that 'default':null
>>> implies that the argument is optional but has no specified default, and
>>> therefore still needs the has_foo magic.
>>>
>>> As you say, it's a bit more of a stretch, but does make introspection
>>> nice (introspection already has to deal with leading '*' to turn it into
>>> something nicer to pass over the wire - if we ever get introspection
>>> working).  I'd have to see it actually coded up to decide for sure if it
>>> turned out to be a net win.
>> 
>> Glad you mention introspection; I didn't think of it.
>> 
>> The "an asterisk at the beginning of a name is not part of the name, but
>> means the parameter is optional" thing is a deviation from our usual
>> design rule against parsing strings in addition to JSON.  My proposal to
>> make the "is optional" property an ordinary JSON member straightens this
>> out.
>> 
>> The bit I'm not sure about is whether we want to keep the
>> NAME-PREFIXED-BY-ASKTERISK: TYPE form as syntactic sugar.
>
> Keeping it as sugar in the input .json files seems reasonable.
>
> Exposing it as sugar in introspection is a bad idea.
>
> Keeping the input file easy to write, and more compact than what
> introspection will output, is a fine tradeoff in my book (easier to
> maintain if there is less to type; while still having a well-defined
> conversion to the formal output form).

Unlike the other sugared form, this one adds syntax beyond JSON, namely
in some (but not all) member names, and that makes it a bit harder to
stomach for me.

Whether it's worthwhile depends on how common the case "optional, no
default" turns out to be.  Wait and see.

>> Keeping the TYPE: NAME form as sugar makes sense to me, because it cuts
>> noise in the schema while adding no syntax beyond JSON.
>
> Exactly - the point of syntactic sugar is to have a short form for
> common usage, while having the full form when full expressiveness is
> needed.  The .json schema files are internal use only; the introspection
> QMP command is not yet written but can adapt to the ideas in this thread.
>
>> 
>> The schema parser desugars its input.  Sugaring schema introspection
>> output makes no sense to me, because all that accomplishes is
>> introspection users have to duplicate the schema parser's desugaring.
>
> I think we're on the same page, then.

:)



[Qemu-devel] [PATCH v3.1 17/31] memory: move preallocation code out of exec.c

2014-05-06 Thread Hu Tao
From: Paolo Bonzini 

So that backends can use it.

Signed-off-by: Paolo Bonzini 
Signed-off-by: Hu Tao 
---
 exec.c   | 44 +--
 include/qemu/osdep.h |  2 ++
 util/oslib-posix.c   | 73 
 3 files changed, 76 insertions(+), 43 deletions(-)

diff --git a/exec.c b/exec.c
index 1e51b2f..710e025 100644
--- a/exec.c
+++ b/exec.c
@@ -1012,13 +1012,6 @@ static long gethugepagesize(const char *path)
 return fs.f_bsize;
 }
 
-static sigjmp_buf sigjump;
-
-static void sigbus_handler(int signal)
-{
-siglongjmp(sigjump, 1);
-}
-
 static void *file_ram_alloc(RAMBlock *block,
 ram_addr_t memory,
 const char *path,
@@ -1088,42 +1081,7 @@ static void *file_ram_alloc(RAMBlock *block,
 }
 
 if (mem_prealloc) {
-int ret, i;
-struct sigaction act, oldact;
-sigset_t set, oldset;
-
-memset(&act, 0, sizeof(act));
-act.sa_handler = &sigbus_handler;
-act.sa_flags = 0;
-
-ret = sigaction(SIGBUS, &act, &oldact);
-if (ret) {
-perror("file_ram_alloc: failed to install signal handler");
-exit(1);
-}
-
-/* unblock SIGBUS */
-sigemptyset(&set);
-sigaddset(&set, SIGBUS);
-pthread_sigmask(SIG_UNBLOCK, &set, &oldset);
-
-if (sigsetjmp(sigjump, 1)) {
-fprintf(stderr, "file_ram_alloc: failed to preallocate pages\n");
-exit(1);
-}
-
-/* MAP_POPULATE silently ignores failures */
-for (i = 0; i < (memory/hpagesize); i++) {
-memset(area + (hpagesize*i), 0, 1);
-}
-
-ret = sigaction(SIGBUS, &oldact, NULL);
-if (ret) {
-perror("file_ram_alloc: failed to reinstall signal handler");
-exit(1);
-}
-
-pthread_sigmask(SIG_SETMASK, &oldset, NULL);
+os_mem_prealloc(fd, area, memory);
 }
 
 block->fd = fd;
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index ffb2966..9c1a119 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -251,4 +251,6 @@ void qemu_init_auxval(char **envp);
 
 void qemu_set_tty_echo(int fd, bool echo);
 
+void os_mem_prealloc(int fd, char *area, size_t sz);
+
 #endif
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index 8e9c770..a22c97d 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -46,6 +46,7 @@ extern int daemon(int, int);
 #else
 #  define QEMU_VMALLOC_ALIGN getpagesize()
 #endif
+#define HUGETLBFS_MAGIC   0x958458f6
 
 #include 
 #include 
@@ -58,9 +59,12 @@ extern int daemon(int, int);
 #include "qemu/sockets.h"
 #include 
 #include 
+#include 
+#include 
 
 #ifdef CONFIG_LINUX
 #include 
+#include 
 #endif
 
 #ifdef __FreeBSD__
@@ -332,3 +336,72 @@ char *qemu_get_exec_dir(void)
 {
 return g_strdup(exec_dir);
 }
+
+static sigjmp_buf sigjump;
+
+static void sigbus_handler(int signal)
+{
+siglongjmp(sigjump, 1);
+}
+
+static size_t fd_getpagesize(int fd)
+{
+#ifdef CONFIG_LINUX
+struct statfs fs;
+int ret;
+
+if (fd != -1) {
+do {
+ret = fstatfs(fd, &fs);
+} while (ret != 0 && errno == EINTR);
+
+if (ret == 0 && fs.f_type == HUGETLBFS_MAGIC) {
+return fs.f_bsize;
+}
+}
+#endif
+
+return getpagesize();
+}
+
+void os_mem_prealloc(int fd, char *area, size_t memory)
+{
+int ret, i;
+struct sigaction act, oldact;
+sigset_t set, oldset;
+size_t hpagesize = fd_getpagesize(fd);
+
+memset(&act, 0, sizeof(act));
+act.sa_handler = &sigbus_handler;
+act.sa_flags = 0;
+
+ret = sigaction(SIGBUS, &act, &oldact);
+if (ret) {
+perror("file_ram_alloc: failed to install signal handler");
+exit(1);
+}
+
+/* unblock SIGBUS */
+sigemptyset(&set);
+sigaddset(&set, SIGBUS);
+pthread_sigmask(SIG_UNBLOCK, &set, &oldset);
+
+if (sigsetjmp(sigjump, 1)) {
+fprintf(stderr, "file_ram_alloc: failed to preallocate pages\n");
+exit(1);
+}
+
+/* MAP_POPULATE silently ignores failures */
+memory = (memory + hpagesize - 1) & -hpagesize;
+for (i = 0; i < (memory/hpagesize); i++) {
+memset(area + (hpagesize*i), 0, 1);
+}
+
+ret = sigaction(SIGBUS, &oldact, NULL);
+if (ret) {
+perror("file_ram_alloc: failed to reinstall signal handler");
+exit(1);
+}
+
+pthread_sigmask(SIG_SETMASK, &oldset, NULL);
+}
-- 
1.8.5.2.229.g4448466




Re: [Qemu-devel] [PULL 28/31] curl: Remove unnecessary explicit calls to internal event handler

2014-05-06 Thread Kevin Wolf
Am 06.05.2014 um 11:44 hat Laurent Desnogues geschrieben:
> Hello,
> 
> sorry for another late detection of the use of too recent features.
> 
> On Wed, Apr 30, 2014 at 8:24 PM, Kevin Wolf  wrote:
> > From: Matthew Booth 
> >
> > Remove calls to curl_multi_do where the relevant handles are already
> > registered to the event loop.
> >
> > Ensure that we kick off socket handling with CURL_SOCKET_TIMEOUT after
> > adding a new handle.
> >
> > Signed-off-by: Matthew Booth 
> > Tested-by: Richard W.M. Jones 
> > Signed-off-by: Kevin Wolf 
> > ---
> >  block/curl.c | 5 +++--
> >  1 file changed, 3 insertions(+), 2 deletions(-)
> >
> > diff --git a/block/curl.c b/block/curl.c
> > index 50bd05f..fd2756e 100644
> > --- a/block/curl.c
> > +++ b/block/curl.c
> > @@ -535,7 +535,6 @@ static int curl_open(BlockDriverState *bs, QDict 
> > *options, int flags,
> >  curl_multi_setopt(s->multi, CURLMOPT_TIMERDATA, s);
> >  curl_multi_setopt(s->multi, CURLMOPT_TIMERFUNCTION, curl_timer_cb);
> >  #endif
> > -curl_multi_do(s);
> >
> >  qemu_opts_del(opts);
> >  return 0;
> > @@ -564,6 +563,7 @@ static const AIOCBInfo curl_aiocb_info = {
> >  static void curl_readv_bh_cb(void *p)
> >  {
> >  CURLState *state;
> > +int running;
> >
> >  CURLAIOCB *acb = p;
> >  BDRVCURLState *s = acb->common.bs->opaque;
> > @@ -612,8 +612,9 @@ static void curl_readv_bh_cb(void *p)
> >  curl_easy_setopt(state->curl, CURLOPT_RANGE, state->range);
> >
> >  curl_multi_add_handle(s->multi, state->curl);
> > -curl_multi_do(s);
> >
> > +/* Tell curl it needs to kick things off */
> > +curl_multi_socket_action(s->multi, CURL_SOCKET_TIMEOUT, 0, &running);
> 
> curl_multi_socket_action isn't available on the CURL lib used
> by CentOS 5.6.  The obvious workaround is to disable CURL
> when calling configure.

Matthew, can you please check whether this call can be avoided, or
otherwise change configure to check the presence of the function?

Kevin



[Qemu-devel] Help needed testing on ppc

2014-05-06 Thread BALATON Zoltan

Hello,

As I got no reply on the qemu-ppc list so far I try here maybe there are 
some people who read this list but don't follow the ppc one.


I don't have the necessary hardware to do the testing needed for the patch 
below. Some context for the discussion can be found in this message: 
http://lists.nongnu.org/archive/html/qemu-ppc/2014-04/msg00277.html


It seems we have some code that contains instructions with a reserved bit set 
in an stwx instruction that works on real hardware but causes an invalid 
instruction exception on QEMU.


I'd appreciate some insight and help.

Regards,
BALATON Zoltan

On Thu, 17 Apr 2014, Programmingkid wrote:

On Apr 17, 2014, at 3:16 AM, qemu-ppc-requ...@nongnu.org wrote:

On Wed, 16 Apr 2014, Alexander Graf wrote:

On 16.04.14 12:24, BALATON Zoltan wrote:

On Tue, 15 Apr 2014, Alexander Graf wrote:

Try to do the same with the _E macro. Be creative :)


This one did it:

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index e3fcb03..d1e175e 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -10341,7 +10341,7 @@ GEN_HANDLER(stop##u, opc, 0xFF, 0xFF, 0x,
type),
#define GEN_STUX(name, stop, opc2, opc3, type)
\
GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x0001, type),
#define GEN_STX_E(name, stop, opc2, opc3, type, type2)
\
-GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x0001, type, type2),
+GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x, type, type2),
#define GEN_STS(name, stop, op, type)
\
GEN_ST(name, stop, op | 0x20, type)
\
GEN_STU(name, stop, op | 0x21, type)
\


Cool. Could you please write a small program similar to the one I sent you
that runs all of these instructions and checks that really none of them
trigger a program interrupt on real hardware? We can then remove the 
reserved

1 bit from the mask.


Would something like this work? (You should be able to change the
instruction to test at the 1: label.) I can't test it though without a PPC
machine.

#include 

int main(int argc, char **argv)
{
  register unsigned long r8 asm("r8");
  register unsigned long r9 asm("r9");
  register unsigned long r10 asm("r10");
  register unsigned long r11 asm("r11");
  register unsigned long r12 asm("r12");
  long val = 0;

  r8 = 0;
  r9 = (long)&val;
  r10 = 0;

  asm volatile("mfcr 8\n\t"
   "bl 1f \n\t"
   "mfcr 11   \n\t"
   "mflr 0\n\t"
   "lwz 8, 36(0)  \n\t"
   "ori 8, 8, 1   \n\t"
   "stw 8, 36(0)  \n\t"
   "mfcr 8\n\t"
   "bl 1f \n\t"
   "mfcr 12   \n\t"
   "b 2f  \n\t"
   "1: stwx 8, 9, 10  \n\t"
   "blr   \n\t"
   "2:\n\t"
: "=r"(r8), "=r"(r11), "=r"(r12)
: "r"(r8), "r"(r9), "r"(r10)
: "cc");

  printf("old cr  (mem):\t%#lx\n", val);
  printf("old cr  (reg):\t%#lx\n", r8);
  printf("new cr1 (reg):\t%#lx\n", r11);
  printf("new cr2 (reg):\t%#lx\n", r12);

  return 0;
}

Regards,
BALATON Zoltan


Just tried out your program on a Macintosh with a G3 processor. It doesn't 
compile under Mac OS X. Under Linux it crashes with a segmentation fault.





[Qemu-devel] [PATCH v3.1 05/31] NUMA: expand MAX_NODES from 64 to 128

2014-05-06 Thread Hu Tao
From: Wanlong Gao 

libnuma choosed 128 for MAX_NODES, so we follow libnuma here.

Signed-off-by: Wanlong Gao 
Reviewed-by: Eduardo Habkost 
Signed-off-by: Paolo Bonzini 
Signed-off-by: Hu Tao 
---
 include/sysemu/sysemu.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 4102be3..423d49e 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -133,7 +133,7 @@ extern size_t boot_splash_filedata_size;
 extern uint8_t qemu_extra_params_fw[2];
 extern QEMUClockType rtc_clock;
 
-#define MAX_NODES 64
+#define MAX_NODES 128
 
 /* The following shall be true for all CPUs:
  *   cpu->cpu_index < max_cpus <= MAX_CPUMASK_BITS
-- 
1.8.5.2.229.g4448466




Re: [Qemu-devel] [PATCH 34/35] pc: ACPI BIOS: make GPE.3 handle memory hotplug event on PIIX and Q35 machines

2014-05-06 Thread Laszlo Ersek
On 05/05/14 18:28, Paolo Bonzini wrote:
> Il 05/05/2014 18:25, Eric Blake ha scritto:
>>> > also make handler edge based to avoid loosing events, the same as
>> s/loosing/losing/
>>
>> (loose rhymes with goose and means the opposite of "tight"; lose rhymes
>> with use and means the opposite of "gain" - it is a very frequent typo
>> to see people put too many 'o's when they meant a variant of "lose")
> 
> Unfortunately rhymes are useless to non-native speakers. :)  A good way
> to remember it is to think of 'loosen' and 'lost' rather than 'loose'
> and 'lose', which are pronounced differently and hence easier to
> associate with the right number of 'o's.

Wiktionary is also helpful. The articles frequently come with phonetic
notation(s) and an audio sample. For example:

http://en.wiktionary.org/wiki/loose   enPR: loo͞s, IPA: /luːs/
http://en.wiktionary.org/wiki/loseenPR: lo͞oz, IPA: /luːz/
   ^   ^
   |   |

I'd say these are helpful; in this case even without audio samples
(although the articles in question have them too).

Other favorites of mine are "close" (as in, shut the door) vs. "close"
(as in, is your house near) -- the two etimologies incur different
pronounciations:

http://en.wiktionary.org/wiki/close#Pronunciation kloʊz
http://en.wiktionary.org/wiki/close#Pronunciation_2   kləʊs
  ^
  |
   (minimally these consonants are accessible to foreigners)

Laszlo



[Qemu-devel] [PATCH v3.1 04/31] NUMA: convert -numa option to use OptsVisitor

2014-05-06 Thread Hu Tao
From: Wanlong Gao 

Signed-off-by: Wanlong Gao 
Signed-off-by: Igor Mammedov 
Tested-by: Eduardo Habkost 
Reviewed-by: Eduardo Habkost 
Signed-off-by: Paolo Bonzini 
Signed-off-by: Hu Tao 
---
 include/sysemu/sysemu.h |   3 +-
 numa.c  | 145 +++-
 qapi-schema.json|  32 +++
 vl.c|  11 +++-
 4 files changed, 114 insertions(+), 77 deletions(-)

diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 3a9308b..4102be3 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -148,9 +148,10 @@ typedef struct node_info {
 DECLARE_BITMAP(node_cpu, MAX_CPUMASK_BITS);
 } NodeInfo;
 extern NodeInfo numa_info[MAX_NODES];
-void numa_add(const char *optarg);
 void set_numa_nodes(void);
 void set_numa_modes(void);
+extern QemuOptsList qemu_numa_opts;
+int numa_init_func(QemuOpts *opts, void *opaque);
 
 #define MAX_OPTION_ROMS 16
 typedef struct QEMUOptionRom {
diff --git a/numa.c b/numa.c
index 48d8bcc..439df87 100644
--- a/numa.c
+++ b/numa.c
@@ -29,101 +29,96 @@
 #include "qom/cpu.h"
 #include "qemu/error-report.h"
 #include "include/exec/cpu-common.h" /* for RAM_ADDR_FMT */
-
-static void numa_node_parse_cpus(int nodenr, const char *cpus)
+#include "qapi-visit.h"
+#include "qapi/opts-visitor.h"
+#include "qapi/dealloc-visitor.h"
+#include "qapi/qmp/qerror.h"
+
+QemuOptsList qemu_numa_opts = {
+.name = "numa",
+.implied_opt_name = "type",
+.head = QTAILQ_HEAD_INITIALIZER(qemu_numa_opts.head),
+.desc = { { 0 } } /* validated with OptsVisitor */
+};
+
+static void numa_node_parse(NumaNodeOptions *node, QemuOpts *opts, Error 
**errp)
 {
-char *endptr;
-unsigned long long value, endvalue;
+uint16_t nodenr;
+uint16List *cpus = NULL;
 
-/* Empty CPU range strings will be considered valid, they will simply
- * not set any bit in the CPU bitmap.
- */
-if (!*cpus) {
-return;
-}
-
-if (parse_uint(cpus, &value, &endptr, 10) < 0) {
-goto error;
-}
-if (*endptr == '-') {
-if (parse_uint_full(endptr + 1, &endvalue, 10) < 0) {
-goto error;
-}
-} else if (*endptr == '\0') {
-endvalue = value;
+if (node->has_nodeid) {
+nodenr = node->nodeid;
 } else {
-goto error;
+nodenr = nb_numa_nodes;
 }
 
-if (endvalue >= MAX_CPUMASK_BITS) {
-endvalue = MAX_CPUMASK_BITS - 1;
-fprintf(stderr,
-"qemu: NUMA: A max of %d VCPUs are supported\n",
- MAX_CPUMASK_BITS);
+if (nodenr >= MAX_NODES) {
+error_setg(errp, "Max number of NUMA nodes reached: %"
+   PRIu16 "\n", nodenr);
+return;
 }
 
-if (endvalue < value) {
-goto error;
+for (cpus = node->cpus; cpus; cpus = cpus->next) {
+if (cpus->value > MAX_CPUMASK_BITS) {
+error_setg(errp, "CPU number %" PRIu16 " is bigger than %d",
+   cpus->value, MAX_CPUMASK_BITS);
+return;
+}
+bitmap_set(numa_info[nodenr].node_cpu, cpus->value, 1);
 }
 
-bitmap_set(numa_info[nodenr].node_cpu, value, endvalue-value+1);
-return;
-
-error:
-fprintf(stderr, "qemu: Invalid NUMA CPU range: %s\n", cpus);
-exit(1);
+if (node->has_mem) {
+uint64_t mem_size = node->mem;
+const char *mem_str = qemu_opt_get(opts, "mem");
+/* Fix up legacy suffix-less format */
+if (g_ascii_isdigit(mem_str[strlen(mem_str) - 1])) {
+mem_size <<= 20;
+}
+numa_info[nodenr].node_mem = mem_size;
+}
 }
 
-void numa_add(const char *optarg)
+int numa_init_func(QemuOpts *opts, void *opaque)
 {
-char option[128];
-char *endptr;
-unsigned long long nodenr;
+NumaOptions *object = NULL;
+Error *err = NULL;
 
-optarg = get_opt_name(option, 128, optarg, ',');
-if (*optarg == ',') {
-optarg++;
+{
+OptsVisitor *ov = opts_visitor_new(opts);
+visit_type_NumaOptions(opts_get_visitor(ov), &object, NULL, &err);
+opts_visitor_cleanup(ov);
 }
-if (!strcmp(option, "node")) {
 
-if (nb_numa_nodes >= MAX_NODES) {
-fprintf(stderr, "qemu: too many NUMA nodes\n");
-exit(1);
-}
+if (err) {
+goto error;
+}
 
-if (get_param_value(option, 128, "nodeid", optarg) == 0) {
-nodenr = nb_numa_nodes;
-} else {
-if (parse_uint_full(option, &nodenr, 10) < 0) {
-fprintf(stderr, "qemu: Invalid NUMA nodeid: %s\n", option);
-exit(1);
-}
+switch (object->kind) {
+case NUMA_OPTIONS_KIND_NODE:
+numa_node_parse(object->node, opts, &err);
+if (err) {
+goto error;
 }
+nb_numa_nodes++;
+break;
+default:
+abort();
+}
 
-if (nodenr >= MAX_NODES) {
-fprintf(stderr, "qemu: invali

[Qemu-devel] [PATCH v3.1 21/31] hostmem: add merge and dump properties

2014-05-06 Thread Hu Tao
From: Paolo Bonzini 

Signed-off-by: Paolo Bonzini 
Signed-off-by: Hu Tao 
---
 backends/hostmem.c   | 85 +++-
 include/qemu/osdep.h | 10 ++
 include/sysemu/hostmem.h |  1 +
 3 files changed, 95 insertions(+), 1 deletion(-)

diff --git a/backends/hostmem.c b/backends/hostmem.c
index 5b2117d..3e5ebfc 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -49,8 +49,74 @@ host_memory_backend_set_size(Object *obj, Visitor *v, void 
*opaque,
 backend->size = value;
 }
 
+static bool host_memory_backend_get_merge(Object *obj, Error **errp)
+{
+HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+
+return backend->merge;
+}
+
+static void host_memory_backend_set_merge(Object *obj, bool value, Error 
**errp)
+{
+HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+
+if (!memory_region_size(&backend->mr)) {
+backend->merge = value;
+return;
+}
+
+if (value != backend->merge) {
+void *ptr = memory_region_get_ram_ptr(&backend->mr);
+uint64_t sz = memory_region_size(&backend->mr);
+
+qemu_madvise(ptr, sz,
+ value ? QEMU_MADV_MERGEABLE : QEMU_MADV_UNMERGEABLE);
+backend->merge = value;
+}
+}
+
+static bool host_memory_backend_get_dump(Object *obj, Error **errp)
+{
+HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+
+return backend->dump;
+}
+
+static void host_memory_backend_set_dump(Object *obj, bool value, Error **errp)
+{
+HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+
+if (!memory_region_size(&backend->mr)) {
+backend->dump = value;
+return;
+}
+
+if (value != backend->dump) {
+void *ptr = memory_region_get_ram_ptr(&backend->mr);
+uint64_t sz = memory_region_size(&backend->mr);
+
+qemu_madvise(ptr, sz,
+ value ? QEMU_MADV_DODUMP : QEMU_MADV_DONTDUMP);
+backend->dump = value;
+}
+}
+
+
 static void host_memory_backend_initfn(Object *obj)
 {
+HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+
+backend->merge = qemu_opt_get_bool(qemu_get_machine_opts(),
+   "mem-merge", true);
+backend->dump = qemu_opt_get_bool(qemu_get_machine_opts(),
+  "dump-guest-core", true);
+
+object_property_add_bool(obj, "merge",
+host_memory_backend_get_merge,
+host_memory_backend_set_merge, NULL);
+object_property_add_bool(obj, "dump",
+host_memory_backend_get_dump,
+host_memory_backend_set_dump, NULL);
 object_property_add(obj, "size", "int",
 host_memory_backend_get_size,
 host_memory_backend_set_size, NULL, NULL, NULL);
@@ -70,6 +136,9 @@ host_memory_backend_memory_init(UserCreatable *uc, Error 
**errp)
 {
 HostMemoryBackend *backend = MEMORY_BACKEND(uc);
 HostMemoryBackendClass *bc = MEMORY_BACKEND_GET_CLASS(uc);
+Error *local_err = NULL;
+void *ptr;
+uint64_t sz;
 
 if (!bc->alloc) {
 error_setg(errp, "memory_alloc is not implemented for type [%s]",
@@ -77,7 +146,21 @@ host_memory_backend_memory_init(UserCreatable *uc, Error 
**errp)
 return;
 }
 
-bc->alloc(backend, errp);
+bc->alloc(backend, &local_err);
+if (local_err) {
+error_propagate(errp, local_err);
+return;
+}
+
+ptr = memory_region_get_ram_ptr(&backend->mr);
+sz = memory_region_size(&backend->mr);
+
+if (backend->merge) {
+qemu_madvise(ptr, sz, QEMU_MADV_MERGEABLE);
+}
+if (!backend->dump) {
+qemu_madvise(ptr, sz, QEMU_MADV_DONTDUMP);
+}
 }
 
 MemoryRegion *
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 9c1a119..820c5d0 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -116,6 +116,16 @@ void qemu_anon_ram_free(void *ptr, size_t size);
 #else
 #define QEMU_MADV_MERGEABLE QEMU_MADV_INVALID
 #endif
+#ifdef MADV_UNMERGEABLE
+#define QEMU_MADV_UNMERGEABLE MADV_UNMERGEABLE
+#else
+#define QEMU_MADV_UNMERGEABLE QEMU_MADV_INVALID
+#endif
+#ifdef MADV_DODUMP
+#define QEMU_MADV_DODUMP MADV_DODUMP
+#else
+#define QEMU_MADV_DODUMP QEMU_MADV_INVALID
+#endif
 #ifdef MADV_DONTDUMP
 #define QEMU_MADV_DONTDUMP MADV_DONTDUMP
 #else
diff --git a/include/sysemu/hostmem.h b/include/sysemu/hostmem.h
index 42c98bd..a6b96eb 100644
--- a/include/sysemu/hostmem.h
+++ b/include/sysemu/hostmem.h
@@ -50,6 +50,7 @@ struct HostMemoryBackend {
 
 /* protected */
 uint64_t size;
+bool merge, dump;
 
 MemoryRegion mr;
 };
-- 
1.8.5.2.229.g4448466




[Qemu-devel] [PATCH] block: Fix open flags with BDRV_O_SNAPSHOT

2014-05-06 Thread Kevin Wolf
The immediately visible effect of this patch is that it fixes committing
a temporary snapshot to its backing file. Previously, it would fail with
a "permission denied" error because bdrv_inherited_flags() forced the
backing file to be read-only, ignoring the r/w reopen of bdrv_commit().

The bigger problem this releaved is that the original open flags must
actually only be applied to the temporary snapshot, and the original
image file must be treated as a backing file of the temporary snapshot
and get the right flags for that.

Reported-by: Jan Kiszka 
Signed-off-by: Kevin Wolf 
---
 block.c| 34 +++---
 include/block/block.h  |  2 +-
 tests/qemu-iotests/051 |  4 
 tests/qemu-iotests/051.out | 10 ++
 4 files changed, 34 insertions(+), 16 deletions(-)

diff --git a/block.c b/block.c
index b749d31..c90c71a 100644
--- a/block.c
+++ b/block.c
@@ -775,6 +775,16 @@ void bdrv_disable_copy_on_read(BlockDriverState *bs)
 }
 
 /*
+ * Returns the flags that a temporary snapshot should get, based on the
+ * originally requested flags (the originally requested image will have flags
+ * like a backing file)
+ */
+static int bdrv_temp_snapshot_flags(int flags)
+{
+return (flags & ~BDRV_O_SNAPSHOT) | BDRV_O_TEMPORARY;
+}
+
+/*
  * Returns the flags that bs->file should get, based on the given flags for
  * the parent BDS
  */
@@ -787,11 +797,6 @@ static int bdrv_inherited_flags(int flags)
  * so we can enable both unconditionally on lower layers. */
 flags |= BDRV_O_CACHE_WB | BDRV_O_UNMAP;
 
-/* The backing file of a temporary snapshot is read-only */
-if (flags & BDRV_O_SNAPSHOT) {
-flags &= ~BDRV_O_RDWR;
-}
-
 /* Clear flags that only apply to the top layer */
 flags &= ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING | BDRV_O_COPY_ON_READ);
 
@@ -817,11 +822,6 @@ static int bdrv_open_flags(BlockDriverState *bs, int flags)
 {
 int open_flags = flags | BDRV_O_CACHE_WB;
 
-/* The backing file of a temporary snapshot is read-only */
-if (flags & BDRV_O_SNAPSHOT) {
-open_flags &= ~BDRV_O_RDWR;
-}
-
 /*
  * Clear flags that are internal to the block layer before opening the
  * image.
@@ -1206,7 +1206,7 @@ done:
 return ret;
 }
 
-void bdrv_append_temp_snapshot(BlockDriverState *bs, Error **errp)
+void bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp)
 {
 /* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */
 char *tmp_filename = g_malloc0(PATH_MAX + 1);
@@ -1262,8 +1262,7 @@ void bdrv_append_temp_snapshot(BlockDriverState *bs, 
Error **errp)
 bs_snapshot = bdrv_new("", &error_abort);
 
 ret = bdrv_open(&bs_snapshot, NULL, NULL, snapshot_options,
-(bs->open_flags & ~BDRV_O_SNAPSHOT) | BDRV_O_TEMPORARY,
-bdrv_qcow2, &local_err);
+flags, bdrv_qcow2, &local_err);
 if (ret < 0) {
 error_propagate(errp, local_err);
 goto out;
@@ -1298,6 +1297,7 @@ int bdrv_open(BlockDriverState **pbs, const char 
*filename,
 BlockDriverState *file = NULL, *bs;
 const char *drvname;
 Error *local_err = NULL;
+int snapshot_flags = 0;
 
 assert(pbs);
 
@@ -1358,6 +1358,10 @@ int bdrv_open(BlockDriverState **pbs, const char 
*filename,
 if (flags & BDRV_O_RDWR) {
 flags |= BDRV_O_ALLOW_RDWR;
 }
+if (flags & BDRV_O_SNAPSHOT) {
+snapshot_flags = bdrv_temp_snapshot_flags(flags);
+flags = bdrv_backing_flags(flags);
+}
 
 assert(file == NULL);
 ret = bdrv_open_image(&file, filename, options, "file",
@@ -1417,8 +1421,8 @@ int bdrv_open(BlockDriverState **pbs, const char 
*filename,
 
 /* For snapshot=on, create a temporary qcow2 overlay. bs points to the
  * temporary snapshot afterwards. */
-if (flags & BDRV_O_SNAPSHOT) {
-bdrv_append_temp_snapshot(bs, &local_err);
+if (snapshot_flags) {
+bdrv_append_temp_snapshot(bs, snapshot_flags, &local_err);
 if (local_err) {
 error_propagate(errp, local_err);
 goto close_and_fail;
diff --git a/include/block/block.h b/include/block/block.h
index 467fb2b..2fda81c 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -191,7 +191,7 @@ int bdrv_open_image(BlockDriverState **pbs, const char 
*filename,
 QDict *options, const char *bdref_key, int flags,
 bool allow_none, Error **errp);
 int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp);
-void bdrv_append_temp_snapshot(BlockDriverState *bs, Error **errp);
+void bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp);
 int bdrv_open(BlockDriverState **pbs, const char *filename,
   const char *reference, QDict *options, int flags,
   BlockDriver *drv, Error **errp);
diff --git a/tests/qemu-iotests/051 b/tests/qemu-iotests/051
index 073dc7a..c4af131 100755
--- 

[Qemu-devel] [PATCH v3.1 01/31] NUMA: move numa related code to new file numa.c

2014-05-06 Thread Hu Tao
From: Wanlong Gao 

Signed-off-by: Wanlong Gao 
Reviewed-by: Eduardo Habkost 
Signed-off-by: Paolo Bonzini 
Signed-off-by: Hu Tao 
---
 Makefile.target   |   2 +-
 cpus.c|  14 
 include/exec/cpu-all.h|   2 -
 include/exec/cpu-common.h |   2 +
 include/sysemu/cpus.h |   1 -
 include/sysemu/sysemu.h   |   3 +
 numa.c| 186 ++
 vl.c  | 139 +-
 8 files changed, 193 insertions(+), 156 deletions(-)
 create mode 100644 numa.c

diff --git a/Makefile.target b/Makefile.target
index ba12340..234d9cd 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -109,7 +109,7 @@ endif #CONFIG_BSD_USER
 #
 # System emulator target
 ifdef CONFIG_SOFTMMU
-obj-y += arch_init.o cpus.o monitor.o gdbstub.o balloon.o ioport.o
+obj-y += arch_init.o cpus.o monitor.o gdbstub.o balloon.o ioport.o numa.o
 obj-y += qtest.o
 obj-y += hw/
 obj-$(CONFIG_FDT) += device_tree.o
diff --git a/cpus.c b/cpus.c
index 7bbe153..7f87adb 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1313,20 +1313,6 @@ static void tcg_exec_all(void)
 exit_request = 0;
 }
 
-void set_numa_modes(void)
-{
-CPUState *cpu;
-int i;
-
-CPU_FOREACH(cpu) {
-for (i = 0; i < nb_numa_nodes; i++) {
-if (test_bit(cpu->cpu_index, node_cpumask[i])) {
-cpu->numa_node = i;
-}
-}
-}
-}
-
 void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg)
 {
 /* XXX: implement xxx_cpu_list for targets that still miss it */
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index fb649a4..758a928 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -414,8 +414,6 @@ CPUArchState *cpu_copy(CPUArchState *env);
 
 /* memory API */
 
-extern ram_addr_t ram_size;
-
 /* RAM is pre-allocated and passed into qemu_ram_alloc_from_ptr */
 #define RAM_PREALLOC_MASK   (1 << 0)
 
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index a21b65a..e8c7970 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -45,6 +45,8 @@ typedef uintptr_t ram_addr_t;
 #  define RAM_ADDR_FMT "%" PRIxPTR
 #endif
 
+extern ram_addr_t ram_size;
+
 /* memory API */
 
 typedef void CPUWriteMemoryFunc(void *opaque, hwaddr addr, uint32_t value);
diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h
index 6502488..4f79081 100644
--- a/include/sysemu/cpus.h
+++ b/include/sysemu/cpus.h
@@ -23,7 +23,6 @@ extern int smp_threads;
 #define smp_threads 1
 #endif
 
-void set_numa_modes(void);
 void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg);
 
 #endif
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index ba5c7f8..565c8f6 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -144,6 +144,9 @@ extern QEMUClockType rtc_clock;
 extern int nb_numa_nodes;
 extern uint64_t node_mem[MAX_NODES];
 extern unsigned long *node_cpumask[MAX_NODES];
+void numa_add(const char *optarg);
+void set_numa_nodes(void);
+void set_numa_modes(void);
 
 #define MAX_OPTION_ROMS 16
 typedef struct QEMUOptionRom {
diff --git a/numa.c b/numa.c
new file mode 100644
index 000..395c14f
--- /dev/null
+++ b/numa.c
@@ -0,0 +1,186 @@
+/*
+ * QEMU System Emulator
+ *
+ * Copyright (c) 2013 Fujitsu Ltd.
+ * Author: Wanlong Gao 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "sysemu/sysemu.h"
+#include "exec/cpu-common.h"
+#include "qemu/bitmap.h"
+#include "qom/cpu.h"
+
+static void numa_node_parse_cpus(int nodenr, const char *cpus)
+{
+char *endptr;
+unsigned long long value, endvalue;
+
+/* Empty CPU range strings will be considered valid, they will simply
+ * not set any bit in the CPU bitmap.
+ */
+if (!*cpus) {
+return;
+}
+
+if (parse_uint(cpus, &value, &endptr, 10) < 0) {
+got

Re: [Qemu-devel] [PATCH] iotests: Use configured python

2014-05-06 Thread Stefan Hajnoczi
On Mon, May 05, 2014 at 06:25:38PM +0200, Max Reitz wrote:
> On 05.05.2014 14:26, Stefan Hajnoczi wrote:
> >On Sat, May 03, 2014 at 04:47:08PM +0200, Max Reitz wrote:
> >>@@ -56,22 +57,22 @@ for IMGOPTS in "compat=0.10" "compat=1.1"; do
> >>  echo === Create image with unknown header extension ===
> >>  echo
> >>  _make_test_img 64M
> >>-./qcow2.py "$TEST_IMG" add-header-ext 0x12345678 "This is a test 
> >>header extension"
> >>-./qcow2.py "$TEST_IMG" dump-header
> >>+$PYTHON qcow2.py "$TEST_IMG" add-header-ext 0x12345678 "This is a test 
> >>header extension"
> >>+$PYTHON qcow2.py "$TEST_IMG" dump-header
> >Please use "$PYTHON" to humor the people who like to put spaces in their
> >path names.
> 
> Following on Peter's explanation, me using ./configure
> --python=python2 results in PYTHON='python2 -B', which probably
> won't work so well with quotes around it.

You have a point, let's take the patch as-is.

> >>@@ -215,9 +222,16 @@ do
> >>  start=`_wallclock`
> >>  $timestamp && echo -n "["`date "+%T"`"]"
> >>-[ ! -x $seq ] && chmod u+x $seq # ensure we can run it
> >>+
> >>+if [ "$(head -n 1 $seq)" == "#!/usr/bin/env python" ]; then
> >>+run_command="$PYTHON $seq"
> >The code generally uses the older `` notation instead of $().  Please
> >use ``.
> 
> If I'd send a v2 with ``, Eric would probably want me to send a v3
> with $(). ;-)
> 
> I personally don't really care what to use, but so far nobody has
> picked on me for using $(), whereas Eric once criticized my use of
> `` (which I had taken over from other tests).

Personally I'm a $() man.  Just pointed it out for consistency but it
seems nobody really likes `` anyway :-).

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

Stefan



[Qemu-devel] [PATCH v3.1 13/31] numa: add -numa node, memdev= option

2014-05-06 Thread Hu Tao
From: Paolo Bonzini 

This option provides the infrastructure for binding guest NUMA nodes
to host NUMA nodes.  For example:

 -object memory-ram,size=1024M,policy=bind,host-nodes=0,id=ram-node0 \
 -numa node,nodeid=0,cpus=0,memdev=ram-node0 \
 -object memory-ram,size=1024M,policy=interleave,host-nodes=1-3,id=ram-node1 \
 -numa node,nodeid=1,cpus=1,memdev=ram-node1

The option replaces "-numa node,mem=".

Signed-off-by: Paolo Bonzini 
Signed-off-by: Hu Tao 
---
 include/sysemu/sysemu.h |  1 +
 numa.c  | 62 +++--
 qapi-schema.json| 11 ++---
 qemu-options.hx | 12 ++
 4 files changed, 77 insertions(+), 9 deletions(-)

diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index caf88dd..1e141e3 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -147,6 +147,7 @@ extern int nb_numa_nodes;
 typedef struct node_info {
 uint64_t node_mem;
 DECLARE_BITMAP(node_cpu, MAX_CPUMASK_BITS);
+struct HostMemoryBackend *node_memdev;
 } NodeInfo;
 extern NodeInfo numa_info[MAX_NODES];
 void set_numa_nodes(void);
diff --git a/numa.c b/numa.c
index bcd7b04..b9850d7 100644
--- a/numa.c
+++ b/numa.c
@@ -34,6 +34,7 @@
 #include "qapi/dealloc-visitor.h"
 #include "qapi/qmp/qerror.h"
 #include "hw/boards.h"
+#include "sysemu/hostmem.h"
 
 QemuOptsList qemu_numa_opts = {
 .name = "numa",
@@ -42,6 +43,8 @@ QemuOptsList qemu_numa_opts = {
 .desc = { { 0 } } /* validated with OptsVisitor */
 };
 
+static int have_memdevs = -1;
+
 static void numa_node_parse(NumaNodeOptions *node, QemuOpts *opts, Error 
**errp)
 {
 uint16_t nodenr;
@@ -68,6 +71,20 @@ static void numa_node_parse(NumaNodeOptions *node, QemuOpts 
*opts, Error **errp)
 bitmap_set(numa_info[nodenr].node_cpu, cpus->value, 1);
 }
 
+if (node->has_mem && node->has_memdev) {
+error_setg(errp, "qemu: cannot specify both mem= and memdev=\n");
+return;
+}
+
+if (have_memdevs == -1) {
+have_memdevs = node->has_memdev;
+}
+if (node->has_memdev != have_memdevs) {
+error_setg(errp, "qemu: memdev option must be specified for either "
+   "all or no nodes\n");
+return;
+}
+
 if (node->has_mem) {
 uint64_t mem_size = node->mem;
 const char *mem_str = qemu_opt_get(opts, "mem");
@@ -77,6 +94,18 @@ static void numa_node_parse(NumaNodeOptions *node, QemuOpts 
*opts, Error **errp)
 }
 numa_info[nodenr].node_mem = mem_size;
 }
+if (node->has_memdev) {
+Object *o;
+o = object_resolve_path_type(node->memdev, TYPE_MEMORY_BACKEND, NULL);
+if (!o) {
+error_setg(errp, "memdev=%s is ambiguous", node->memdev);
+return;
+}
+
+object_ref(o);
+numa_info[nodenr].node_mem = object_property_get_int(o, "size", NULL);
+numa_info[nodenr].node_memdev = MEMORY_BACKEND(o);
+}
 }
 
 int numa_init_func(QemuOpts *opts, void *opaque)
@@ -196,10 +225,39 @@ void set_numa_modes(void)
 }
 }
 
+static void allocate_system_memory_nonnuma(MemoryRegion *mr, Object *owner,
+   const char *name,
+   uint64_t ram_size)
+{
+memory_region_init_ram(mr, owner, name, ram_size);
+vmstate_register_ram_global(mr);
+}
+
 void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner,
   const char *name,
   uint64_t ram_size)
 {
-memory_region_init_ram(mr, owner, name, ram_size);
-vmstate_register_ram_global(mr);
+uint64_t addr = 0;
+int i;
+
+if (nb_numa_nodes == 0 || !have_memdevs) {
+allocate_system_memory_nonnuma(mr, owner, name, ram_size);
+return;
+}
+
+memory_region_init(mr, owner, name, ram_size);
+for (i = 0; i < nb_numa_nodes; i++) {
+Error *local_err = NULL;
+uint64_t size = numa_info[i].node_mem;
+HostMemoryBackend *backend = numa_info[i].node_memdev;
+MemoryRegion *seg = host_memory_backend_get_memory(backend, 
&local_err);
+if (local_err) {
+qerror_report_err(local_err);
+exit(1);
+}
+
+memory_region_add_subregion(mr, addr, seg);
+vmstate_register_ram_global(seg);
+addr += size;
+}
 }
diff --git a/qapi-schema.json b/qapi-schema.json
index 9394494..5dd30eb 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -4717,8 +4717,12 @@
 # @cpus: #optional VCPUs belonging to this node (assign VCPUS round-robin
 # if omitted)
 #
-# @mem: #optional memory size of this node (equally divide total memory among
-#nodes if omitted)
+# @mem: #optional memory size of this node; mutually exclusive with @memdev.
+#   Equally divide total memory among nodes if both @mem and @memdev are
+#   omitted.
+#
+# @memdev: #optional memory backend obje

Re: [Qemu-devel] [PULL v2 00/15] linux-user update

2014-05-06 Thread Peter Maydell
On 5 May 2014 20:00,   wrote:
> From: Riku Voipio 
>
> The following changes since commit fdaad4715ae9e998fd0595bedfb16fdaf0c68ccc:
>
>   Merge remote-tracking branch 
> 'remotes/pmaydell/tags/pull-target-arm-20140501' into staging (2014-05-02 
> 11:32:00 +0100)
>
> are available in the git repository at:
>
>   http://git.linaro.org/git/people/riku.voipio/qemu.git 
> linux-user-for-upstream

Applied, thanks.

PS: if you could consistently use the git:// url it would
save me a fractional amount of effort :-)

thanks
-- PMM



Re: [Qemu-devel] [PULL 7/8] gtk: Fix -serial vc

2014-05-06 Thread Jan Kiszka
On 2014-05-05 16:46, Gerd Hoffmann wrote:
> On Mo, 2014-05-05 at 13:55 +0200, Gerd Hoffmann wrote:
>>   Hi,
>>
>>> Looks better thanks to "gtk: zap scrolled_window" (monitor is properly
>>> formatted again). But the whole queue spits this out on the terminal:
>>>
>>> (:13169): Gtk-CRITICAL **: IA__gtk_window_resize: assertion `width 
>>> > 0' failed
>>>
>>> (:13169): Gdk-CRITICAL **: IA__gdk_window_set_cursor: assertion 
>>> `GDK_IS_WINDOW (window)' failed
>>
>> Yes, there is some work-in-progress stuff in that branch causing this.
> 
> Feel free to check out the branch again.  Warnings are fixed, resizing
> is fixed, and you can move tabs to windows (so you can see vga + monitor
> at the same time).

Still issues remaining. Scenario: Fired up a Linux guest up to graphical
mode, issued hard reset from monitor console, switched to guest display
-> window is larger than boot loader screen.

Jan




signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PATCH] Fix 'name' option to work with -readconfig

2014-05-06 Thread Dr. David Alan Gilbert (git)
From: "Dr. David Alan Gilbert" 

The 'name' option silently failed when used in config files
( http://lists.gnu.org/archive/html/qemu-devel/2014-04/msg00378.html )

Signed-off-by: Dr. David Alan Gilbert 
Reported-by: William Dauchy 
---
 vl.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/vl.c b/vl.c
index 8411a4a..47c199a 100644
--- a/vl.c
+++ b/vl.c
@@ -965,7 +965,7 @@ static int parse_sandbox(QemuOpts *opts, void *opaque)
 return 0;
 }
 
-static void parse_name(QemuOpts *opts)
+static int parse_name(QemuOpts *opts, void *opaque)
 {
 const char *proc_name;
 
@@ -978,6 +978,8 @@ static void parse_name(QemuOpts *opts)
 if (proc_name) {
 os_set_proc_name(proc_name);
 }
+
+return 0;
 }
 
 bool usb_enabled(bool default_usb)
@@ -3780,7 +3782,6 @@ int main(int argc, char **argv, char **envp)
 if (!opts) {
 exit(1);
 }
-parse_name(opts);
 break;
 case QEMU_OPTION_prom_env:
 if (nb_prom_envs >= MAX_PROM_ENVS) {
@@ -3955,6 +3956,10 @@ int main(int argc, char **argv, char **envp)
 exit(1);
 }
 
+if (qemu_opts_foreach(qemu_find_opts("name"), parse_name, NULL, 1)) {
+exit(1);
+}
+
 #ifndef _WIN32
 if (qemu_opts_foreach(qemu_find_opts("add-fd"), parse_add_fd, NULL, 1)) {
 exit(1);
-- 
1.9.0




Re: [Qemu-devel] [PATCH] block: Fix open flags with BDRV_O_SNAPSHOT

2014-05-06 Thread Jan Kiszka
On 2014-05-06 12:19, Kevin Wolf wrote:
> The immediately visible effect of this patch is that it fixes committing
> a temporary snapshot to its backing file. Previously, it would fail with
> a "permission denied" error because bdrv_inherited_flags() forced the
> backing file to be read-only, ignoring the r/w reopen of bdrv_commit().
> 
> The bigger problem this releaved is that the original open flags must
> actually only be applied to the temporary snapshot, and the original
> image file must be treated as a backing file of the temporary snapshot
> and get the right flags for that.
> 
> Reported-by: Jan Kiszka 
> Signed-off-by: Kevin Wolf 
> ---
>  block.c| 34 +++---
>  include/block/block.h  |  2 +-
>  tests/qemu-iotests/051 |  4 
>  tests/qemu-iotests/051.out | 10 ++
>  4 files changed, 34 insertions(+), 16 deletions(-)
> 
> diff --git a/block.c b/block.c
> index b749d31..c90c71a 100644
> --- a/block.c
> +++ b/block.c
> @@ -775,6 +775,16 @@ void bdrv_disable_copy_on_read(BlockDriverState *bs)
>  }
>  
>  /*
> + * Returns the flags that a temporary snapshot should get, based on the
> + * originally requested flags (the originally requested image will have flags
> + * like a backing file)
> + */
> +static int bdrv_temp_snapshot_flags(int flags)
> +{
> +return (flags & ~BDRV_O_SNAPSHOT) | BDRV_O_TEMPORARY;
> +}
> +
> +/*
>   * Returns the flags that bs->file should get, based on the given flags for
>   * the parent BDS
>   */
> @@ -787,11 +797,6 @@ static int bdrv_inherited_flags(int flags)
>   * so we can enable both unconditionally on lower layers. */
>  flags |= BDRV_O_CACHE_WB | BDRV_O_UNMAP;
>  
> -/* The backing file of a temporary snapshot is read-only */
> -if (flags & BDRV_O_SNAPSHOT) {
> -flags &= ~BDRV_O_RDWR;
> -}
> -
>  /* Clear flags that only apply to the top layer */
>  flags &= ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING | BDRV_O_COPY_ON_READ);
>  
> @@ -817,11 +822,6 @@ static int bdrv_open_flags(BlockDriverState *bs, int 
> flags)
>  {
>  int open_flags = flags | BDRV_O_CACHE_WB;
>  
> -/* The backing file of a temporary snapshot is read-only */
> -if (flags & BDRV_O_SNAPSHOT) {
> -open_flags &= ~BDRV_O_RDWR;
> -}
> -
>  /*
>   * Clear flags that are internal to the block layer before opening the
>   * image.
> @@ -1206,7 +1206,7 @@ done:
>  return ret;
>  }
>  
> -void bdrv_append_temp_snapshot(BlockDriverState *bs, Error **errp)
> +void bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp)
>  {
>  /* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */
>  char *tmp_filename = g_malloc0(PATH_MAX + 1);
> @@ -1262,8 +1262,7 @@ void bdrv_append_temp_snapshot(BlockDriverState *bs, 
> Error **errp)
>  bs_snapshot = bdrv_new("", &error_abort);
>  
>  ret = bdrv_open(&bs_snapshot, NULL, NULL, snapshot_options,
> -(bs->open_flags & ~BDRV_O_SNAPSHOT) | BDRV_O_TEMPORARY,
> -bdrv_qcow2, &local_err);
> +flags, bdrv_qcow2, &local_err);
>  if (ret < 0) {
>  error_propagate(errp, local_err);
>  goto out;
> @@ -1298,6 +1297,7 @@ int bdrv_open(BlockDriverState **pbs, const char 
> *filename,
>  BlockDriverState *file = NULL, *bs;
>  const char *drvname;
>  Error *local_err = NULL;
> +int snapshot_flags = 0;
>  
>  assert(pbs);
>  
> @@ -1358,6 +1358,10 @@ int bdrv_open(BlockDriverState **pbs, const char 
> *filename,
>  if (flags & BDRV_O_RDWR) {
>  flags |= BDRV_O_ALLOW_RDWR;
>  }
> +if (flags & BDRV_O_SNAPSHOT) {
> +snapshot_flags = bdrv_temp_snapshot_flags(flags);
> +flags = bdrv_backing_flags(flags);
> +}
>  
>  assert(file == NULL);
>  ret = bdrv_open_image(&file, filename, options, "file",
> @@ -1417,8 +1421,8 @@ int bdrv_open(BlockDriverState **pbs, const char 
> *filename,
>  
>  /* For snapshot=on, create a temporary qcow2 overlay. bs points to the
>   * temporary snapshot afterwards. */
> -if (flags & BDRV_O_SNAPSHOT) {
> -bdrv_append_temp_snapshot(bs, &local_err);
> +if (snapshot_flags) {
> +bdrv_append_temp_snapshot(bs, snapshot_flags, &local_err);
>  if (local_err) {
>  error_propagate(errp, local_err);
>  goto close_and_fail;
> diff --git a/include/block/block.h b/include/block/block.h
> index 467fb2b..2fda81c 100644
> --- a/include/block/block.h
> +++ b/include/block/block.h
> @@ -191,7 +191,7 @@ int bdrv_open_image(BlockDriverState **pbs, const char 
> *filename,
>  QDict *options, const char *bdref_key, int flags,
>  bool allow_none, Error **errp);
>  int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error 
> **errp);
> -void bdrv_append_temp_snapshot(BlockDriverState *bs, Error **errp);
> +void bdrv_append_temp_snapshot(BlockDriverState

Re: [Qemu-devel] [PULL] target-alpha update

2014-05-06 Thread Peter Maydell
On 3 May 2014 04:46, Richard Henderson  wrote:
> Ouch.  Silly typo that wasn't found in the sniff-test kernel boots
> I was using to test the branch.  One must boot all the way to init
> to see the breakage.
>
> Please pull.

Applied, thanks.

-- PMM



Re: [Qemu-devel] [PATCH] [v2 PATCH] qemu-img: sort block formats in help message

2014-05-06 Thread Stefan Hajnoczi
On Mon, May 05, 2014 at 12:53:34PM -0400, Mike Day wrote:
> The help message for qemu-img lists the supported block formats, of
> which there are 27 as of version 2.0.50. The formats are printed in
> the order of their driver's position in a linked list, which appears
> random. This patch prints the formats in sorted order, making it
> easier to read and to find a specific format in the list.
> 
> v2: Incorporated feedback from Stefan Hajnoczi
> 
> Signed-off-by: Mike Day 
> ---
>  qemu-img.c | 27 ---
>  1 file changed, 24 insertions(+), 3 deletions(-)

Thanks, applied to my block tree with Fam's suggestions squashed in:
https://github.com/stefanha/qemu/commits/block

Stefan



Re: [Qemu-devel] [PATCH] block/nfs: Check for NULL server part

2014-05-06 Thread Stefan Hajnoczi
On Mon, May 05, 2014 at 08:27:49PM +0200, Max Reitz wrote:
> After the URL has been parsed make sure the server part is valid in
> order to avoid a segmentation fault when calling nfs_mount().
> 
> Signed-off-by: Max Reitz 
> ---
>  block/nfs.c | 4 
>  1 file changed, 4 insertions(+)

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

Stefan



Re: [Qemu-devel] [PATCH v5 12/21] block: define get_block_status return value

2014-05-06 Thread Kevin Wolf
Am 05.05.2014 um 16:58 hat Paolo Bonzini geschrieben:
> Il 05/05/2014 16:34, Kevin Wolf ha scritto:
> > I think we're missing the information whether the BDRV_BLOCK_ZERO flag
> > actually comes from bs itself or from the backing chain. Do we need
> > another flag or does someone have a better idea?
> 
> Not sure if it is a better idea :) but we can duplicate the logic of
> bdrv_get_co_block_status in bdrv_is_allocated.
> 
> The observation here is that bdrv_has_zero_init should have been 
> changed to bdrv_unallocated_blocks_are_zero in commit c3d8688
> (block/get_block_status: fix BDRV_BLOCK_ZERO for unallocated blocks,
> 2013-10-24); the logic in the commit message applies just as well to
> bdrv_is_allocated.

But the result still wouldn't be right. We have an implication that you
can't simply reverse:

If this block is unallocated and unallocated blocks read as zero,
then this block reads as zero.

You're trying to use something like "If the block reads as zero and
unallocated blocks read as zero, it must be unallocated", which quite
obviously doesn't work.

Kevin



Re: [Qemu-devel] [PATCH] block/raw-posix: Fall back to SEEK_HOLE/SEEK_DATA

2014-05-06 Thread Stefan Hajnoczi
On Mon, May 05, 2014 at 10:01:39PM +0200, Max Reitz wrote:
> The current version of raw-posix always uses ioctl(FS_IOC_FIEMAP) if
> FIEMAP is available; lseek with SEEK_HOLE/SEEK_DATA are not even
> compiled in in this case. However, there may be implementations which
> support the latter but not the former (e.g., NFSv4.2). In this case,
> raw-posix should fall back to lseek with SEEK_HOLE/SEEK_DATA if FIEMAP
> does not work.
> 
> Signed-off-by: Max Reitz 
> ---
> As Linux does not yet implement NFSv4.2 (I don't even know whether the
> specification is complete), I have no way of testing whether this
> actually works for the proposed case. But as it doesn't break any of the
> existing test cases, it should be fine.
> ---
>  block/raw-posix.c | 27 +--
>  1 file changed, 21 insertions(+), 6 deletions(-)
> 
> diff --git a/block/raw-posix.c b/block/raw-posix.c
> index 3ce026d..e523633 100644
> --- a/block/raw-posix.c
> +++ b/block/raw-posix.c
> @@ -146,6 +146,9 @@ typedef struct BDRVRawState {
>  bool has_discard:1;
>  bool has_write_zeroes:1;
>  bool discard_zeroes:1;
> +#if defined CONFIG_FIEMAP && defined SEEK_HOLE && defined SEEK_DATA
> +bool use_seek_hole_data;
> +#endif
>  } BDRVRawState;
>  
>  typedef struct BDRVRawReopenState {
> @@ -1291,6 +1294,7 @@ static int64_t coroutine_fn 
> raw_co_get_block_status(BlockDriverState *bs,
>  int64_t sector_num,
>  int nb_sectors, int *pnum)
>  {
> +BDRVRawState *s = bs->opaque;
>  off_t start, data, hole;
>  int64_t ret;
>  
> @@ -1303,22 +1307,31 @@ static int64_t coroutine_fn 
> raw_co_get_block_status(BlockDriverState *bs,
>  ret = BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID | start;
>  
>  #ifdef CONFIG_FIEMAP
> -
> -BDRVRawState *s = bs->opaque;
>  struct {
>  struct fiemap fm;
>  struct fiemap_extent fe;
>  } f;
>  
> +#if defined SEEK_HOLE && defined SEEK_DATA
> +if (s->use_seek_hole_data) {
> +goto try_seek_hole_data;
> +}
> +#endif

This is becoming hard to read due to the ifdefs and their relationships.

A minor simplification is to change the bool field:
#if defined CONFIG_FIEMAP
bool use_fiemap;
#endif

...

#if defined CONFIG_FIEMAP
if (s->use_fiemap) {
...try fiemap...
}
#endif /* CONFIG_FIEMAP */

use_fiemap is not dependent on SEEK_HOLE/SEEK_DATA.  That reduces the
amount of ifdefs needed.

A bigger cleanup is extracting the FIEMAP and SEEK_HOLE/SEEK_DATA
implementations into their own static functions.  Then
raw_co_get_block_status() becomes simpler and doesn't need ifdefs:

ret = try_fiemap(...);
if (ret < 0) {
ret = try_seekhole(...);
}
if (ret < 0) {
...report every block allocated by default
}

In other words, let normal C control flow describe the relationships
between these code paths.  Use ifdef only to nop out try_fiemap() and
try_seekhole().

What do you think?

Stefan



Re: [Qemu-devel] [PATCH v3 7/7] hw/net/stellaris_enet: Convert to vmstate

2014-05-06 Thread Dr. David Alan Gilbert
* Peter Maydell (peter.mayd...@linaro.org) wrote:
> Convert this device to use vmstate for its save/load, including
> providing a post_load function that sanitizes inbound data to
> avoid possible buffer overflows if it is malicious.
> 
> The sanitizing fixes CVE-2013-4532 (though nobody should be
> relying on the security properties of most of the unmaintained
> ARM board models anyway, and migration doesn't actually
> work on this board due to issues in other device models).
> 
> Signed-off-by: Peter Maydell 
> ---
>  hw/net/stellaris_enet.c | 150 
> ++--
>  1 file changed, 82 insertions(+), 68 deletions(-)
> 
> diff --git a/hw/net/stellaris_enet.c b/hw/net/stellaris_enet.c
> index 9e8f143..0287ce1 100644
> --- a/hw/net/stellaris_enet.c
> +++ b/hw/net/stellaris_enet.c
> @@ -47,6 +47,11 @@ do { fprintf(stderr, "stellaris_enet: error: " fmt , ## 
> __VA_ARGS__);} while (0)
>  OBJECT_CHECK(stellaris_enet_state, (obj), TYPE_STELLARIS_ENET)
>  
>  typedef struct {
> +uint8_t data[2048];
> +uint32_t len;
> +} StellarisEnetRxFrame;
> +
> +typedef struct {
>  SysBusDevice parent_obj;
>  
>  uint32_t ris;
> @@ -59,22 +64,91 @@ typedef struct {
>  uint32_t mtxd;
>  uint32_t mrxd;
>  uint32_t np;
> -int tx_fifo_len;
> +uint32_t tx_fifo_len;
>  uint8_t tx_fifo[2048];
>  /* Real hardware has a 2k fifo, which works out to be at most 31 packets.
> We implement a full 31 packet fifo.  */
> -struct {
> -uint8_t data[2048];
> -int len;
> -} rx[31];
> -int rx_fifo_offset;
> -int next_packet;
> +StellarisEnetRxFrame rx[31];
> +uint32_t rx_fifo_offset;
> +uint32_t next_packet;
>  NICState *nic;
>  NICConf conf;
>  qemu_irq irq;
>  MemoryRegion mmio;
>  } stellaris_enet_state;
>  
> +static const VMStateDescription vmstate_rx_frame = {
> +.name = "stellaris_enet/rx_frame",
> +.version_id = 1,
> +.minimum_version_id = 1,
> +.minimum_version_id_old = 1,
> +.fields = (VMStateField[]) {
> +VMSTATE_UINT8_ARRAY(data, StellarisEnetRxFrame, 2048),
> +VMSTATE_UINT32(len, StellarisEnetRxFrame),
> +VMSTATE_END_OF_LIST()
> +}
> +};
> +
> +static int stellaris_enet_post_load(void *opaque, int version_id)
> +{
> +stellaris_enet_state *s = opaque;
> +int i;
> +
> +/* Sanitize inbound state. Note that next_packet is an index but
> + * np is a size; hence their valid upper bounds differ.
> + */
> +if (s->next_packet >= ARRAY_SIZE(s->rx)) {
> +return -1;
> +}
> +
> +if (s->np > ARRAY_SIZE(s->rx)) {
> +return -1;
> +}
> +
> +for (i = 0; i < ARRAY_SIZE(s->rx); i++) {
> +if (s->rx[i].len > ARRAY_SIZE(s->rx[i].data)) {
> +return -1;
> +}
> +}
> +
> +if (s->rx_fifo_offset > ARRAY_SIZE(s->rx[0].data) + 4) {
> +return -1;
> +}

Can you explain that +4 ?
I think I can see how it would end up equalling ARRAY_SIZE if
you've just read the last 4 bytes, but how does it go beyond?

> +
> +if (s->tx_fifo_len > ARRAY_SIZE(s->tx_fifo)) {
> +return -1;
> +}
> +
> +return 0;
> +}
> +
> +static const VMStateDescription vmstate_stellaris_enet = {
> +.name = "stellaris_enet",
> +.version_id = 2,
> +.minimum_version_id = 2,
> +.minimum_version_id_old = 2,

Weren't we killing off the minimum_version_id_old's ?


Dave

> +.post_load = stellaris_enet_post_load,
> +.fields = (VMStateField[]) {
> +VMSTATE_UINT32(ris, stellaris_enet_state),
> +VMSTATE_UINT32(im, stellaris_enet_state),
> +VMSTATE_UINT32(rctl, stellaris_enet_state),
> +VMSTATE_UINT32(tctl, stellaris_enet_state),
> +VMSTATE_UINT32(thr, stellaris_enet_state),
> +VMSTATE_UINT32(mctl, stellaris_enet_state),
> +VMSTATE_UINT32(mdv, stellaris_enet_state),
> +VMSTATE_UINT32(mtxd, stellaris_enet_state),
> +VMSTATE_UINT32(mrxd, stellaris_enet_state),
> +VMSTATE_UINT32(np, stellaris_enet_state),
> +VMSTATE_UINT32(tx_fifo_len, stellaris_enet_state),
> +VMSTATE_UINT8_ARRAY(tx_fifo, stellaris_enet_state, 2048),
> +VMSTATE_STRUCT_ARRAY(rx, stellaris_enet_state, 31, 1,
> + vmstate_rx_frame, StellarisEnetRxFrame),
> +VMSTATE_UINT32(rx_fifo_offset, stellaris_enet_state),
> +VMSTATE_UINT32(next_packet, stellaris_enet_state),
> +VMSTATE_END_OF_LIST()
> +}
> +};
> +
>  static void stellaris_enet_update(stellaris_enet_state *s)
>  {
>  qemu_set_irq(s->irq, (s->ris & s->im) != 0);
> @@ -379,63 +453,6 @@ static void stellaris_enet_reset(stellaris_enet_state *s)
>  s->tx_fifo_len = 0;
>  }
>  
> -static void stellaris_enet_save(QEMUFile *f, void *opaque)
> -{
> -stellaris_enet_state *s = (stellaris_enet_state *)opaque;
> -int i;
> -
> -qemu_put_be32(f, s->ris);
> -qemu_put_be32(f, s->im);
> -qemu_

Re: [Qemu-devel] [PATCH v2 2/2] qapi: Allow setting default values for optional parameters

2014-05-06 Thread Markus Armbruster
Eric Blake  writes:

> On 05/05/2014 07:30 PM, Fam Zheng wrote:
>
>>> NAME: { 'type': TYPE, 'default': DEFAULT }
>>>
>>> where
>>>
>>> NAME: { 'type': TYPE }
>>>
>>> can be abbreviated to
>>>
>>> NAME: TYPE
>
>> 
>> In data definition, we allow inline sub-structure:
>> 
>> { 'type': 'VersionInfo',
>>   'data': {'qemu': {'major': 'int', 'minor': 'int', 'micro': 'int'},
>>'package': 'str'} }
>> 
>> If we allow properties as a dict, we need to disambiguate properly from the
>> above case. Proposing:
>> 
>> MAGIC: { 'name': NAME, 'type: TYPE, 'default': DEFAULT }
>
> Oh, good catch.

Indeed.

>  The alternative is to drop all instances of inline
> sub-structs.  Searching for 'data.*{.*{', I found only VersionInfo and
> PciBridgeInfo; I then did a full manual search of qapi-schema.json and
> only found the additional instance of PciDeviceInfo where the sub-struct
> is not on the same line as the initial { of the 'data'.  Just getting
> rid of inlined sub-structs may be quite feasible.
>
> On a related vein, there are a number of types that aren't merely a
> string name.  For example:
>
> { 'command': 'migrate-set-capabilities',
>   'data': { 'capabilities': ['MigrationCapabilityStatus'] } }
>
> and similar, where we have an array type rather than a raw string type
> name.  But at least with that, NAME: { 'type': [ 'array' ] } is still a
> reasonable parse.
>
> The problem with MAGIC:{'name'...} is that you need to express more than
> one parameter, but as a dict, you can't reuse the same MAGIC more than
> once.  That is:
>
> 'data': { MAGIC : { 'name': 'qemu', 'type': { 'major'...} },
>   MAGIC : { 'name': 'package', 'type', 'str' } } }
>
> proves that you have to have two distinct MAGIC in the same 'data', so
> '' for both is out.
>
>> 
>> Where MAGIC should NOT be something that is a valid NAME from current schema.
>> Some ideas:
>> 
>>  - Special string, that has invalid chars as a identifier, like '*', '%', 
>> '&',
>>etc, or simply an empty str ''.
>>Of course we need to enforce the checking and distinguishing in
>>scripts/qapi-types.py.
>> 
>>  - Non-string: current NAME must be a string, any type non-string could be
>>distinguished from NAME, like number, bool, null, []. But its meaning 
>> could
>>be confusing to reviewer.

JSON requires member names to be strings.

>>  - Special symbol: we can define a dedicate symbol for this, like the literal
>>TYPE, in the schema. But this way we deviate more from JSON.
>
> Also, while we aren't strict JSON, it's nice that we're still fairly
> close to JSON5, and worth keeping that property.

Both ideas move us further away from JSON and JSON5.

JSON5 allows unquoted identifiers as member names, but that's just
shorthand for the same name in quotes.

>> Personally, I think empty str '' makes more sense for me. What do you think?
>> 
>
> At this point, I'm leaning towards dropping support for unnamed inlined
> sub-structs.

For what it's worth, qapi-code-gen.txt has only strings (i.e. type
names) in the value position of a member declaration, never an object
(i.e. anonymous complex type, what you called unnamed inlined
sub-struct).

Another idea (I'm not sure I like it, though): in the unsugared NAME:
OBJECT form, OBJECT has a mandatory member 'type'.  This can be used to
decide whether we have an unsugared member definition or sugared member
definition with an anonymous complex type.  Examples:

* This can't be an unsugared member definition, because it lacks 'type':

'qemu': {'major': 'int', 'minor': 'int', 'micro': 'int'}

* This could be either, but we prefer unsugared then:

'foo': { 'type': 'str' }

  If you want an anonymous complex type, you need to desugar, like this:

'foo': { 'type': { 'type': 'str' } }

Might want to outlaw member name 'type' to remove the ambiguity.

Yet another idea: drop anonymous complex types in the sugared form only.
Then an object in the value position always means unsugared.  We change
the existing members of anonymous complex type from NAME: OBJECT to
NAME: { 'type': OBJECT }.

>> Anyway we only add things, so we will keep the '*name' suger.

The schema is still just an internal interface; we can change it as much
as we want.  With schema introspection, the desugared form of the schema
visible there will be ABI.  Which means we better use our chance to make
our schema language a bit more extensible while it lasts.



Re: [Qemu-devel] [PATCH v2 2/2] qapi: Allow setting default values for optional parameters

2014-05-06 Thread Markus Armbruster
Fam Zheng  writes:

> On Mon, 05/05 21:09, Eric Blake wrote:
>> On 05/05/2014 07:30 PM, Fam Zheng wrote:
>> 
>> >> NAME: { 'type': TYPE, 'default': DEFAULT }
>> >>
>> >> where
>> >>
>> >> NAME: { 'type': TYPE }
>> >>
>> >> can be abbreviated to
>> >>
>> >> NAME: TYPE
>> 
>> > 
>> > In data definition, we allow inline sub-structure:
>> > 
>> > { 'type': 'VersionInfo',
>> >   'data': {'qemu': {'major': 'int', 'minor': 'int', 'micro': 'int'},
>> >'package': 'str'} }
>> > 
>> > If we allow properties as a dict, we need to disambiguate properly from the
>> > above case. Proposing:
>> > 
>> > MAGIC: { 'name': NAME, 'type: TYPE, 'default': DEFAULT }
>> 
>> Oh, good catch.  The alternative is to drop all instances of inline
>> sub-structs.  Searching for 'data.*{.*{', I found only VersionInfo and
>> PciBridgeInfo; I then did a full manual search of qapi-schema.json and
>> only found the additional instance of PciDeviceInfo where the sub-struct
>> is not on the same line as the initial { of the 'data'.  Just getting
>> rid of inlined sub-structs may be quite feasible.
>
> Sounds good.
>
>> 
>> On a related vein, there are a number of types that aren't merely a
>> string name.  For example:
>> 
>> { 'command': 'migrate-set-capabilities',
>>   'data': { 'capabilities': ['MigrationCapabilityStatus'] } }
>> 
>> and similar, where we have an array type rather than a raw string type
>> name.  But at least with that, NAME: { 'type': [ 'array' ] } is still a
>> reasonable parse.
>> 
>> The problem with MAGIC:{'name'...} is that you need to express more than
>> one parameter, but as a dict, you can't reuse the same MAGIC more than
>> once.  That is:
>> 
>> 'data': { MAGIC : { 'name': 'qemu', 'type': { 'major'...} },
>>   MAGIC : { 'name': 'package', 'type', 'str' } } }
>
> Right.
>
> Not necessarily better than dropping inline structure, just another idea:
>
>   'data' { '@arg_with_properties': { 'type': 'str' },
>'*simple_optional': 'str',
>'@optional_full': { 'type': 'int', 'default': 1 },
>'the_most_common_form': 'bool',
>'inline_structure': { 'major': ...} }
>
> Where '@' is a prefix for property dictionary similar to, while exclusive 
> with,
> optional mark '*'.

If we decide to keep the '*' sigil, we can add more.  Two similar
violations of the "no syntax beyond JSON" design rule aren't really
worse than one.

That said, I dislike all sigils equally :)

[...]



[Qemu-devel] [PATCH 03/22] gtk: cleanup CONFIG_VTE ifdef a bit.

2014-05-06 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann 
---
 ui/gtk.c | 45 ++---
 1 file changed, 26 insertions(+), 19 deletions(-)

diff --git a/ui/gtk.c b/ui/gtk.c
index 776e72d..068a39b 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -108,8 +108,8 @@ static const int modifier_keycode[] = {
 typedef struct VirtualConsole
 {
 GtkWidget *menu_item;
-GtkWidget *terminal;
 #if defined(CONFIG_VTE)
+GtkWidget *terminal;
 CharDriverState *chr;
 #endif
 } VirtualConsole;
@@ -1124,13 +1124,12 @@ static gboolean gd_focus_out_event(GtkWidget *widget,
 
 /** Virtual Console Callbacks **/
 
+#if defined(CONFIG_VTE)
 static int gd_vc_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
 {
-#if defined(CONFIG_VTE)
 VirtualConsole *vc = chr->opaque;
 
 vte_terminal_feed(VTE_TERMINAL(vc->terminal), (const char *)buf, len);
-#endif
 return len;
 }
 
@@ -1151,12 +1150,6 @@ static CharDriverState *gd_vc_handler(ChardevVC *unused)
 return chr;
 }
 
-void early_gtk_display_init(void)
-{
-register_vc_handler(gd_vc_handler);
-}
-
-#if defined(CONFIG_VTE)
 static gboolean gd_vc_in(VteTerminal *terminal, gchar *text, guint size,
  gpointer user_data)
 {
@@ -1165,12 +1158,10 @@ static gboolean gd_vc_in(VteTerminal *terminal, gchar 
*text, guint size,
 qemu_chr_be_write(vc->chr, (uint8_t  *)text, (unsigned int)size);
 return TRUE;
 }
-#endif
 
 static GSList *gd_vc_init(GtkDisplayState *s, VirtualConsole *vc, int index, 
GSList *group,
   GtkWidget *view_menu)
 {
-#if defined(CONFIG_VTE)
 const char *label;
 char buffer[32];
 char path[32];
@@ -1212,10 +1203,23 @@ static GSList *gd_vc_init(GtkDisplayState *s, 
VirtualConsole *vc, int index, GSL
 vc->chr->init(vc->chr);
 }
 
-#endif /* CONFIG_VTE */
 return group;
 }
 
+static void gd_vcs_init(GtkDisplayState *s, GSList *group,
+GtkWidget *view_menu)
+{
+int i;
+
+for (i = 0; i < nb_vcs; i++) {
+VirtualConsole *vc = &s->vc[i];
+
+group = gd_vc_init(s, vc, i, group, view_menu);
+s->nb_vcs++;
+}
+}
+#endif /* CONFIG_VTE */
+
 /** Window Creation **/
 
 static void gd_connect_signals(GtkDisplayState *s)
@@ -1316,7 +1320,6 @@ static GtkWidget *gd_create_menu_view(GtkDisplayState *s, 
GtkAccelGroup *accel_g
 GSList *group = NULL;
 GtkWidget *view_menu;
 GtkWidget *separator;
-int i;
 
 view_menu = gtk_menu_new();
 gtk_menu_set_accel_group(GTK_MENU(view_menu), accel_group);
@@ -1378,12 +1381,9 @@ static GtkWidget *gd_create_menu_view(GtkDisplayState 
*s, GtkAccelGroup *accel_g
 gtk_accel_map_add_entry("/View/VGA", GDK_KEY_1, HOTKEY_MODIFIERS);
 gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), s->vga_item);
 
-for (i = 0; i < nb_vcs; i++) {
-VirtualConsole *vc = &s->vc[i];
-
-group = gd_vc_init(s, vc, i, group, view_menu);
-s->nb_vcs++;
-}
+#if defined(CONFIG_VTE)
+gd_vcs_init(s, group, view_menu);
+#endif
 
 separator = gtk_separator_menu_item_new();
 gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), separator);
@@ -1512,3 +1512,10 @@ void gtk_display_init(DisplayState *ds, bool 
full_screen, bool grab_on_hover)
 
 global_state = s;
 }
+
+void early_gtk_display_init(void)
+{
+#if defined(CONFIG_VTE)
+register_vc_handler(gd_vc_handler);
+#endif
+}
-- 
1.8.3.1




[Qemu-devel] [PATCH 00/22] gtk: ui overhaul

2014-05-06 Thread Gerd Hoffmann
  Hi,

Here is the current gtk patch queue, featuring a ui overhaul.
Overall goal is better multihead/multiseat support.  Changes
in this patch series:

 (1) Restruct code+data, move graphical display state to
 separate struct so we can have multiple instances.
 (2) Add support for multiple displays.  If your guest
 has more than one gfx device you'll get a tab for each.
 (3) Add support for moving tabs to windows.  Try View/Untabify
 to move a tab to its own window.  Close the new window
 to move it back.
 (4) Various code adaptions (especially in the input grab code)
 so it deals with multiple windows correctly.
 (5) Misc minor clanups and fixes along the way.

Code is also available here:
  https://www.kraxel.org/cgit/qemu/log/?h=rebase/ui-gtk-next
[ warning: branch is a moving target ]

Please test and review.  Feedback is welcome.

cheers,
  Gerd

Bruce Rogers (1):
  gtk: Add handling for the xfree86 keycodes

Cole Robinson (1):
  gtk: Add a scrollbar for text consoles

Gerd Hoffmann (20):
  gtk: zap scrolled_window
  gtk: zap vte size requests
  gtk: cleanup CONFIG_VTE ifdef a bit.
  gtk: remove page numbering assumtions from the code
  gtk: VirtualConsole restruction
  gtk: move vga state into VirtualGfxConsole
  gtk: support multiple gfx displays
  gtk: use device type as label
  gtk: simplify resize
  gtk: allow moving tabs to windows and back.
  gtk: add tab to trace events
  gtk: add gd_grab trace event
  gtk: keep track of grab owner
  gtk: skip keyboard grab when hover autograb is active
  gtk: update gd_update_caption
  gtk: fix grab checks
  gtk: update all windows on mouse mode changes
  gtk: enable window pointer grabs
  gtk: enable untabify for gfx
  gtk: zap unused global_state

 trace-events |7 +-
 ui/gtk.c | 1038 +-
 2 files changed, 663 insertions(+), 382 deletions(-)

-- 
1.8.3.1




[Qemu-devel] [PATCH 13/22] gtk: add gd_grab trace event

2014-05-06 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann 
---
 trace-events | 1 +
 ui/gtk.c | 4 
 2 files changed, 5 insertions(+)

diff --git a/trace-events b/trace-events
index 9b9d9d9..c93440d 100644
--- a/trace-events
+++ b/trace-events
@@ -1041,6 +1041,7 @@ ppm_save(const char *filename, void *display_surface) "%s 
surface=%p"
 gd_switch(const char *tab, int width, int height) "tab=%s, width=%d, height=%d"
 gd_update(const char *tab, int x, int y, int w, int h) "tab=%s, x=%d, y=%d, 
w=%d, h=%d"
 gd_key_event(const char *tab, int gdk_keycode, int qemu_keycode, const char 
*action) "tab=%s, translated GDK keycode %d to QEMU keycode %d (%s)"
+gd_grab(const char *tab, const char *device, bool on) "tab=%s, %s %d"
 
 # ui/input.c
 input_event_key_number(int conidx, int number, bool down) "con %d, key number 
0x%x, down %d"
diff --git a/ui/gtk.c b/ui/gtk.c
index c47f4ee..b251976 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -1058,6 +1058,7 @@ static void gd_grab_keyboard(VirtualConsole *vc)
   FALSE,
   GDK_CURRENT_TIME);
 #endif
+trace_gd_grab(vc->label, "kbd", true);
 }
 
 static void gd_ungrab_keyboard(VirtualConsole *vc)
@@ -1080,6 +1081,7 @@ static void gd_ungrab_keyboard(VirtualConsole *vc)
 #else
 gdk_keyboard_ungrab(GDK_CURRENT_TIME);
 #endif
+trace_gd_grab(vc->label, "kbd", false);
 }
 
 static void gd_grab_pointer(VirtualConsole *vc)
@@ -1125,6 +1127,7 @@ static void gd_grab_pointer(VirtualConsole *vc)
 gdk_display_get_pointer(display, NULL,
 &vc->s->grab_x_root, &vc->s->grab_y_root, NULL);
 #endif
+trace_gd_grab(vc->label, "ptr", true);
 }
 
 static void gd_ungrab_pointer(VirtualConsole *vc)
@@ -1153,6 +1156,7 @@ static void gd_ungrab_pointer(VirtualConsole *vc)
  gtk_widget_get_screen(vc->gfx.drawing_area),
  vc->s->grab_x_root, vc->s->grab_y_root);
 #endif
+trace_gd_grab(vc->label, "ptr", false);
 }
 
 static void gd_menu_grab_input(GtkMenuItem *item, void *opaque)
-- 
1.8.3.1




[Qemu-devel] [PATCH 01/22] gtk: zap scrolled_window

2014-05-06 Thread Gerd Hoffmann
The vte widget implements the scrollable interface, placing it into
a scrolled window is pointless and creates a bunch of strange effects.
Zap it.

Signed-off-by: Gerd Hoffmann 
---
 ui/gtk.c | 19 ++-
 1 file changed, 2 insertions(+), 17 deletions(-)

diff --git a/ui/gtk.c b/ui/gtk.c
index 9f5061a..f6f3677 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -110,7 +110,6 @@ typedef struct VirtualConsole
 GtkWidget *menu_item;
 GtkWidget *terminal;
 #if defined(CONFIG_VTE)
-GtkWidget *scrolled_window;
 CharDriverState *chr;
 #endif
 } VirtualConsole;
@@ -1189,8 +1188,6 @@ static GSList *gd_vc_init(GtkDisplayState *s, 
VirtualConsole *vc, int index, GSL
 const char *label;
 char buffer[32];
 char path[32];
-GtkWidget *scrolled_window;
-GtkAdjustment *vadjustment;
 
 snprintf(buffer, sizeof(buffer), "vc%d", index);
 snprintf(path, sizeof(path), "/View/VC%d", index);
@@ -1213,24 +1210,12 @@ static GSList *gd_vc_init(GtkDisplayState *s, 
VirtualConsole *vc, int index, GSL
 
 vte_terminal_set_scrollback_lines(VTE_TERMINAL(vc->terminal), -1);
 
-#if VTE_CHECK_VERSION(0, 28, 0) && GTK_CHECK_VERSION(3, 0, 0)
-vadjustment = gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(vc->terminal));
-#else
-vadjustment = vte_terminal_get_adjustment(VTE_TERMINAL(vc->terminal));
-#endif
-
-scrolled_window = gtk_scrolled_window_new(NULL, vadjustment);
-gtk_container_add(GTK_CONTAINER(scrolled_window), vc->terminal);
-
 vte_terminal_set_size(VTE_TERMINAL(vc->terminal), 80, 25);
 
 vc->chr->opaque = vc;
-vc->scrolled_window = scrolled_window;
-
-gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(vc->scrolled_window),
-   GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
 
-gtk_notebook_append_page(GTK_NOTEBOOK(s->notebook), scrolled_window, 
gtk_label_new(label));
+gtk_notebook_append_page(GTK_NOTEBOOK(s->notebook), vc->terminal,
+ gtk_label_new(label));
 g_signal_connect(vc->menu_item, "activate",
  G_CALLBACK(gd_menu_switch_vc), s);
 
-- 
1.8.3.1




[Qemu-devel] [PATCH 10/22] gtk: simplify resize

2014-05-06 Thread Gerd Hoffmann
Simply ask for a small window size.  When the widgets don't fit in gtk
will automatically make the window large enougth to make things fit, no
need to try (and fail) duplicate that logic in qemu.

Signed-off-by: Gerd Hoffmann 
---
 ui/gtk.c | 40 ++--
 1 file changed, 14 insertions(+), 26 deletions(-)

diff --git a/ui/gtk.c b/ui/gtk.c
index a8393dd..6790cf8 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -296,35 +296,23 @@ static void gd_update_caption(GtkDisplayState *s)
 static void gd_update_windowsize(VirtualConsole *vc)
 {
 GtkDisplayState *s = vc->s;
+double sx, sy;
 
-if (!s->full_screen) {
-GtkRequisition req;
-double sx, sy;
-
-if (s->free_scale) {
-sx = vc->gfx.scale_x;
-sy = vc->gfx.scale_y;
-
-vc->gfx.scale_y = 1.0;
-vc->gfx.scale_x = 1.0;
-} else {
-sx = 1.0;
-sy = 1.0;
-}
-
-gtk_widget_set_size_request
-(vc->gfx.drawing_area,
- surface_width(vc->gfx.ds) * vc->gfx.scale_x,
- surface_height(vc->gfx.ds) * vc->gfx.scale_y);
-#if GTK_CHECK_VERSION(3, 0, 0)
-gtk_widget_get_preferred_size(s->vbox, NULL, &req);
-#else
-gtk_widget_size_request(s->vbox, &req);
-#endif
+if (vc->type != GD_VC_GFX || s->full_screen) {
+return;
+}
 
-gtk_window_resize(GTK_WINDOW(s->window),
-  req.width * sx, req.height * sy);
+if (s->free_scale) {
+sx = 1.0;
+sy = 1.0;
+} else {
+sx = vc->gfx.scale_x;
+sy = vc->gfx.scale_y;
 }
+gtk_widget_set_size_request(vc->gfx.drawing_area,
+surface_width(vc->gfx.ds) * sx,
+surface_height(vc->gfx.ds) * sy);
+gtk_window_resize(GTK_WINDOW(s->window), 320, 240);
 }
 
 static void gd_update_full_redraw(VirtualConsole *vc)
-- 
1.8.3.1




[Qemu-devel] [PATCH 12/22] gtk: add tab to trace events

2014-05-06 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann 
---
 trace-events | 6 +++---
 ui/gtk.c | 6 +++---
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/trace-events b/trace-events
index a5218ba..9b9d9d9 100644
--- a/trace-events
+++ b/trace-events
@@ -1038,9 +1038,9 @@ displaychangelistener_unregister(void *dcl, const char 
*name) "%p [ %s ]"
 ppm_save(const char *filename, void *display_surface) "%s surface=%p"
 
 # ui/gtk.c
-gd_switch(int width, int height) "width=%d, height=%d"
-gd_update(int x, int y, int w, int h) "x=%d, y=%d, w=%d, h=%d"
-gd_key_event(int gdk_keycode, int qemu_keycode, const char *action) 
"translated GDK keycode %d to QEMU keycode %d (%s)"
+gd_switch(const char *tab, int width, int height) "tab=%s, width=%d, height=%d"
+gd_update(const char *tab, int x, int y, int w, int h) "tab=%s, x=%d, y=%d, 
w=%d, h=%d"
+gd_key_event(const char *tab, int gdk_keycode, int qemu_keycode, const char 
*action) "tab=%s, translated GDK keycode %d to QEMU keycode %d (%s)"
 
 # ui/input.c
 input_event_key_number(int conidx, int number, bool down) "con %d, key number 
0x%x, down %d"
diff --git a/ui/gtk.c b/ui/gtk.c
index e90d232..c47f4ee 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -355,7 +355,7 @@ static void gd_update(DisplayChangeListener *dcl,
 int fbw, fbh;
 int ww, wh;
 
-trace_gd_update(x, y, w, h);
+trace_gd_update(vc->label, x, y, w, h);
 
 if (vc->gfx.convert) {
 pixman_image_composite(PIXMAN_OP_SRC, vc->gfx.ds->image,
@@ -461,7 +461,7 @@ static void gd_switch(DisplayChangeListener *dcl,
 VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
 bool resized = true;
 
-trace_gd_switch(surface_width(surface), surface_height(surface));
+trace_gd_switch(vc->label, surface_width(surface), 
surface_height(surface));
 
 if (vc->gfx.surface) {
 cairo_surface_destroy(vc->gfx.surface);
@@ -815,7 +815,7 @@ static gboolean gd_key_event(GtkWidget *widget, GdkEventKey 
*key, void *opaque)
 }
 #endif
 
-trace_gd_key_event(gdk_keycode, qemu_keycode,
+trace_gd_key_event(vc->label, gdk_keycode, qemu_keycode,
(key->type == GDK_KEY_PRESS) ? "down" : "up");
 
 for (i = 0; i < ARRAY_SIZE(modifier_keycode); i++) {
-- 
1.8.3.1




[Qemu-devel] [PATCH 09/22] gtk: use device type as label

2014-05-06 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann 
---
 ui/gtk.c | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/ui/gtk.c b/ui/gtk.c
index 0756432..a8393dd 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -67,6 +67,7 @@
 #include "x_keymap.h"
 #include "keymaps.h"
 #include "sysemu/char.h"
+#include "qom/object.h"
 
 #define MAX_VCS 10
 
@@ -1457,6 +1458,15 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, 
VirtualConsole *vc,
   QemuConsole *con, int idx,
   GSList *group, GtkWidget *view_menu)
 {
+const char *label = "VGA";
+Error *local_err = NULL;
+Object *obj;
+
+obj = object_property_get_link(OBJECT(con), "device", &local_err);
+if (obj) {
+label = object_get_typename(obj);
+}
+
 vc->s = s;
 vc->gfx.scale_x = 1.0;
 vc->gfx.scale_y = 1.0;
@@ -1477,10 +1487,10 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, 
VirtualConsole *vc,
 vc->type = GD_VC_GFX;
 vc->tab_item = vc->gfx.drawing_area;
 gtk_notebook_append_page(GTK_NOTEBOOK(s->notebook),
- vc->tab_item, gtk_label_new("VGA"));
+ vc->tab_item, gtk_label_new(label));
 gd_connect_vc_gfx_signals(vc);
 
-group = gd_vc_menu_init(s, vc, "VGA", idx, group, view_menu);
+group = gd_vc_menu_init(s, vc, label, idx, group, view_menu);
 
 vc->gfx.dcl.ops = &dcl_ops;
 vc->gfx.dcl.con = con;
-- 
1.8.3.1




[Qemu-devel] [PATCH 04/22] gtk: Add a scrollbar for text consoles

2014-05-06 Thread Gerd Hoffmann
From: Cole Robinson 

Only show the scrollbar if the content doesn't fit on the visible space.

[ kraxel: fix box packing ]

Signed-off-by: Cole Robinson 
Signed-off-by: Gerd Hoffmann 
---
 ui/gtk.c | 42 --
 1 file changed, 40 insertions(+), 2 deletions(-)

diff --git a/ui/gtk.c b/ui/gtk.c
index 068a39b..6a3fe00 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -109,6 +109,8 @@ typedef struct VirtualConsole
 {
 GtkWidget *menu_item;
 #if defined(CONFIG_VTE)
+GtkWidget *box;
+GtkWidget *scrollbar;
 GtkWidget *terminal;
 CharDriverState *chr;
 #endif
@@ -1125,6 +1127,18 @@ static gboolean gd_focus_out_event(GtkWidget *widget,
 /** Virtual Console Callbacks **/
 
 #if defined(CONFIG_VTE)
+static void gd_vc_adjustment_changed(GtkAdjustment *adjustment, void *opaque)
+{
+VirtualConsole *vc = opaque;
+
+if (gtk_adjustment_get_upper(adjustment) >
+gtk_adjustment_get_page_size(adjustment)) {
+gtk_widget_show(vc->scrollbar);
+} else {
+gtk_widget_hide(vc->scrollbar);
+}
+}
+
 static int gd_vc_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
 {
 VirtualConsole *vc = chr->opaque;
@@ -1165,6 +1179,9 @@ static GSList *gd_vc_init(GtkDisplayState *s, 
VirtualConsole *vc, int index, GSL
 const char *label;
 char buffer[32];
 char path[32];
+GtkWidget *box;
+GtkWidget *scrollbar;
+GtkAdjustment *vadjustment;
 
 snprintf(buffer, sizeof(buffer), "vc%d", index);
 snprintf(path, sizeof(path), "/View/VC%d", index);
@@ -1186,12 +1203,33 @@ static GSList *gd_vc_init(GtkDisplayState *s, 
VirtualConsole *vc, int index, GSL
 g_signal_connect(vc->terminal, "commit", G_CALLBACK(gd_vc_in), vc);
 
 vte_terminal_set_scrollback_lines(VTE_TERMINAL(vc->terminal), -1);
-
 vte_terminal_set_size(VTE_TERMINAL(vc->terminal), 80, 25);
 
+#if VTE_CHECK_VERSION(0, 28, 0) && GTK_CHECK_VERSION(3, 0, 0)
+vadjustment = gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(vc->terminal));
+#else
+vadjustment = vte_terminal_get_adjustment(VTE_TERMINAL(vc->terminal));
+#endif
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2);
+scrollbar = gtk_scrollbar_new(GTK_ORIENTATION_VERTICAL, vadjustment);
+#else
+box = gtk_hbox_new(false, 2);
+scrollbar = gtk_vscrollbar_new(vadjustment);
+#endif
+
+gtk_box_pack_start(GTK_BOX(box), vc->terminal, TRUE, TRUE, 0);
+gtk_box_pack_start(GTK_BOX(box), scrollbar, FALSE, FALSE, 0);
+
 vc->chr->opaque = vc;
+vc->box = box;
+vc->scrollbar = scrollbar;
+
+g_signal_connect(vadjustment, "changed",
+ G_CALLBACK(gd_vc_adjustment_changed), vc);
 
-gtk_notebook_append_page(GTK_NOTEBOOK(s->notebook), vc->terminal,
+gtk_notebook_append_page(GTK_NOTEBOOK(s->notebook), box,
  gtk_label_new(label));
 g_signal_connect(vc->menu_item, "activate",
  G_CALLBACK(gd_menu_switch_vc), s);
-- 
1.8.3.1




[Qemu-devel] [PATCH 05/22] gtk: remove page numbering assumtions from the code

2014-05-06 Thread Gerd Hoffmann
Lookup page numbers using gtk_notebook_page_num() instead.

Signed-off-by: Gerd Hoffmann 
---
 ui/gtk.c | 40 ++--
 1 file changed, 30 insertions(+), 10 deletions(-)

diff --git a/ui/gtk.c b/ui/gtk.c
index 6a3fe00..49753ef 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -190,7 +190,11 @@ static bool gd_grab_on_hover(GtkDisplayState *s)
 
 static bool gd_on_vga(GtkDisplayState *s)
 {
-return gtk_notebook_get_current_page(GTK_NOTEBOOK(s->notebook)) == 0;
+gint p1, p2;
+
+p1 = gtk_notebook_get_current_page(GTK_NOTEBOOK(s->notebook));
+p2 = gtk_notebook_page_num(GTK_NOTEBOOK(s->notebook), s->drawing_area);
+return p1 == p2;
 }
 
 static void gd_update_cursor(GtkDisplayState *s, gboolean override)
@@ -805,19 +809,25 @@ static void gd_menu_quit(GtkMenuItem *item, void *opaque)
 static void gd_menu_switch_vc(GtkMenuItem *item, void *opaque)
 {
 GtkDisplayState *s = opaque;
+gint page;
 
 if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(s->vga_item))) {
-gtk_notebook_set_current_page(GTK_NOTEBOOK(s->notebook), 0);
+page = gtk_notebook_page_num(GTK_NOTEBOOK(s->notebook),
+ s->drawing_area);
+gtk_notebook_set_current_page(GTK_NOTEBOOK(s->notebook), page);
 } else {
-int i;
-
 gtk_release_modifiers(s);
+#if defined(CONFIG_VTE)
+gint i;
 for (i = 0; i < s->nb_vcs; i++) {
 if 
(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(s->vc[i].menu_item))) {
-gtk_notebook_set_current_page(GTK_NOTEBOOK(s->notebook), i + 
1);
-break;
+page = gtk_notebook_page_num(GTK_NOTEBOOK(s->notebook),
+ s->vc[i].box);
+gtk_notebook_set_current_page(GTK_NOTEBOOK(s->notebook), page);
+return;
 }
 }
+#endif
 }
 }
 
@@ -1061,12 +1071,14 @@ static void gd_change_page(GtkNotebook *nb, gpointer 
arg1, guint arg2,
 {
 GtkDisplayState *s = data;
 gboolean on_vga;
+gint page;
 
 if (!gtk_widget_get_realized(s->notebook)) {
 return;
 }
 
-on_vga = arg2 == 0;
+page = gtk_notebook_page_num(GTK_NOTEBOOK(s->notebook), s->drawing_area);
+on_vga = arg2 == page;
 
 if (!on_vga) {
 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item),
@@ -1076,12 +1088,20 @@ static void gd_change_page(GtkNotebook *nb, gpointer 
arg1, guint arg2,
TRUE);
 }
 
-if (arg2 == 0) {
+if (on_vga) {
 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->vga_item), TRUE);
 } else {
 #if defined(CONFIG_VTE)
-VirtualConsole *vc = &s->vc[arg2 - 1];
-gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(vc->menu_item), 
TRUE);
+VirtualConsole *vc;
+gint page, i;
+for (i = 0; i < s->nb_vcs; i++) {
+vc = &s->vc[i];
+page = gtk_notebook_page_num(GTK_NOTEBOOK(s->notebook), vc->box);
+if (page == arg2) {
+gtk_check_menu_item_set_active
+(GTK_CHECK_MENU_ITEM(vc->menu_item), TRUE);
+}
+}
 #else
 g_assert_not_reached();
 #endif
-- 
1.8.3.1




[Qemu-devel] [PATCH 15/22] gtk: skip keyboard grab when hover autograb is active

2014-05-06 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann 
---
 ui/gtk.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/ui/gtk.c b/ui/gtk.c
index 02e4685..a00635a 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -1183,7 +1183,9 @@ static void gd_menu_grab_input(GtkMenuItem *item, void 
*opaque)
 VirtualConsole *vc = gd_vc_find_current(s);
 
 if (gd_is_grab_active(s)) {
-gd_grab_keyboard(vc);
+if (!gd_grab_on_hover(s)) {
+gd_grab_keyboard(vc);
+}
 gd_grab_pointer(vc);
 } else {
 gd_ungrab_keyboard(s);
-- 
1.8.3.1




[Qemu-devel] [PATCH 19/22] gtk: enable window pointer grabs

2014-05-06 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann 
---
 ui/gtk.c | 24 +---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/ui/gtk.c b/ui/gtk.c
index 3754246..6cfb09c 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -773,10 +773,7 @@ static gboolean gd_button_event(GtkWidget *widget, 
GdkEventButton *button,
 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item),
TRUE);
 } else {
-#if 0
-/* FIXME: no way (yet) to ungrab */
 gd_grab_pointer(vc);
-#endif
 gd_update_caption(s);
 }
 return TRUE;
@@ -945,6 +942,20 @@ static gboolean gd_tab_window_close(GtkWidget *widget, 
GdkEvent *event,
 return TRUE;
 }
 
+static gboolean gd_win_grab(void *opaque)
+{
+VirtualConsole *vc = opaque;
+
+fprintf(stderr, "%s: %s\n", __func__, vc->label);
+if (vc->s->ptr_owner) {
+gd_ungrab_pointer(vc->s);
+} else {
+gd_grab_pointer(vc);
+}
+gd_update_caption(vc->s);
+return TRUE;
+}
+
 static void gd_menu_untabify(GtkMenuItem *item, void *opaque)
 {
 GtkDisplayState *s = opaque;
@@ -963,6 +974,13 @@ static void gd_menu_untabify(GtkMenuItem *item, void 
*opaque)
  G_CALLBACK(gd_tab_window_close), vc);
 gtk_widget_show_all(vc->window);
 
+GtkAccelGroup *ag = gtk_accel_group_new();
+gtk_window_add_accel_group(GTK_WINDOW(vc->window), ag);
+
+GClosure *cb = g_cclosure_new_swap(G_CALLBACK(gd_win_grab), vc, NULL);
+gtk_accel_group_connect(ag, GDK_KEY_g, HOTKEY_MODIFIERS, 0, cb);
+
+fprintf(stderr, "%s: %p\n", __func__, vc);
 gd_update_caption(s);
 }
 }
-- 
1.8.3.1




[Qemu-devel] [PATCH 07/22] gtk: move vga state into VirtualGfxConsole

2014-05-06 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann 
---
 ui/gtk.c | 615 ++-
 1 file changed, 337 insertions(+), 278 deletions(-)

diff --git a/ui/gtk.c b/ui/gtk.c
index 78f6ccc..bc42f68 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -105,6 +105,18 @@ static const int modifier_keycode[] = {
 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8, 0xdb, 0xdd,
 };
 
+typedef struct GtkDisplayState GtkDisplayState;
+
+typedef struct VirtualGfxConsole {
+GtkWidget *drawing_area;
+DisplayChangeListener dcl;
+DisplaySurface *ds;
+pixman_image_t *convert;
+cairo_surface_t *surface;
+double scale_x;
+double scale_y;
+} VirtualGfxConsole;
+
 #if defined(CONFIG_VTE)
 typedef struct VirtualVteConsole {
 GtkWidget *box;
@@ -114,18 +126,25 @@ typedef struct VirtualVteConsole {
 } VirtualVteConsole;
 #endif
 
+typedef enum VirtualConsoleType {
+GD_VC_GFX,
+GD_VC_VTE,
+} VirtualConsoleType;
+
 typedef struct VirtualConsole {
+GtkDisplayState *s;
 GtkWidget *menu_item;
 GtkWidget *tab_item;
+VirtualConsoleType type;
 union {
+VirtualGfxConsole gfx;
 #if defined(CONFIG_VTE)
 VirtualVteConsole vte;
 #endif
 };
 } VirtualConsole;
 
-typedef struct GtkDisplayState
-{
+struct GtkDisplayState {
 GtkWidget *window;
 
 GtkWidget *menu_bar;
@@ -148,7 +167,6 @@ typedef struct GtkDisplayState
 GtkWidget *zoom_fit_item;
 GtkWidget *grab_item;
 GtkWidget *grab_on_hover_item;
-GtkWidget *vga_item;
 
 int nb_vcs;
 VirtualConsole vc[MAX_VCS];
@@ -157,11 +175,6 @@ typedef struct GtkDisplayState
 
 GtkWidget *vbox;
 GtkWidget *notebook;
-GtkWidget *drawing_area;
-cairo_surface_t *surface;
-pixman_image_t *convert;
-DisplayChangeListener dcl;
-DisplaySurface *ds;
 int button_mask;
 gboolean last_set;
 int last_x;
@@ -169,8 +182,6 @@ typedef struct GtkDisplayState
 int grab_x_root;
 int grab_y_root;
 
-double scale_x;
-double scale_y;
 gboolean full_screen;
 
 GdkCursor *null_cursor;
@@ -180,7 +191,7 @@ typedef struct GtkDisplayState
 bool external_pause_update;
 
 bool modifier_pressed[ARRAY_SIZE(modifier_keycode)];
-} GtkDisplayState;
+};
 
 static GtkDisplayState *global_state;
 
@@ -216,6 +227,14 @@ static VirtualConsole *gd_vc_find_by_page(GtkDisplayState 
*s, gint page)
 return NULL;
 }
 
+static VirtualConsole *gd_vc_find_current(GtkDisplayState *s)
+{
+gint page;
+
+page = gtk_notebook_get_current_page(GTK_NOTEBOOK(s->notebook));
+return gd_vc_find_by_page(s, page);
+}
+
 static bool gd_is_grab_active(GtkDisplayState *s)
 {
 return gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(s->grab_item));
@@ -226,26 +245,17 @@ static bool gd_grab_on_hover(GtkDisplayState *s)
 return 
gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(s->grab_on_hover_item));
 }
 
-static bool gd_on_vga(GtkDisplayState *s)
-{
-gint p1, p2;
-
-p1 = gtk_notebook_get_current_page(GTK_NOTEBOOK(s->notebook));
-p2 = gtk_notebook_page_num(GTK_NOTEBOOK(s->notebook), s->drawing_area);
-return p1 == p2;
-}
-
-static void gd_update_cursor(GtkDisplayState *s, gboolean override)
+static void gd_update_cursor(VirtualConsole *vc)
 {
+GtkDisplayState *s = vc->s;
 GdkWindow *window;
-bool on_vga;
-
-window = gtk_widget_get_window(GTK_WIDGET(s->drawing_area));
 
-on_vga = gd_on_vga(s);
+if (vc->type != GD_VC_GFX) {
+return;
+}
 
-if ((override || on_vga) &&
-(s->full_screen || qemu_input_is_absolute() || gd_is_grab_active(s))) {
+window = gtk_widget_get_window(GTK_WIDGET(vc->gfx.drawing_area));
+if (s->full_screen || qemu_input_is_absolute() || gd_is_grab_active(s)) {
 gdk_window_set_cursor(window, s->null_cursor);
 } else {
 gdk_window_set_cursor(window, NULL);
@@ -282,26 +292,29 @@ static void gd_update_caption(GtkDisplayState *s)
 g_free(title);
 }
 
-static void gd_update_windowsize(GtkDisplayState *s)
+static void gd_update_windowsize(VirtualConsole *vc)
 {
+GtkDisplayState *s = vc->s;
+
 if (!s->full_screen) {
 GtkRequisition req;
 double sx, sy;
 
 if (s->free_scale) {
-sx = s->scale_x;
-sy = s->scale_y;
+sx = vc->gfx.scale_x;
+sy = vc->gfx.scale_y;
 
-s->scale_y = 1.0;
-s->scale_x = 1.0;
+vc->gfx.scale_y = 1.0;
+vc->gfx.scale_x = 1.0;
 } else {
 sx = 1.0;
 sy = 1.0;
 }
 
-gtk_widget_set_size_request(s->drawing_area,
-surface_width(s->ds) * s->scale_x,
-surface_height(s->ds) * s->scale_y);
+gtk_widget_set_size_request
+(vc->gfx.drawing_area,
+ surface_width(vc->gfx.ds) * vc->gfx.scale_x,
+ surface_height(vc->gfx.ds) * vc->gfx.scale_y);
 #if GTK_CHECK_VERSION(3, 0, 0)

[Qemu-devel] [PATCH 06/22] gtk: VirtualConsole restruction

2014-05-06 Thread Gerd Hoffmann
Move all vte-related items into VirtualVteConsole substruct.

Signed-off-by: Gerd Hoffmann 
---
 ui/gtk.c | 119 +++
 1 file changed, 73 insertions(+), 46 deletions(-)

diff --git a/ui/gtk.c b/ui/gtk.c
index 49753ef..78f6ccc 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -105,15 +105,23 @@ static const int modifier_keycode[] = {
 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8, 0xdb, 0xdd,
 };
 
-typedef struct VirtualConsole
-{
-GtkWidget *menu_item;
 #if defined(CONFIG_VTE)
+typedef struct VirtualVteConsole {
 GtkWidget *box;
 GtkWidget *scrollbar;
 GtkWidget *terminal;
 CharDriverState *chr;
+} VirtualVteConsole;
+#endif
+
+typedef struct VirtualConsole {
+GtkWidget *menu_item;
+GtkWidget *tab_item;
+union {
+#if defined(CONFIG_VTE)
+VirtualVteConsole vte;
 #endif
+};
 } VirtualConsole;
 
 typedef struct GtkDisplayState
@@ -178,6 +186,36 @@ static GtkDisplayState *global_state;
 
 /** Utility Functions **/
 
+static VirtualConsole *gd_vc_find_by_menu(GtkDisplayState *s)
+{
+VirtualConsole *vc;
+gint i;
+
+for (i = 0; i < s->nb_vcs; i++) {
+vc = &s->vc[i];
+if (gtk_check_menu_item_get_active
+(GTK_CHECK_MENU_ITEM(vc->menu_item))) {
+return vc;
+}
+}
+return NULL;
+}
+
+static VirtualConsole *gd_vc_find_by_page(GtkDisplayState *s, gint page)
+{
+VirtualConsole *vc;
+gint i, p;
+
+for (i = 0; i < s->nb_vcs; i++) {
+vc = &s->vc[i];
+p = gtk_notebook_page_num(GTK_NOTEBOOK(s->notebook), vc->tab_item);
+if (p == page) {
+return vc;
+}
+}
+return NULL;
+}
+
 static bool gd_is_grab_active(GtkDisplayState *s)
 {
 return gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(s->grab_item));
@@ -817,17 +855,12 @@ static void gd_menu_switch_vc(GtkMenuItem *item, void 
*opaque)
 gtk_notebook_set_current_page(GTK_NOTEBOOK(s->notebook), page);
 } else {
 gtk_release_modifiers(s);
-#if defined(CONFIG_VTE)
-gint i;
-for (i = 0; i < s->nb_vcs; i++) {
-if 
(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(s->vc[i].menu_item))) {
-page = gtk_notebook_page_num(GTK_NOTEBOOK(s->notebook),
- s->vc[i].box);
-gtk_notebook_set_current_page(GTK_NOTEBOOK(s->notebook), page);
-return;
-}
+VirtualConsole *vc = gd_vc_find_by_menu(s);
+if (vc) {
+page = gtk_notebook_page_num(GTK_NOTEBOOK(s->notebook),
+ vc->tab_item);
+gtk_notebook_set_current_page(GTK_NOTEBOOK(s->notebook), page);
 }
-#endif
 }
 }
 
@@ -1091,20 +1124,12 @@ static void gd_change_page(GtkNotebook *nb, gpointer 
arg1, guint arg2,
 if (on_vga) {
 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->vga_item), TRUE);
 } else {
-#if defined(CONFIG_VTE)
 VirtualConsole *vc;
-gint page, i;
-for (i = 0; i < s->nb_vcs; i++) {
-vc = &s->vc[i];
-page = gtk_notebook_page_num(GTK_NOTEBOOK(s->notebook), vc->box);
-if (page == arg2) {
-gtk_check_menu_item_set_active
-(GTK_CHECK_MENU_ITEM(vc->menu_item), TRUE);
-}
+vc = gd_vc_find_by_page(s, arg2);
+if (vc) {
+gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(vc->menu_item),
+   TRUE);
 }
-#else
-g_assert_not_reached();
-#endif
 }
 
 gtk_widget_set_sensitive(s->grab_item, on_vga);
@@ -1153,9 +1178,9 @@ static void gd_vc_adjustment_changed(GtkAdjustment 
*adjustment, void *opaque)
 
 if (gtk_adjustment_get_upper(adjustment) >
 gtk_adjustment_get_page_size(adjustment)) {
-gtk_widget_show(vc->scrollbar);
+gtk_widget_show(vc->vte.scrollbar);
 } else {
-gtk_widget_hide(vc->scrollbar);
+gtk_widget_hide(vc->vte.scrollbar);
 }
 }
 
@@ -1163,7 +1188,7 @@ static int gd_vc_chr_write(CharDriverState *chr, const 
uint8_t *buf, int len)
 {
 VirtualConsole *vc = chr->opaque;
 
-vte_terminal_feed(VTE_TERMINAL(vc->terminal), (const char *)buf, len);
+vte_terminal_feed(VTE_TERMINAL(vc->vte.terminal), (const char *)buf, len);
 return len;
 }
 
@@ -1189,7 +1214,7 @@ static gboolean gd_vc_in(VteTerminal *terminal, gchar 
*text, guint size,
 {
 VirtualConsole *vc = user_data;
 
-qemu_chr_be_write(vc->chr, (uint8_t  *)text, (unsigned int)size);
+qemu_chr_be_write(vc->vte.chr, (uint8_t  *)text, (unsigned int)size);
 return TRUE;
 }
 
@@ -1206,10 +1231,10 @@ static GSList *gd_vc_init(GtkDisplayState *s, 
VirtualConsole *vc, int index, GSL
 snprintf(buffer, sizeof(buffer), "vc%d", index);
 snprintf(path, sizeof(path), "/View/VC%d", index);
 
-vc->chr = vcs[index];
+vc->vte.chr = vcs[index];
 

[Qemu-devel] [PATCH 14/22] gtk: keep track of grab owner

2014-05-06 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann 
---
 ui/gtk.c | 28 +++-
 1 file changed, 23 insertions(+), 5 deletions(-)

diff --git a/ui/gtk.c b/ui/gtk.c
index b251976..02e4685 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -185,6 +185,8 @@ struct GtkDisplayState {
 int last_y;
 int grab_x_root;
 int grab_y_root;
+VirtualConsole *kbd_owner;
+VirtualConsole *ptr_owner;
 
 gboolean full_screen;
 
@@ -1058,11 +1060,19 @@ static void gd_grab_keyboard(VirtualConsole *vc)
   FALSE,
   GDK_CURRENT_TIME);
 #endif
+vc->s->kbd_owner = vc;
 trace_gd_grab(vc->label, "kbd", true);
 }
 
-static void gd_ungrab_keyboard(VirtualConsole *vc)
+static void gd_ungrab_keyboard(GtkDisplayState *s)
 {
+VirtualConsole *vc = s->kbd_owner;
+
+if (vc == NULL) {
+return;
+}
+s->kbd_owner = NULL;
+
 #if GTK_CHECK_VERSION(3, 0, 0)
 GdkDisplay *display = gtk_widget_get_display(vc->gfx.drawing_area);
 GdkDeviceManager *mgr = gdk_display_get_device_manager(display);
@@ -1127,11 +1137,19 @@ static void gd_grab_pointer(VirtualConsole *vc)
 gdk_display_get_pointer(display, NULL,
 &vc->s->grab_x_root, &vc->s->grab_y_root, NULL);
 #endif
+vc->s->ptr_owner = vc;
 trace_gd_grab(vc->label, "ptr", true);
 }
 
-static void gd_ungrab_pointer(VirtualConsole *vc)
+static void gd_ungrab_pointer(GtkDisplayState *s)
 {
+VirtualConsole *vc = s->ptr_owner;
+
+if (vc == NULL) {
+return;
+}
+s->ptr_owner = NULL;
+
 GdkDisplay *display = gtk_widget_get_display(vc->gfx.drawing_area);
 #if GTK_CHECK_VERSION(3, 0, 0)
 GdkDeviceManager *mgr = gdk_display_get_device_manager(display);
@@ -1168,8 +1186,8 @@ static void gd_menu_grab_input(GtkMenuItem *item, void 
*opaque)
 gd_grab_keyboard(vc);
 gd_grab_pointer(vc);
 } else {
-gd_ungrab_keyboard(vc);
-gd_ungrab_pointer(vc);
+gd_ungrab_keyboard(s);
+gd_ungrab_pointer(s);
 }
 
 gd_update_caption(s);
@@ -1227,7 +1245,7 @@ static gboolean gd_leave_event(GtkWidget *widget, 
GdkEventCrossing *crossing,
 GtkDisplayState *s = vc->s;
 
 if (!gd_is_grab_active(s) && gd_grab_on_hover(s)) {
-gd_ungrab_keyboard(vc);
+gd_ungrab_keyboard(s);
 }
 
 return TRUE;
-- 
1.8.3.1




[Qemu-devel] [PATCH 16/22] gtk: update gd_update_caption

2014-05-06 Thread Gerd Hoffmann
Adapt to recent changes, handle multiple windows.

Signed-off-by: Gerd Hoffmann 
---
 ui/gtk.c | 45 -
 1 file changed, 28 insertions(+), 17 deletions(-)

diff --git a/ui/gtk.c b/ui/gtk.c
index a00635a..2739cc8 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -271,11 +271,20 @@ static void gd_update_cursor(VirtualConsole *vc)
 static void gd_update_caption(GtkDisplayState *s)
 {
 const char *status = "";
+gchar *prefix;
 gchar *title;
 const char *grab = "";
 bool is_paused = !runstate_is_running();
+int i;
 
-if (gd_is_grab_active(s)) {
+if (qemu_name) {
+prefix = g_strdup_printf("QEMU (%s)", qemu_name);
+} else {
+prefix = g_strdup_printf("QEMU");
+}
+
+if (s->ptr_owner != NULL &&
+s->ptr_owner->window == NULL) {
 grab = _(" - Press Ctrl+Alt+G to release grab");
 }
 
@@ -287,15 +296,24 @@ static void gd_update_caption(GtkDisplayState *s)
is_paused);
 s->external_pause_update = false;
 
-if (qemu_name) {
-title = g_strdup_printf("QEMU (%s)%s%s", qemu_name, status, grab);
-} else {
-title = g_strdup_printf("QEMU%s%s", status, grab);
-}
-
+title = g_strdup_printf("%s%s%s", prefix, status, grab);
 gtk_window_set_title(GTK_WINDOW(s->window), title);
-
 g_free(title);
+
+for (i = 0; i < s->nb_vcs; i++) {
+VirtualConsole *vc = &s->vc[i];
+
+if (!vc->window) {
+continue;
+}
+title = g_strdup_printf("%s: %s%s%s", prefix, vc->label,
+vc == s->kbd_owner ? " +kbd" : "",
+vc == s->ptr_owner ? " +ptr" : "");
+gtk_window_set_title(GTK_WINDOW(vc->window), title);
+g_free(title);
+}
+
+g_free(prefix);
 }
 
 static void gd_update_windowsize(VirtualConsole *vc)
@@ -915,7 +933,6 @@ static void gd_menu_untabify(GtkMenuItem *item, void 
*opaque)
 {
 GtkDisplayState *s = opaque;
 VirtualConsole *vc = gd_vc_find_current(s);
-char *title;
 
 if (vc->type == GD_VC_GFX) {
 /* temporary: needs more work to get grabs etc correct */
@@ -926,17 +943,11 @@ static void gd_menu_untabify(GtkMenuItem *item, void 
*opaque)
 vc->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 gtk_widget_reparent(vc->tab_item, vc->window);
 
-if (qemu_name) {
-title = g_strdup_printf("QEMU (%s): %s", qemu_name, vc->label);
-} else {
-title = g_strdup_printf("QEMU: %s", vc->label);
-}
-gtk_window_set_title(GTK_WINDOW(vc->window), title);
-g_free(title);
-
 g_signal_connect(vc->window, "delete-event",
  G_CALLBACK(gd_tab_window_close), vc);
 gtk_widget_show_all(vc->window);
+
+gd_update_caption(s);
 }
 }
 
-- 
1.8.3.1




[Qemu-devel] [PATCH 02/22] gtk: zap vte size requests

2014-05-06 Thread Gerd Hoffmann
The vte tabs simply get the size of the vga tab then, with whatever
cols and lines are fitting in.  I find this bahavior more useful than
resizing the qemu window all day long.

YMMV.  Comments are welcome.

Signed-off-by: Gerd Hoffmann 
---
 ui/gtk.c | 14 --
 1 file changed, 14 deletions(-)

diff --git a/ui/gtk.c b/ui/gtk.c
index f6f3677..776e72d 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -1058,19 +1058,12 @@ static void gd_change_page(GtkNotebook *nb, gpointer 
arg1, guint arg2,
gpointer data)
 {
 GtkDisplayState *s = data;
-guint last_page;
 gboolean on_vga;
 
 if (!gtk_widget_get_realized(s->notebook)) {
 return;
 }
 
-last_page = gtk_notebook_get_current_page(nb);
-
-if (last_page) {
-gtk_widget_set_size_request(s->vc[last_page - 1].terminal, -1, -1);
-}
-
 on_vga = arg2 == 0;
 
 if (!on_vga) {
@@ -1086,14 +1079,7 @@ static void gd_change_page(GtkNotebook *nb, gpointer 
arg1, guint arg2,
 } else {
 #if defined(CONFIG_VTE)
 VirtualConsole *vc = &s->vc[arg2 - 1];
-VteTerminal *term = VTE_TERMINAL(vc->terminal);
-int width, height;
-
-width = 80 * vte_terminal_get_char_width(term);
-height = 25 * vte_terminal_get_char_height(term);
-
 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(vc->menu_item), 
TRUE);
-gtk_widget_set_size_request(vc->terminal, width, height);
 #else
 g_assert_not_reached();
 #endif
-- 
1.8.3.1




[Qemu-devel] [PATCH 11/22] gtk: allow moving tabs to windows and back.

2014-05-06 Thread Gerd Hoffmann
View->Untabify will move to tab to a new window.
Simply closing the window will move it back into a notebook tab.
The label will be permamently stored in VirtualConsole->label,
so it can easily be reused to (re-)label tabs and windows.

Works for vte tabs only for now. pointer/kbd grab code needs
adaptions before we can enable it for gfx tabs too.

Signed-off-by: Gerd Hoffmann 
---
 ui/gtk.c | 74 ++--
 1 file changed, 63 insertions(+), 11 deletions(-)

diff --git a/ui/gtk.c b/ui/gtk.c
index 6790cf8..e90d232 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -134,6 +134,8 @@ typedef enum VirtualConsoleType {
 
 typedef struct VirtualConsole {
 GtkDisplayState *s;
+char *label;
+GtkWidget *window;
 GtkWidget *menu_item;
 GtkWidget *tab_item;
 VirtualConsoleType type;
@@ -173,6 +175,7 @@ struct GtkDisplayState {
 VirtualConsole vc[MAX_VCS];
 
 GtkWidget *show_tabs_item;
+GtkWidget *untabify_item;
 
 GtkWidget *vbox;
 GtkWidget *notebook;
@@ -891,6 +894,50 @@ static void gd_menu_show_tabs(GtkMenuItem *item, void 
*opaque)
 }
 }
 
+static gboolean gd_tab_window_close(GtkWidget *widget, GdkEvent *event,
+void *opaque)
+{
+VirtualConsole *vc = opaque;
+GtkDisplayState *s = vc->s;
+
+gtk_widget_set_sensitive(vc->menu_item, true);
+gtk_widget_reparent(vc->tab_item, s->notebook);
+gtk_notebook_set_tab_label_text(GTK_NOTEBOOK(s->notebook),
+vc->tab_item, vc->label);
+gtk_widget_destroy(vc->window);
+vc->window = NULL;
+return TRUE;
+}
+
+static void gd_menu_untabify(GtkMenuItem *item, void *opaque)
+{
+GtkDisplayState *s = opaque;
+VirtualConsole *vc = gd_vc_find_current(s);
+char *title;
+
+if (vc->type == GD_VC_GFX) {
+/* temporary: needs more work to get grabs etc correct */
+return;
+}
+if (!vc->window) {
+gtk_widget_set_sensitive(vc->menu_item, false);
+vc->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+gtk_widget_reparent(vc->tab_item, vc->window);
+
+if (qemu_name) {
+title = g_strdup_printf("QEMU (%s): %s", qemu_name, vc->label);
+} else {
+title = g_strdup_printf("QEMU: %s", vc->label);
+}
+gtk_window_set_title(GTK_WINDOW(vc->window), title);
+g_free(title);
+
+g_signal_connect(vc->window, "delete-event",
+ G_CALLBACK(gd_tab_window_close), vc);
+gtk_widget_show_all(vc->window);
+}
+}
+
 static void gd_menu_full_screen(GtkMenuItem *item, void *opaque)
 {
 GtkDisplayState *s = opaque;
@@ -1196,14 +1243,13 @@ static gboolean gd_focus_out_event(GtkWidget *widget,
 /** Virtual Console Callbacks **/
 
 static GSList *gd_vc_menu_init(GtkDisplayState *s, VirtualConsole *vc,
-   const char *label, int idx,
-   GSList *group, GtkWidget *view_menu)
+   int idx, GSList *group, GtkWidget *view_menu)
 {
 char path[32];
 
 snprintf(path, sizeof(path), "/View/VC%d", idx);
 
-vc->menu_item = gtk_radio_menu_item_new_with_mnemonic(group, label);
+vc->menu_item = gtk_radio_menu_item_new_with_mnemonic(group, vc->label);
 group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(vc->menu_item));
 gtk_menu_item_set_accel_path(GTK_MENU_ITEM(vc->menu_item), path);
 gtk_accel_map_add_entry(path, GDK_KEY_1 + idx, HOTKEY_MODIFIERS);
@@ -1266,7 +1312,6 @@ static GSList *gd_vc_vte_init(GtkDisplayState *s, 
VirtualConsole *vc,
   CharDriverState *chr, int idx,
   GSList *group, GtkWidget *view_menu)
 {
-const char *label;
 char buffer[32];
 GtkWidget *box;
 GtkWidget *scrollbar;
@@ -1276,8 +1321,9 @@ static GSList *gd_vc_vte_init(GtkDisplayState *s, 
VirtualConsole *vc,
 vc->vte.chr = chr;
 
 snprintf(buffer, sizeof(buffer), "vc%d", idx);
-label = vc->vte.chr->label ? vc->vte.chr->label : buffer;
-group = gd_vc_menu_init(s, vc, vc->vte.chr->label, idx, group, view_menu);
+vc->label = g_strdup_printf("%s", vc->vte.chr->label
+? vc->vte.chr->label : buffer);
+group = gd_vc_menu_init(s, vc, idx, group, view_menu);
 
 vc->vte.terminal = vte_terminal_new();
 g_signal_connect(vc->vte.terminal, "commit", G_CALLBACK(gd_vc_in), vc);
@@ -1313,7 +1359,7 @@ static GSList *gd_vc_vte_init(GtkDisplayState *s, 
VirtualConsole *vc,
 vc->type = GD_VC_VTE;
 vc->tab_item = box;
 gtk_notebook_append_page(GTK_NOTEBOOK(s->notebook), vc->tab_item,
- gtk_label_new(label));
+ gtk_label_new(vc->label));
 
 qemu_chr_be_generic_open(vc->vte.chr);
 if (vc->vte.chr->init) {
@@ -1372,6 +1418,8 @@ static void gd_connect_signals(GtkDisplayState *s)
 {
 g_signal_connect(s->show_tab

[Qemu-devel] [PATCH 08/22] gtk: support multiple gfx displays

2014-05-06 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann 
---
 ui/gtk.c | 80 ++--
 1 file changed, 43 insertions(+), 37 deletions(-)

diff --git a/ui/gtk.c b/ui/gtk.c
index bc42f68..0756432 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -1206,6 +1206,26 @@ static gboolean gd_focus_out_event(GtkWidget *widget,
 
 /** Virtual Console Callbacks **/
 
+static GSList *gd_vc_menu_init(GtkDisplayState *s, VirtualConsole *vc,
+   const char *label, int idx,
+   GSList *group, GtkWidget *view_menu)
+{
+char path[32];
+
+snprintf(path, sizeof(path), "/View/VC%d", idx);
+
+vc->menu_item = gtk_radio_menu_item_new_with_mnemonic(group, label);
+group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(vc->menu_item));
+gtk_menu_item_set_accel_path(GTK_MENU_ITEM(vc->menu_item), path);
+gtk_accel_map_add_entry(path, GDK_KEY_1 + idx, HOTKEY_MODIFIERS);
+
+g_signal_connect(vc->menu_item, "activate",
+ G_CALLBACK(gd_menu_switch_vc), s);
+gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), vc->menu_item);
+
+return group;
+}
+
 #if defined(CONFIG_VTE)
 static void gd_vc_adjustment_changed(GtkAdjustment *adjustment, void *opaque)
 {
@@ -1253,32 +1273,22 @@ static gboolean gd_vc_in(VteTerminal *terminal, gchar 
*text, guint size,
 return TRUE;
 }
 
-static GSList *gd_vc_vte_init(GtkDisplayState *s, VirtualConsole *vc, int 
index,
+static GSList *gd_vc_vte_init(GtkDisplayState *s, VirtualConsole *vc,
+  CharDriverState *chr, int idx,
   GSList *group, GtkWidget *view_menu)
 {
 const char *label;
 char buffer[32];
-char path[32];
 GtkWidget *box;
 GtkWidget *scrollbar;
 GtkAdjustment *vadjustment;
 
-snprintf(buffer, sizeof(buffer), "vc%d", index);
-snprintf(path, sizeof(path), "/View/VC%d", index);
-
 vc->s = s;
-vc->vte.chr = vcs[index];
-
-if (vc->vte.chr->label) {
-label = vc->vte.chr->label;
-} else {
-label = buffer;
-}
+vc->vte.chr = chr;
 
-vc->menu_item = gtk_radio_menu_item_new_with_mnemonic(group, label);
-group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(vc->menu_item));
-gtk_menu_item_set_accel_path(GTK_MENU_ITEM(vc->menu_item), path);
-gtk_accel_map_add_entry(path, GDK_KEY_2 + index, HOTKEY_MODIFIERS);
+snprintf(buffer, sizeof(buffer), "vc%d", idx);
+label = vc->vte.chr->label ? vc->vte.chr->label : buffer;
+group = gd_vc_menu_init(s, vc, vc->vte.chr->label, idx, group, view_menu);
 
 vc->vte.terminal = vte_terminal_new();
 g_signal_connect(vc->vte.terminal, "commit", G_CALLBACK(gd_vc_in), vc);
@@ -1315,10 +1325,6 @@ static GSList *gd_vc_vte_init(GtkDisplayState *s, 
VirtualConsole *vc, int index,
 vc->tab_item = box;
 gtk_notebook_append_page(GTK_NOTEBOOK(s->notebook), vc->tab_item,
  gtk_label_new(label));
-g_signal_connect(vc->menu_item, "activate",
- G_CALLBACK(gd_menu_switch_vc), s);
-
-gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), vc->menu_item);
 
 qemu_chr_be_generic_open(vc->vte.chr);
 if (vc->vte.chr->init) {
@@ -1328,15 +1334,14 @@ static GSList *gd_vc_vte_init(GtkDisplayState *s, 
VirtualConsole *vc, int index,
 return group;
 }
 
-static void gd_vcs_init(GtkDisplayState *s, int offset, GSList *group,
+static void gd_vcs_init(GtkDisplayState *s, GSList *group,
 GtkWidget *view_menu)
 {
 int i;
 
 for (i = 0; i < nb_vcs; i++) {
-VirtualConsole *vc = &s->vc[offset+i];
-
-group = gd_vc_vte_init(s, vc, i, group, view_menu);
+VirtualConsole *vc = &s->vc[s->nb_vcs];
+group = gd_vc_vte_init(s, vc, vcs[i], s->nb_vcs, group, view_menu);
 s->nb_vcs++;
 }
 }
@@ -1449,7 +1454,7 @@ static const DisplayChangeListenerOps dcl_ops = {
 };
 
 static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc,
-  QemuConsole *con, int index,
+  QemuConsole *con, int idx,
   GSList *group, GtkWidget *view_menu)
 {
 vc->s = s;
@@ -1475,15 +1480,7 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, 
VirtualConsole *vc,
  vc->tab_item, gtk_label_new("VGA"));
 gd_connect_vc_gfx_signals(vc);
 
-vc->menu_item = gtk_radio_menu_item_new_with_mnemonic(group, "_VGA");
-group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(vc->menu_item));
-gtk_menu_item_set_accel_path(GTK_MENU_ITEM(vc->menu_item),
- "/View/VGA");
-gtk_accel_map_add_entry("/View/VGA", GDK_KEY_1, HOTKEY_MODIFIERS);
-gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), vc->menu_item);
-
-g_signal_connect(vc->menu_item, "activate",
- G_CALLBACK(gd_menu_switch_vc), s);
+group = gd_vc_menu_init(s, vc, "VGA", idx, grou

[Qemu-devel] [PATCH 17/22] gtk: fix grab checks

2014-05-06 Thread Gerd Hoffmann
---
 ui/gtk.c | 35 +++
 1 file changed, 23 insertions(+), 12 deletions(-)

diff --git a/ui/gtk.c b/ui/gtk.c
index 2739cc8..5b1af8b 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -201,6 +201,9 @@ struct GtkDisplayState {
 
 static GtkDisplayState *global_state;
 
+static void gd_grab_pointer(VirtualConsole *vc);
+static void gd_ungrab_pointer(GtkDisplayState *s);
+
 /** Utility Functions **/
 
 static VirtualConsole *gd_vc_find_by_menu(GtkDisplayState *s)
@@ -261,7 +264,7 @@ static void gd_update_cursor(VirtualConsole *vc)
 }
 
 window = gtk_widget_get_window(GTK_WIDGET(vc->gfx.drawing_area));
-if (s->full_screen || qemu_input_is_absolute() || gd_is_grab_active(s)) {
+if (s->full_screen || qemu_input_is_absolute() || s->ptr_owner == vc) {
 gdk_window_set_cursor(window, s->null_cursor);
 } else {
 gdk_window_set_cursor(window, NULL);
@@ -702,7 +705,7 @@ static gboolean gd_motion_event(GtkWidget *widget, 
GdkEventMotion *motion,
 qemu_input_queue_abs(vc->gfx.dcl.con, INPUT_AXIS_Y, y,
  surface_height(vc->gfx.ds));
 qemu_input_event_sync();
-} else if (s->last_set && gd_is_grab_active(s)) {
+} else if (s->last_set && s->ptr_owner == vc) {
 qemu_input_queue_rel(vc->gfx.dcl.con, INPUT_AXIS_X, x - s->last_x);
 qemu_input_queue_rel(vc->gfx.dcl.con, INPUT_AXIS_Y, y - s->last_y);
 qemu_input_event_sync();
@@ -711,7 +714,7 @@ static gboolean gd_motion_event(GtkWidget *widget, 
GdkEventMotion *motion,
 s->last_y = y;
 s->last_set = TRUE;
 
-if (!qemu_input_is_absolute() && gd_is_grab_active(s)) {
+if (!qemu_input_is_absolute() && s->ptr_owner == vc) {
 GdkScreen *screen = gtk_widget_get_screen(vc->gfx.drawing_area);
 int x = (int)motion->x_root;
 int y = (int)motion->y_root;
@@ -760,9 +763,18 @@ static gboolean gd_button_event(GtkWidget *widget, 
GdkEventButton *button,
 
 /* implicitly grab the input at the first click in the relative mode */
 if (button->button == 1 && button->type == GDK_BUTTON_PRESS &&
-!qemu_input_is_absolute() && !gd_is_grab_active(s)) {
-gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item),
-   TRUE);
+!qemu_input_is_absolute() && s->ptr_owner != vc) {
+gd_ungrab_pointer(s);
+if (!vc->window) {
+gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item),
+   TRUE);
+} else {
+#if 0
+/* FIXME: no way (yet) to ungrab */
+gd_grab_pointer(vc);
+#endif
+gd_update_caption(s);
+}
 return TRUE;
 }
 
@@ -1224,7 +1236,6 @@ static void gd_change_page(GtkNotebook *nb, gpointer 
arg1, guint arg2,
 }
 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(vc->menu_item),
TRUE);
-
 on_vga = (vc->type == GD_VC_GFX);
 if (!on_vga) {
 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item),
@@ -1244,10 +1255,11 @@ static gboolean gd_enter_event(GtkWidget *widget, 
GdkEventCrossing *crossing,
 VirtualConsole *vc = opaque;
 GtkDisplayState *s = vc->s;
 
-if (!gd_is_grab_active(s) && gd_grab_on_hover(s)) {
+if (gd_grab_on_hover(s)) {
+gd_ungrab_keyboard(s);
 gd_grab_keyboard(vc);
+gd_update_caption(s);
 }
-
 return TRUE;
 }
 
@@ -1257,10 +1269,10 @@ static gboolean gd_leave_event(GtkWidget *widget, 
GdkEventCrossing *crossing,
 VirtualConsole *vc = opaque;
 GtkDisplayState *s = vc->s;
 
-if (!gd_is_grab_active(s) && gd_grab_on_hover(s)) {
+if (gd_grab_on_hover(s)) {
 gd_ungrab_keyboard(s);
+gd_update_caption(s);
 }
-
 return TRUE;
 }
 
@@ -1271,7 +1283,6 @@ static gboolean gd_focus_out_event(GtkWidget *widget,
 GtkDisplayState *s = vc->s;
 
 gtk_release_modifiers(s);
-
 return TRUE;
 }
 
-- 
1.8.3.1




Re: [Qemu-devel] [PATCH v3 7/7] hw/net/stellaris_enet: Convert to vmstate

2014-05-06 Thread Peter Maydell
On 6 May 2014 12:53, Dr. David Alan Gilbert  wrote:
> * Peter Maydell (peter.mayd...@linaro.org) wrote:
>> +{
>> +stellaris_enet_state *s = opaque;
>> +int i;
>> +
>> +/* Sanitize inbound state. Note that next_packet is an index but
>> + * np is a size; hence their valid upper bounds differ.
>> + */
>> +if (s->next_packet >= ARRAY_SIZE(s->rx)) {
>> +return -1;
>> +}
>> +
>> +if (s->np > ARRAY_SIZE(s->rx)) {
>> +return -1;
>> +}
>> +
>> +for (i = 0; i < ARRAY_SIZE(s->rx); i++) {
>> +if (s->rx[i].len > ARRAY_SIZE(s->rx[i].data)) {
>> +return -1;
>> +}
>> +}
>> +
>> +if (s->rx_fifo_offset > ARRAY_SIZE(s->rx[0].data) + 4) {
>> +return -1;
>> +}
>
> Can you explain that +4 ?
> I think I can see how it would end up equalling ARRAY_SIZE if
> you've just read the last 4 bytes, but how does it go beyond?

Whoops, I think this should be - 4, not + 4 (I think I
messed up when I rearranged this from "offset + 4 > ARRAY_SIZE"
to avoid the potential overflow in that expression.)
The DATA read code is going to read from the 4 bytes starting
at s->rx[s->next_packet].data + s->rx_fifo_offset, so
we need to make sure the offset doesn't allow that to
overrun. (When we read the last 4 bytes then
the rx_fifo_offset is reset to zero immediately, so at
migration it's never possible for it to be equal to
ARRAY_SIZE).

>> +
>> +if (s->tx_fifo_len > ARRAY_SIZE(s->tx_fifo)) {
>> +return -1;
>> +}
>> +
>> +return 0;
>> +}
>> +
>> +static const VMStateDescription vmstate_stellaris_enet = {
>> +.name = "stellaris_enet",
>> +.version_id = 2,
>> +.minimum_version_id = 2,
>> +.minimum_version_id_old = 2,
>
> Weren't we killing off the minimum_version_id_old's ?

Yes, but we can't til the patch making it optional
hits master (it is in the current migration pullreq,
so if that goes in OK I'll just delete the _old line.)

thanks
-- PMM



[Qemu-devel] [PATCH 18/22] gtk: update all windows on mouse mode changes

2014-05-06 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann 
---
 ui/gtk.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/ui/gtk.c b/ui/gtk.c
index 5b1af8b..3754246 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -553,6 +553,7 @@ static void gd_change_runstate(void *opaque, int running, 
RunState state)
 static void gd_mouse_mode_change(Notifier *notify, void *data)
 {
 GtkDisplayState *s;
+int i;
 
 s = container_of(notify, GtkDisplayState, mouse_mode_notifier);
 /* release the grab at switching to absolute mode */
@@ -560,7 +561,10 @@ static void gd_mouse_mode_change(Notifier *notify, void 
*data)
 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item),
FALSE);
 }
-gd_update_cursor(gd_vc_find_current(s));
+for (i = 0; i < s->nb_vcs; i++) {
+VirtualConsole *vc = &s->vc[i];
+gd_update_cursor(vc);
+}
 }
 
 /** GTK Events **/
-- 
1.8.3.1




Re: [Qemu-devel] [PATCH] improve emulation correctness

2014-05-06 Thread poletaev
Thank you for attention :)
This patch not needed, according to QEMU dev policy, and so I will not sent
it any more. 
I found another defect, and it not related with undefined flags.

-Original Message-
From: Stefan Hajnoczi [mailto:stefa...@gmail.com] 
Sent: Friday, May 02, 2014 1:09 PM
To: poletaev
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH] improve emulation correctness

On Thu, Apr 24, 2014 at 12:35:24PM +0400, poletaev wrote:
> There is a set of test, that checks QEMU CPU for similar behavior with 
> real hardware (http://roberto.greyhats.it/projects/pills.html). Test 
> reg/pill2579.c can detect, that program is execute in emulated
environment.
> It is related with behavior of rcl instruction. If the number of 
> shifted bits more than 1, OF of eflags become undefined. Real CPUs 
> does not change OF, if it is undefined. QEMU do it anyway.
> 
> Emulated program can execute that test and after that can understand 
> environment not real.
> 
>  
> 
> Signed-off-by: Dmitry Poletaev 

I see you resent the patch and it received attention the second time :).

Stefan




Re: [Qemu-devel] [PATCH 5/6] input: switch sparc32 kbd to new input api

2014-05-06 Thread Gerd Hoffmann
  Hi,

> - put_queue(s, 0); // XXX, layout?
> + put_queue(s, 0x21); // USA layout

> Here is a mapping with corrected codes for arrows/pgup/pgdown... :
> 
> static const uint8_t qcode_to_keycode[Q_KEY_CODE_MAX] = {
[ ... ]

Picked it up, thanks.

> I have tried a 119 keys Sun USB keyboard but the additional keys do not seem 
> to
> be detected by QEMU. Needs more work...

Using the 'sendkey' monitor command should work.

Typing on the physical keyboard needs work in the UI code I guess.
What you are using?  gtk? sdl? vnc?

cheers,
  Gerd





[Qemu-devel] [PATCH 20/22] gtk: enable untabify for gfx

2014-05-06 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann 
---
 ui/gtk.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/ui/gtk.c b/ui/gtk.c
index 6cfb09c..37fe4a2 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -338,7 +338,11 @@ static void gd_update_windowsize(VirtualConsole *vc)
 gtk_widget_set_size_request(vc->gfx.drawing_area,
 surface_width(vc->gfx.ds) * sx,
 surface_height(vc->gfx.ds) * sy);
-gtk_window_resize(GTK_WINDOW(s->window), 320, 240);
+if (vc->window) {
+gtk_window_resize(GTK_WINDOW(vc->window), 320, 240);
+} else {
+gtk_window_resize(GTK_WINDOW(s->window), 320, 240);
+}
 }
 
 static void gd_update_full_redraw(VirtualConsole *vc)
@@ -962,8 +966,8 @@ static void gd_menu_untabify(GtkMenuItem *item, void 
*opaque)
 VirtualConsole *vc = gd_vc_find_current(s);
 
 if (vc->type == GD_VC_GFX) {
-/* temporary: needs more work to get grabs etc correct */
-return;
+gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item),
+   FALSE);
 }
 if (!vc->window) {
 gtk_widget_set_sensitive(vc->menu_item, false);
-- 
1.8.3.1




[Qemu-devel] [PATCH 22/22] gtk: zap unused global_state

2014-05-06 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann 
---
 ui/gtk.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/ui/gtk.c b/ui/gtk.c
index a9136ed..3355cb4 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -204,8 +204,6 @@ struct GtkDisplayState {
 bool has_evdev;
 };
 
-static GtkDisplayState *global_state;
-
 static void gd_grab_pointer(VirtualConsole *vc);
 static void gd_ungrab_pointer(GtkDisplayState *s);
 
@@ -1815,8 +1813,6 @@ void gtk_display_init(DisplayState *ds, bool full_screen, 
bool grab_on_hover)
 }
 
 gd_set_keycode_type(s);
-
-global_state = s;
 }
 
 void early_gtk_display_init(void)
-- 
1.8.3.1




Re: [Qemu-devel] [PATCH v8 0/4] qemu-img: add preallocation=full

2014-05-06 Thread Stefan Hajnoczi
On Wed, Apr 09, 2014 at 03:12:33PM +0800, Hu Tao wrote:
> The purpose of this series is to use posix_fallocate() when creating
> img file to ensure there are disk space for it which is way fast than
> acturally writing to disk. But this only works in file system level.
> For cases like thin provisioning, an option full preallocation is
> added to write zeros to storage to ensure disk space.
> 
> Hu Tao (4):
>   qapi: introduce PreallocMode and a new PreallocMode full.
>   raw, qcow2: don't convert file size to sector size
>   raw-posix: Add full image preallocation option
>   qcow2: Add full image preallocation option
> 
>  block/qcow2.c  | 95 
> --
>  block/raw-posix.c  | 63 ++
>  block/raw-win32.c  |  4 +-
>  qapi-schema.json   | 14 +++
>  tests/qemu-iotests/082.out | 54 +-
>  5 files changed, 182 insertions(+), 48 deletions(-)

Kevin: You had review comments on the last revision.  Are you happy with
v8?

Stefan



Re: [Qemu-devel] Help needed testing on ppc

2014-05-06 Thread Tom Musta
On 5/6/2014 5:03 AM, BALATON Zoltan wrote:
> Hello,
> 
> As I got no reply on the qemu-ppc list so far I try here maybe there are some 
> people who read this list but don't follow the ppc one.
> 
> I don't have the necessary hardware to do the testing needed for the patch 
> below. Some context for the discussion can be found in this message: 
> http://lists.nongnu.org/archive/html/qemu-ppc/2014-04/msg00277.html
> 
> It seems we have some code that contains instructions with a reserved bit set 
> in an stwx instruction that works on real hardware but causes an invalid 
> instruction exception on QEMU.
> 
> I'd appreciate some insight and help.
> 
> Regards,
> BALATON Zoltan

This is a bit tricky.  You appear to have code that has a reserved bit set.

Early forms of the PowerPC ISA (circa 1998) said this:  "All reserved fields in 
instructions should be zero.  If they are not, the instruction form
is invalid. ...  Any attempt to execute an invalid form of an instruction will 
cause the system illegal instruction error handler to
be invoked or yield boundedly undefined results."   QEMU, as a general rule, 
meets this requirement by causing illegal instruction
exceptions.

More modern versions of the ISA (circa 2006) say this: "Reserved fields in 
instructions are ignored by the processor.  This is a requirement
in the Server environment and is being phased into the Embedded environment. 
... To maximize compatibility with future architecture
extensions, software must ensure that reserved fields in instructions contain 
zero and that defined fields of instructions do not contain
reserved values."  Technically, QEMU does not comply with the requirement in 
the first sentence;  and MorpOS does not comply with the third.

The newer form of the ISA is compatible with the older one since ignoring 
reserved fields is a valid implementation of "boundedly undefined."

A few questions and comments:

(1) Why is MorphOS using this invalid instruction form?  Would it be easier to 
fix the OS rather than QEMU?  Is there some undocumented
processor behavior that the code is dependent upon (e.g. is it actually 
expected CR0 to be set?).

(2) Your patch makes some store instructions compliant with the most recent 
ISAs but there are many other instructions that are not
addressed by the patch.  I think fixing only some will be a future source of 
confusion.

(3) The change risks breaking behavior on older designs which may very well 
have taken the illegal instruction interrupt.  Would it make more
sense to leave the masks as-is and instead make a single, isolated change in 
the decoder (gen_intermediate_code_internal).  This behavior
could be made conditional (configuration item?  processor family specific 
flag?).  Unfortunately, the masks also catch some invalid forms
that do not involve reserved fields (e.g. lq/stq to odd numbered registers).

(4) In general, modeling undefined behavior is a slippery slope.  I would much 
prefer to see the code fixed or justified before changing QEMU.









Re: [Qemu-devel] [PATCH net v1 1/1] net: xilinx_ethlite: Fix Rx-pong interrupt

2014-05-06 Thread Stefan Hajnoczi
On Mon, May 05, 2014 at 09:39:38PM -0700, Peter Crosthwaite wrote:
> There is no CTRL_I bit in the pong buffer control register. The
> CTRL_I bit from the ping buffer masks both ping and pong buffers.
> Fix.
> 
> Signed-off-by: Peter Crosthwaite 
> ---
> 
>  hw/net/xilinx_ethlite.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)

Unfamiliar with the device but the patch itself looks clean.  I'll drop
it from my queue if there are comments.

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

Stefan



Re: [Qemu-devel] [PATCH v3] glib: fix g_poll early timeout on windows

2014-05-06 Thread Stefan Hajnoczi
On Fri, Apr 18, 2014 at 08:24:03PM +0400, Stanislav Vorobiov wrote:
> From: Sangho Park 
> 
> g_poll has a problem on Windows when using
> timeouts < 10ms, in glib/gpoll.c:
> 
> /* If not, and we have a significant timeout, poll again with
>  * timeout then. Note that this will return indication for only
>  * one event, or only for messages. We ignore timeouts less than
>  * ten milliseconds as they are mostly pointless on Windows, the
>  * MsgWaitForMultipleObjectsEx() call will timeout right away
>  * anyway.
>  */
> if (retval == 0 && (timeout == INFINITE || timeout >= 10))
>   retval = poll_rest (poll_msgs, handles, nhandles, fds, nfds, timeout);
> 
> so whenever g_poll is called with timeout < 10ms it does
> a quick poll instead of wait, this causes significant performance
> degradation of QEMU, thus we should use WaitForMultipleObjectsEx
> directly
> 
> Signed-off-by: Stanislav Vorobiov 
> ---
>  include/glib-compat.h |   19 +
>  include/qemu-common.h |   12 --
>  util/oslib-win32.c|  112 
> +
>  3 files changed, 131 insertions(+), 12 deletions(-)

What is the status of this patch?

I haven't followed the discussions around the issue but can review/merge
if there is agreement now.

Stefan



Re: [Qemu-devel] [PATCH] block/raw-posix: Fall back to SEEK_HOLE/SEEK_DATA

2014-05-06 Thread Eric Blake
On 05/06/2014 05:49 AM, Stefan Hajnoczi wrote:
> On Mon, May 05, 2014 at 10:01:39PM +0200, Max Reitz wrote:
>> The current version of raw-posix always uses ioctl(FS_IOC_FIEMAP) if
>> FIEMAP is available; lseek with SEEK_HOLE/SEEK_DATA are not even
>> compiled in in this case. However, there may be implementations which
>> support the latter but not the former (e.g., NFSv4.2). In this case,
>> raw-posix should fall back to lseek with SEEK_HOLE/SEEK_DATA if FIEMAP
>> does not work.
>>

> 
> A bigger cleanup is extracting the FIEMAP and SEEK_HOLE/SEEK_DATA
> implementations into their own static functions.  Then
> raw_co_get_block_status() becomes simpler and doesn't need ifdefs:
> 
> ret = try_fiemap(...);
> if (ret < 0) {
> ret = try_seekhole(...);
> }
> if (ret < 0) {
> ...report every block allocated by default
> }
> 
> In other words, let normal C control flow describe the relationships
> between these code paths.  Use ifdef only to nop out try_fiemap() and
> try_seekhole().
> 
> What do you think?

I like the idea - separating control flow from #ifdefs (by having stubs
on the other end of the ifdef) definitely makes algorithms easier to
understand.

More things to consider: GNU Coreutils has support for both fiemap and
seek_hole, but favors seek_hole first, for a couple reasons.  First,
FIEMAP has not always been reliable: on some older kernel/filesystem
pairs, fiemap could return stale results, which led cp(1) to cause data
loss unless it did an fsync() first to get the fiemap to be stable - but
the cost of the fsync() made the operation slower than if fiemap were
never used.  Second, POSIX will be standardizing seek_hole in its next
revision [1] (still several years out, but the fact that it is an
announced intention means people are starting to implement it now).
fiemap, on the other hand, remains a Linux-only extension.  Yes, fiemap
provides more details than seek_hole (and is the ONLY way to know the
difference between a hole that has reserved space on the disk vs a hole
that will require allocation if is written to), but if all you need to
know is whether a hole exists (rather than what type of hole), then
seek_hole is MUCH simpler.

[1] http://austingroupbugs.net/view.php?id=415

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



signature.asc
Description: OpenPGP digital signature


  1   2   3   >