Compare commits

..

53 Commits

Author SHA1 Message Date
Peter Maydell
d00e6cddc2 Update version for v2.2.0-rc5 release
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-12-04 15:51:22 +00:00
Peter Maydell
54f3a180a3 Merge remote-tracking branch 'remotes/kraxel/tags/pull-cve-2014-8106-20141204-1' into staging
cirrus: fix blit region check

# gpg: Signature made Thu 04 Dec 2014 11:54:57 GMT using RSA key ID D3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>"

* remotes/kraxel/tags/pull-cve-2014-8106-20141204-1:
  cirrus: don't overflow CirrusVGAState->cirrus_bltbuf
  cirrus: fix blit region check

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-12-04 12:22:46 +00:00
Peter Maydell
0d7954c288 Update version for v2.2.0-rc4 release
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-12-01 13:35:26 +00:00
Gonglei
b19ca18802 vhost: Fix vhostfd leak in error branch
Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Message-id: 1417166789-1960-1-git-send-email-arei.gonglei@huawei.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-12-01 12:29:35 +00:00
Gerd Hoffmann
bf25983345 cirrus: don't overflow CirrusVGAState->cirrus_bltbuf
This is CVE-2014-8106.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-12-01 10:25:46 +01:00
Gerd Hoffmann
d3532a0db0 cirrus: fix blit region check
Issues:
 * Doesn't check pitches correctly in case it is negative.
 * Doesn't check width at all.

Turn macro into functions while being at it, also factor out the check
for one region which we then can simply call twice for src + dst.

This is CVE-2014-8106.

Reported-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
2014-12-01 10:25:12 +01:00
David Gibson
db12451dec Fix for crash after migration in virtio-rng on bi-endian targets
VirtIO devices now remember which endianness they're operating in in order
to support targets which may have guests of either endianness, such as
powerpc.  This endianness state is transferred in a subsection of the
virtio device's information.

With virtio-rng this can lead to an abort after a loadvm hitting the
assert() in virtio_is_big_endian().  This can be reproduced by doing a
migrate and load from file on a bi-endian target with a virtio-rng device.
The actual guest state isn't particularly important to triggering this.

The cause is that virtio_rng_load_device() calls virtio_rng_process() which
accesses the ring and thus needs the endianness.  However,
virtio_rng_process() is called via virtio_load() before it loads the
subsections.  Essentially the ->load callback in VirtioDeviceClass should
only be used for actually reading the device state from the stream, not for
post-load re-initialization.

This patch fixes the bug by moving the virtio_rng_process() after the call
to virtio_load().  Better yet would be to convert virtio to use vmsd and
have the virtio_rng_process() as a post_load callback, but that's a bigger
project for another day.

This is bugfix, and should be considered for the 2.2 branch.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Message-id: 1417067290-20715-1-git-send-email-david@gibson.dropbear.id.au
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-11-28 13:06:00 +00:00
Jason Wang
771b6ed37e virtio-net: fix unmap leak
virtio_net_handle_ctrl() and other functions that process control vq
request call iov_discard_front() which will shorten the iov. This will
lead unmapping in virtqueue_push() leaks mapping.

Fixes this by keeping the original iov untouched and using a temp variable
in those functions.

Cc: Wen Congyang <wency@cn.fujitsu.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Message-id: 1417082643-23907-1-git-send-email-jasowang@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-11-28 10:29:20 +00:00
Marcel Apfelbaum
4cae4d5aca hmp: fix regression of HMP device_del auto-completion
The commits:
 - 6a1fa9f5 (monitor: add del completion for peripheral device)
 - 66e56b13 (qdev: add qdev_build_hotpluggable_device_list helper)

cause a QEMU crash when trying to use HMP device_del auto-completion.
It can be easily reproduced by:
    <qemu-bin> -enable-kvm  ~/images/fedora.qcow2 -monitor stdio -device virtio-net-pci,id=vnet

    (qemu) device_del
    /home/mapfelba/git/upstream/qemu/hw/core/qdev.c:941:qdev_build_hotpluggable_device_list: Object 0x7f6ce04e4fe0 is not an instance of type device
    Aborted (core dumped)

The root cause is qdev_build_hotpluggable_device_list going recursively over
all peripherals and their children assuming all are devices. It doesn't work
since PCI devices have at least on child which is a memory region (bus master).

Solved by observing that all devices appear as direct children of
/machine/peripheral container. No need of going recursively
over all the children.

Signed-off-by: Marcel Apfelbaum <marcel.a@redhat.com>
Reported-by: Gal Hammer <ghammer@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Message-id: 1417002601-20799-1-git-send-email-marcel.a@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-11-27 14:36:20 +00:00
Peter Maydell
490309fcfb qemu-timer: Avoid overflows when converting timeout to struct timespec
In qemu_poll_ns(), when we convert an int64_t nanosecond timeout into
a struct timespec, we may accidentally run into overflow problems if
the timeout is very long. This happens because the tv_sec field is a
time_t, which is signed, so we might end up setting it to a negative
value by mistake. This will result in what was intended to be a
near-infinite timeout turning into an instantaneous timeout, and we'll
busy loop. Cap the maximum timeout at INT32_MAX seconds (about 68 years)
to avoid this problem.

This specifically manifested on ARM hosts as an extreme slowdown on
guest shutdown (when the guest reprogrammed the PL031 RTC to not
generate alarms using a very long timeout) but could happen on other
hosts and guests too.

Reported-by: Christoffer Dall <christoffer.dall@linaro.org>
Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Fam Zheng <famz@redhat.com>
Message-id: 1416939705-1272-1-git-send-email-peter.maydell@linaro.org
2014-11-27 11:31:58 +00:00
Peter Maydell
3ef4ebcc5c Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
The final 2.2 patches from me.

# gpg: Signature made Wed 26 Nov 2014 11:12:25 GMT using RSA key ID 78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>"
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>"
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg:          It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* remotes/bonzini/tags/for-upstream:
  s390x/kvm: Fix compile error
  fw_cfg: fix boot order bug when dynamically modified via QOM
  -machine vmport=auto: Fix handling of VMWare ioport emulation for xen

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-11-26 12:18:00 +00:00
Christian Borntraeger
dc622deb2d s390x/kvm: Fix compile error
commit a2b257d621 "memory: expose alignment used for allocating RAM
as MemoryRegion API" triggered a compile error on KVM/s390x.

Fix the prototype and the implementation of legacy_s390_alloc.

Cc: Igor Mammedov <imammedo@redhat.com>
Cc: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-11-26 12:11:27 +01:00
Gonglei
f3b3766899 fw_cfg: fix boot order bug when dynamically modified via QOM
When we dynamically modify boot order, the length of
boot order will be changed, but we don't update
s->files->f[i].size with new length. This casuse
seabios read a wrong vale of qemu cfg file about
bootorder.

Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-11-26 12:11:27 +01:00
Don Slutz
d1048bef9d -machine vmport=auto: Fix handling of VMWare ioport emulation for xen
c/s 9b23cfb76b

or

c/s b154537ad0

moved the testing of xen_enabled() from pc_init1() to
pc_machine_initfn().

xen_enabled() does not return the correct value in
pc_machine_initfn().

Changed vmport from a bool to an enum.  Added the value "auto" to do
the old way.  Move check of xen_enabled() back to pc_init1().

Acked-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Don Slutz <dslutz@verizon.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-11-26 12:11:27 +01:00
Peter Maydell
2528043f1f Update version for v2.2.0-rc3 release
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-11-25 18:23:54 +00:00
Gerd Hoffmann
df5b2adb73 input: move input-send-event into experimental namespace
Ongoing discussions on how we are going to specify the console,
so tag the command as experiental so we can refine things in
the 2.3 development cycle.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 1416923657-10614-1-git-send-email-armbru@redhat.com
[Spell out "not a stable API", and x- the QAPI schema, too]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Amos Kong <akong@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-11-25 17:03:31 +00:00
Peter Maydell
ca6028185d Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
pc, pci, misc bugfixes

A bunch of bugfixes for 2.2.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

# gpg: Signature made Mon 24 Nov 2014 18:59:47 GMT using RSA key ID D28D5469
# gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>"
# gpg:                 aka "Michael S. Tsirkin <mst@redhat.com>"

* remotes/mst/tags/for_upstream:
  pc: acpi: mark all possible CPUs as enabled in SRAT
  pcie: fix improper use of negative value
  pcie: fix typo in pcie_cap_deverr_init()
  target-i386: move generic memory hotplug methods to DSDTs
  acpi-build: mark RAM dirty on table update
  hw/pci: fix crash on shpc error flow
  pc: count in 1Gb hugepage alignment when sizing hotplug-memory container
  pc: explicitly check maxmem limit when adding DIMM
  pc: pc-dimm: use backend alignment during address auto allocation
  pc: align DIMM's address/size by backend's alignment value
  memory: expose alignment used for allocating RAM as MemoryRegion API
  pc: limit DIMM address and size to page aligned values
  pc: make pc_dimm_plug() more readble
  pc: kvm: check if KVM has free memory slots to avoid abort()
  qemu-char: fix tcp_get_fds

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-11-24 19:31:50 +00:00
Igor Mammedov
dd0247e09a pc: acpi: mark all possible CPUs as enabled in SRAT
If QEMU is started with  -numa ... Windows only notices that
CPU has been hot-added but it will not online such CPUs.

It's caused by the fact that possible CPUs are flagged as
not enabled in SRAT and Windows honoring that information
doesn't use corresponding CPU.

ACPI 5.0 Spec regarding to flag says:
"
Table 5-47 Local APIC Flags
...
Enabled: if zero, this processor is unusable, and the operating system
support will not attempt to use it.
"

Fix QEMU to adhere to spec and mark possible CPUs as enabled
in SRAT.

With that Windows onlines hot-added CPUs as expected.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-11-24 20:57:11 +02:00
Gonglei
6c150fbd34 pcie: fix improper use of negative value
Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-11-24 20:57:11 +02:00
Gonglei
8e815eeefe pcie: fix typo in pcie_cap_deverr_init()
Reported-by:
 https://bugs.launchpad.net/qemu/+bug/1393440

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-11-24 20:57:10 +02:00
Paolo Bonzini
4f99ab7a78 target-i386: move generic memory hotplug methods to DSDTs
This makes it simpler to keep the SSDT byte-for-byte identical for a
given machine type, which is a goal we want to have for 2.2 and newer
types.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-11-24 20:57:10 +02:00
Michael S. Tsirkin
ad5b88b1f1 acpi-build: mark RAM dirty on table update
acpi build modifies internal FW CFG RAM on first access
but we forgot to mark it dirty.
If this RAM has been migrated already, it won't be
migrated again, returning corrupted tables to guest.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-11-24 20:57:10 +02:00
Marcel Apfelbaum
109e90e470 hw/pci: fix crash on shpc error flow
If the pci bridge enters in error flow as part
of init process it will only delete the shpc mmio
subregion but not remove it from the properties list,
resulting in segmentation fault when the bridge runs
the exit function.

Example: add a pci bridge without specifing the chassis number:
    <qemu-bin> ... -device pci-bridge,id=p1
Result:
    (qemu) qemu-system-x86_64: -device pci-bridge,id=p1: Bridge chassis not specified. Each bridge is required to be assigned a unique chassis id > 0.
    qemu-system-x86_64: -device pci-bridge,id=p1: Device
    initialization failed.
    Segmentation fault (core dumped)

    if (child->class->unparent) {
    #0  0x00005555558d629b in object_finalize_child_property (obj=0x555556d2e830, name=0x555556d30630 "shpc-mmio[0]", opaque=0x555556a42fc8) at qom/object.c:1078
    #1  0x00005555558d4b1f in object_property_del_all (obj=0x555556d2e830) at qom/object.c:367
    #2  0x00005555558d4ca1 in object_finalize (data=0x555556d2e830) at qom/object.c:412
    #3  0x00005555558d55a1 in object_unref (obj=0x555556d2e830) at qom/object.c:720
    #4  0x000055555572c907 in qdev_device_add (opts=0x5555563544f0) at qdev-monitor.c:566
    #5  0x0000555555744f16 in device_init_func (opts=0x5555563544f0, opaque=0x0) at vl.c:2213
    #6  0x00005555559cf5f0 in qemu_opts_foreach (list=0x555555e0f8e0 <qemu_device_opts>, func=0x555555744efa <device_init_func>, opaque=0x0, abort_on_failure=1) at util/qemu-option.c:1057
    #7  0x000055555574a11b in main (argc=16, argv=0x7fffffffdde8, envp=0x7fffffffde70) at vl.c:423

Unparent the shpc mmio region as part of shpc cleanup.

Signed-off-by: Marcel Apfelbaum <marcel.a@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Amos Kong <akong@redhat.com>
2014-11-24 20:57:10 +02:00
Igor Mammedov
085f8e88ba pc: count in 1Gb hugepage alignment when sizing hotplug-memory container
if DIMMs with different size/alignment are interleaved
in creation order, it could lead to hotplug-memory
container fragmentation and following inability to use
all RAM upto maxmem.
For example:
    -m 4G,slots=3,maxmem=7G
    -object memory-backend-file,id=mem-1,size=256M,mem-path=/pagesize-2MB
    -device pc-dimm,id=mem1,memdev=mem-1
    -object memory-backend-file,id=mem-2,size=1G,mem-path=/pagesize-1GB
    -device pc-dimm,id=mem2,memdev=mem-2
    -object memory-backend-file,id=mem-3,size=256M,mem-path=/pagesize-2MB
    -device pc-dimm,id=mem3,memdev=mem-3

fragments hotplug-memory container and doesn't allow
to use 1GB hugepage backend to consume remainig 1Gb.

To ease managment factor count in max 1Gb alignment for
each memory slot when sizing hotplug-memory region so
that regadless of fragmentaion it would be possible to
add max aligned DIMM.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-11-24 20:57:10 +02:00
Igor Mammedov
b03541fa77 pc: explicitly check maxmem limit when adding DIMM
Currently maxmem limit is not checked and depends on
hotplug region container not being able to fit more RAM
than maxmem. Do check explicitly so that it would
be possible to change hotplug container size later
to deal with fragmentation.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-11-24 20:57:10 +02:00
Peter Maydell
3d4a70f80f Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block patches for 2.2.0-rc3

# gpg: Signature made Mon 24 Nov 2014 12:52:23 GMT using RSA key ID C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"

* remotes/kevin/tags/for-upstream:
  Revert "qemu-img info: show nocow info"

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-11-24 15:01:54 +00:00
Peter Maydell
a31a7475e9 Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
Three patches to fix ExtINT for the QEMU implementation of the local APIC.

# gpg: Signature made Mon 24 Nov 2014 13:38:36 GMT using RSA key ID 78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>"
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>"
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg:          It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* remotes/bonzini/tags/for-upstream:
  apic: fix incorrect handling of ExtINT interrupts wrt processor priority
  apic: fix loss of IPI due to masked ExtINT
  apic: avoid getting out of halted state on masked PIC interrupts

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-11-24 13:50:22 +00:00
Paolo Bonzini
5224c88dd3 apic: fix incorrect handling of ExtINT interrupts wrt processor priority
This fixes another failure with ExtINT, demonstrated by QNX.  The failure
mode is as follows:
- IPI sent to cpu 0 (bit set in APIC irr)
- IPI accepted by cpu 0 (bit cleared in irr, set in isr)
- IPI sent to cpu 0 (bit set in both irr and isr)
- PIC interrupt sent to cpu 0

The PIC interrupt causes CPU_INTERRUPT_HARD to be set, but
apic_irq_pending observes that the highest pending APIC interrupt priority
(the IPI) is the same as the processor priority (since the IPI is still
being handled), so apic_get_interrupt returns a spurious interrupt rather
than the pending PIC interrupt. The result is an endless sequence of
spurious interrupts, since nothing will clear CPU_INTERRUPT_HARD.

Instead, ExtINT interrupts should have ignored the processor priority.
Calling apic_check_pic early in apic_get_interrupt ensures that
apic_deliver_pic_intr is called instead of delivering the spurious
interrupt.  apic_deliver_pic_intr then clears CPU_INTERRUPT_HARD if needed.

Reported-by: Richard Bilson <rbilson@qnx.com>
Tested-by: Richard Bilson <rbilson@qnx.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-11-24 14:37:45 +01:00
Paolo Bonzini
8092cb7132 apic: fix loss of IPI due to masked ExtINT
This patch fixes an obscure failure of the QNX kernel on QEMU x86 SMP.
In QNX, all hardware interrupts come via the PIC, and are delivered by
the cpu 0 LAPIC in ExtINT mode, while IPIs are delivered by the LAPIC
in fixed mode.

This bug happens as follows:
- cpu 0 masks a particular PIC interrupt
- IPI sent to cpu 0 (CPU_INTERRUPT_HARD is set)
- before the IPI is accepted, the masked interrupt line is asserted by the
device

Since the interrupt is masked, apic_deliver_pic_intr will clear
CPU_INTERRUPT_HARD. The IPI will still be set in the APIC irr, but since
CPU_INTERRUPT_HARD is not set the cpu will not notice. Depending on the
scenario this can cause a system hang, i.e. if cpu 0 is expected to unmask
the interrupt.

In order to fix this, do a full check of the APIC before an EXTINT
is acknowledged.  This can result in clearing CPU_INTERRUPT_HARD, but
can also result in delivering the lost IPI.

Reported-by: Richard Bilson <rbilson@qnx.com>
Tested-by: Richard Bilson <rbilson@qnx.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-11-24 14:37:40 +01:00
Paolo Bonzini
60e68042cf apic: avoid getting out of halted state on masked PIC interrupts
After the next patch, if a masked PIC interrupts causes CPU_INTERRUPT_POLL
to be set, the CPU will spuriously get out of halted state.  While this
is technically valid, we should avoid that.

Make CPU_INTERRUPT_POLL run apic_update_irq in the right thread and then
look at CPU_INTERRUPT_HARD.  If CPU_INTERRUPT_HARD does not get set,
do not report the CPU as having work.

Also move the handling of software-disabled APIC from apic_update_irq
to apic_irq_pending, and always trigger CPU_INTERRUPT_POLL.  This will
be important once we will add a case that resets CPU_INTERRUPT_HARD
from apic_update_irq.  We want to run it even if we go through
CPU_INTERRUPT_POLL, and even if the local APIC is software disabled.

Reported-by: Richard Bilson <rbilson@qnx.com>
Tested-by: Richard Bilson <rbilson@qnx.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-11-24 14:37:30 +01:00
Kevin Wolf
24bf10dac3 Revert "qemu-img info: show nocow info"
This reverts commit 000c4dfff4.

The main reason for reverting this commit before the 2.2 release is that
it adds a QAPI interface that we don't want to keep: The 'nocow' flag
doesn't generally make sense for block nodes, but only for the raw-posix
driver. It should therefore be part of ImageInfoSpecific rather than
ImageInfo.

The commit contains more problems, but unlike the API stability issue
they wouldn't justify reverting it.

Conflicts:
	block/qapi.c

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-11-24 13:52:10 +01:00
Igor Mammedov
0c0de1b681 pc: pc-dimm: use backend alignment during address auto allocation
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-11-23 12:12:46 +02:00
Igor Mammedov
91aa70ab2a pc: align DIMM's address/size by backend's alignment value
Performance wise it's better to align GVA by the backend's
page size.

Also do not allow to create DIMM device with suboptimal
size (i.e. not aligned to backends page size) to aviod
memory loss.

Do above only for 2.2 and newer machine types to avoid
breaking working configs with 2.1 machine type.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-11-23 12:12:39 +02:00
Igor Mammedov
a2b257d621 memory: expose alignment used for allocating RAM as MemoryRegion API
introduce memory_region_get_alignment() that returns
underlying memory block alignment or 0 if it's not
relevant/implemented for backend.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-11-23 12:11:30 +02:00
Igor Mammedov
92a37a04d6 pc: limit DIMM address and size to page aligned values
When running in KVM mode, kvm_set_phys_mem() will silently
fail if registered MemoryRegion address/size is not page
aligned. Causing memory hotplug failure in guest.

Mapping non aligned MemoryRegion in TCG mode 'works', but
sane guest OS still expects page aligned memory module
and fails to initialize it if it's not aligned.

So do not allow non aligned (i.e. valid) address/size
values for DIMM to avoid either KVM failure or guest
issues caused by it.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-11-23 12:11:30 +02:00
Igor Mammedov
34dde13685 pc: make pc_dimm_plug() more readble
split addr initialization from declaration so that
later when new local vars are added property getter
wouldn't drift off of error check.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-11-23 12:11:30 +02:00
Igor Mammedov
b8865591d4 pc: kvm: check if KVM has free memory slots to avoid abort()
When more memory devices are used than available
KVM memory slots, QEMU crashes with:

kvm_alloc_slot: no free slot available
Aborted (core dumped)

Fix this by checking that KVM has a free slot before
attempting to map memory in guest address space.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-11-23 12:11:29 +02:00
Michael S. Tsirkin
c409572678 qemu-char: fix tcp_get_fds
tcp_get_fds API discards fds if there's more than 1 of these.

It's tricky to fix this without API changes in the generic case.

However, this API is only used by tests ATM, and tests know how
many fds they expect.

So let's not waste cycles trying to fix this properly:
simply assume at most 16 fds (tests use at most 8 now).
assert if some test tries to get more.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-11-23 12:11:29 +02:00
Peter Maydell
0e88f47850 Merge remote-tracking branch 'remotes/stefanha/tags/net-pull-request' into staging
# gpg: Signature made Fri 21 Nov 2014 11:12:37 GMT using RSA key ID 81AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg:                 aka "Stefan Hajnoczi <stefanha@gmail.com>"

* remotes/stefanha/tags/net-pull-request:
  rtl8139: fix Pointer to local outside scope
  pcnet: fix Negative array index read
  net/socket: fix Uninitialized scalar variable
  net/slirp: fix memory leak

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-11-21 14:15:37 +00:00
Peter Maydell
a00c117338 Merge remote-tracking branch 'remotes/kraxel/tags/pull-gtk-20141121-1' into staging
gtk: two bugfixes for 2.2.

# gpg: Signature made Fri 21 Nov 2014 07:38:45 GMT using RSA key ID D3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>"

* remotes/kraxel/tags/pull-gtk-20141121-1:
  gtk: Don't crash if -nodefaults
  gtk: fix possible memory leak about local_err

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-11-21 13:22:18 +00:00
Gonglei
b0af844007 rtl8139: fix Pointer to local outside scope
Coverity spot:
 Assigning: iov = struct iovec [3]({{buf, 12UL},
                       {(void *)dot1q_buf, 4UL},
                       {buf + 12, size - 12}})
 (address of temporary variable of type struct iovec [3]).
 out_of_scope: Temporary variable of type struct iovec [3] goes out of scope.

Pointer to local outside scope (RETURN_LOCAL)
use_invalid:
 Using iov, which points to an out-of-scope temporary variable of type struct iovec [3].

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-11-21 10:50:54 +00:00
Gonglei
7b50d00911 pcnet: fix Negative array index read
s->xmit_pos maybe assigned to a negative value (-1),
but in this branch variable s->xmit_pos as an index to
array s->buffer. Let's add a check for s->xmit_pos.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-11-21 10:50:54 +00:00
Gonglei
8db804ac41 net/socket: fix Uninitialized scalar variable
If is_connected parameter is false, the saddr
variable will no initialize. Coverity report:
uninit_use: Using uninitialized value saddr.sin_port.

We don't need add saddr information to nc->info_str
when is_connected is false.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-11-21 10:50:54 +00:00
Gonglei
7a8919dc29 net/slirp: fix memory leak
commit b412eb61 introduce 'cmd:' target for guestfwd,
and fwd don't be used in this scenario, and will leak
memory in true branch with 'cmd:'. Let's allocate memory
for fwd variable just in else statement.

Cc: Alexander Graf <agraf@suse.de>
Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-11-21 10:50:54 +00:00
Fam Zheng
b310a2a609 gtk: Don't crash if -nodefaults
This fixes a crash by just skipping the vte resize hack if cur is NULL.

Reproducer:

qemu-system-x86_64 -nodefaults

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-11-21 08:37:59 +01:00
zhanghailiang
8a0f9b5263 gtk: fix possible memory leak about local_err
local_err in gd_vc_gfx_init() is not freed, and we don't use it,
so remove it.

Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-11-21 08:37:59 +01:00
Leif Lindholm
9c7074da5e hw/arm/virt: set stdout-path instead of linux,stdout-path
ePAPR 1.1 defines the stdout-path property, making the os-specific
linux,stdout-path property redundant. Change the DT setup for ARM virt
to use the generic property - supported by Linux since 3.15.

The old QEMU behaviour was not present in any released version of
QEMU, and was only added to QEMU after the kernel changed, so
this should not break any existing setups.

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
[PMM: add note to commit about the old behaviour never hving been
in a released version of QEMU]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-11-20 14:58:37 +00:00
Peter Maydell
ff323a6b54 Merge remote-tracking branch 'remotes/agraf/tags/signed-ppc-for-upstream' into staging
Patch queue for ppc - 2014-11-20

Hopefully the last few fixups for 2.2:

  - KVM memory slot fix (should usually only occur on PPC)
  - e300 fix
  - Altivec mtvscr instruction fix

# gpg: Signature made Thu 20 Nov 2014 13:53:34 GMT using RSA key ID 03FEDC60
# gpg: Good signature from "Alexander Graf <agraf@suse.de>"
# gpg:                 aka "Alexander Graf <alex@csgraf.de>"

* remotes/agraf/tags/signed-ppc-for-upstream:
  target-ppc: Altivec's mtvscr Decodes Wrong Register
  kvm: Fix memory slot page alignment logic
  target-ppc: Fix breakpoint registers for e300

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-11-20 14:02:24 +00:00
Tom Musta
76cb658419 target-ppc: Altivec's mtvscr Decodes Wrong Register
The Move to Vector Status and Control Register (mtvscr) instruction
uses VRB as the source register.  Fix the code generator to correctly
decode the VRB field.  That is, use "rB(ctx->opcode)" instead of
"rD(ctx->opcode)".

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-11-20 14:52:01 +01:00
Alexander Graf
f2a64032a1 kvm: Fix memory slot page alignment logic
Memory slots have to be page aligned to get entered into KVM. There
is existing logic that tries to ensure that we pad memory slots that
are not page aligned to the biggest region that would still fit in the
alignment requirements.

Unfortunately, that logic is broken. It tries to calculate the start
offset based on the region size.

Fix up the logic to do the thing it was intended to do and document it
properly in the comment above it.

With this patch applied, I can successfully run an e500 guest with more
than 3GB RAM (at which point RAM starts overlapping subpage memory regions).

Cc: qemu-stable@nongnu.org
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-11-20 14:52:01 +01:00
Fabien Chouteau
3ade1a055c target-ppc: Fix breakpoint registers for e300
In the previous patch, the registers were added to init_proc_G2LE
instead of init_proc_e300.

Signed-off-by: Fabien Chouteau <chouteau@adacore.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-11-20 14:52:01 +01:00
Peter Maydell
f75ad80f6c Merge remote-tracking branch 'remotes/amit-migration/tags/for-2.2-2' into staging
Fix from a while back that unfortunately got ignored.  Dave Gilbert says
it may actually fix a case where autoconverge would break on a repeat
migration (and not just fix stats).

# gpg: Signature made Thu 20 Nov 2014 12:52:41 GMT using RSA key ID 854083B6
# gpg: Good signature from "Amit Shah <amit@amitshah.net>"
# gpg:                 aka "Amit Shah <amit@kernel.org>"
# gpg:                 aka "Amit Shah <amitshah@gmx.net>"

* remotes/amit-migration/tags/for-2.2-2:
  migration: static variables will not be reset at second migration

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-11-20 13:00:28 +00:00
ChenLiang
6c1b663c4c migration: static variables will not be reset at second migration
The static variables in migration_bitmap_sync will not be reset in
the case of a second attempted migration.

Signed-off-by: ChenLiang <chenliang88@huawei.com>
Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Amit Shah <amit.shah@redhat.com>
2014-11-20 18:17:22 +05:30
65 changed files with 2233 additions and 1208 deletions

View File

@@ -1 +1 @@
2.1.92
2.1.95

View File

@@ -486,15 +486,23 @@ static void migration_bitmap_sync_range(ram_addr_t start, ram_addr_t length)
/* Needs iothread lock! */
/* Fix me: there are too many global variables used in migration process. */
static int64_t start_time;
static int64_t bytes_xfer_prev;
static int64_t num_dirty_pages_period;
static void migration_bitmap_sync_init(void)
{
start_time = 0;
bytes_xfer_prev = 0;
num_dirty_pages_period = 0;
}
static void migration_bitmap_sync(void)
{
RAMBlock *block;
uint64_t num_dirty_pages_init = migration_dirty_pages;
MigrationState *s = migrate_get_current();
static int64_t start_time;
static int64_t bytes_xfer_prev;
static int64_t num_dirty_pages_period;
int64_t end_time;
int64_t bytes_xfer_now;
static uint64_t xbzrle_cache_miss_prev;
@@ -774,6 +782,7 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
mig_throttle_on = false;
dirty_rate_high_cnt = 0;
bitmap_sync_count = 0;
migration_bitmap_sync_init();
if (migrate_use_xbzrle()) {
XBZRLE_cache_lock();

View File

@@ -29,13 +29,6 @@
#include "qapi/qmp-output-visitor.h"
#include "qapi/qmp/types.h"
#include "sysemu/block-backend.h"
#ifdef __linux__
#include <linux/fs.h>
#include <sys/ioctl.h>
#ifndef FS_NOCOW_FL
#define FS_NOCOW_FL 0x00800000 /* Do not cow file */
#endif
#endif
BlockDeviceInfo *bdrv_block_device_info(BlockDriverState *bs)
{
@@ -180,9 +173,6 @@ void bdrv_query_image_info(BlockDriverState *bs,
int ret;
Error *err = NULL;
ImageInfo *info;
#ifdef __linux__
int fd, attr;
#endif
size = bdrv_getlength(bs);
if (size < 0) {
@@ -212,18 +202,6 @@ void bdrv_query_image_info(BlockDriverState *bs,
info->format_specific = bdrv_get_specific_info(bs);
info->has_format_specific = info->format_specific != NULL;
#ifdef __linux__
/* get NOCOW info */
fd = qemu_open(bs->filename, O_RDONLY | O_NONBLOCK);
if (fd >= 0) {
if (ioctl(fd, FS_IOC_GETFLAGS, &attr) == 0 && (attr & FS_NOCOW_FL)) {
info->has_nocow = true;
info->nocow = true;
}
qemu_close(fd);
}
#endif
backing_filename = bs->backing_file;
if (backing_filename[0] != '\0') {
info->backing_filename = g_strdup(backing_filename);
@@ -655,8 +633,4 @@ void bdrv_image_info_dump(fprintf_function func_fprintf, void *f,
func_fprintf(f, "Format specific information:\n");
bdrv_image_info_specific_dump(func_fprintf, f, info->format_specific);
}
if (info->has_nocow && info->nocow) {
func_fprintf(f, "NOCOW flag: set\n");
}
}

9
exec.c
View File

@@ -909,14 +909,15 @@ static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
uint16_t section);
static subpage_t *subpage_init(AddressSpace *as, hwaddr base);
static void *(*phys_mem_alloc)(size_t size) = qemu_anon_ram_alloc;
static void *(*phys_mem_alloc)(size_t size, uint64_t *align) =
qemu_anon_ram_alloc;
/*
* Set a custom physical guest memory alloator.
* Accelerators with unusual needs may need this. Hopefully, we can
* get rid of it eventually.
*/
void phys_mem_set_alloc(void *(*alloc)(size_t))
void phys_mem_set_alloc(void *(*alloc)(size_t, uint64_t *align))
{
phys_mem_alloc = alloc;
}
@@ -1098,6 +1099,7 @@ static void *file_ram_alloc(RAMBlock *block,
error_propagate(errp, local_err);
goto error;
}
block->mr->align = hpagesize;
if (memory < hpagesize) {
error_setg(errp, "memory size 0x" RAM_ADDR_FMT " must be equal to "
@@ -1309,7 +1311,8 @@ static ram_addr_t ram_block_add(RAMBlock *new_block, Error **errp)
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);
new_block->host = phys_mem_alloc(new_block->length,
&new_block->mr->align);
if (!new_block->host) {
error_setg_errno(errp, errno,
"cannot set up guest memory '%s'",

View File

@@ -389,7 +389,7 @@ static void create_uart(const VirtBoardInfo *vbi, qemu_irq *pic)
qemu_fdt_setprop(vbi->fdt, nodename, "clock-names",
clocknames, sizeof(clocknames));
qemu_fdt_setprop_string(vbi->fdt, "/chosen", "linux,stdout-path", nodename);
qemu_fdt_setprop_string(vbi->fdt, "/chosen", "stdout-path", nodename);
g_free(nodename);
}

View File

@@ -811,12 +811,12 @@ err:
return -1;
}
void *rom_add_blob(const char *name, const void *blob, size_t len,
ram_addr_t rom_add_blob(const char *name, const void *blob, size_t len,
hwaddr addr, const char *fw_file_name,
FWCfgReadCallback fw_callback, void *callback_opaque)
{
Rom *rom;
void *data = NULL;
ram_addr_t ret = RAM_ADDR_MAX;
rom = g_malloc0(sizeof(*rom));
rom->name = g_strdup(name);
@@ -828,11 +828,13 @@ void *rom_add_blob(const char *name, const void *blob, size_t len,
rom_insert(rom);
if (fw_file_name && fw_cfg) {
char devpath[100];
void *data;
snprintf(devpath, sizeof(devpath), "/rom@%s", fw_file_name);
if (rom_file_has_mr) {
data = rom_set_mr(rom, OBJECT(fw_cfg), devpath);
ret = memory_region_get_ram_addr(rom->mr);
} else {
data = rom->data;
}
@@ -841,7 +843,7 @@ void *rom_add_blob(const char *name, const void *blob, size_t len,
fw_callback, callback_opaque,
data, rom->romsize);
}
return data;
return ret;
}
/* This function is specific for elf program because we don't need to allocate

View File

@@ -935,7 +935,7 @@ void qdev_alias_all_properties(DeviceState *target, Object *source)
} while (class != object_class_by_name(TYPE_DEVICE));
}
int qdev_build_hotpluggable_device_list(Object *obj, void *opaque)
static int qdev_add_hotpluggable_device(Object *obj, void *opaque)
{
GSList **list = opaque;
DeviceState *dev = DEVICE(obj);
@@ -944,10 +944,18 @@ int qdev_build_hotpluggable_device_list(Object *obj, void *opaque)
*list = g_slist_append(*list, dev);
}
object_child_foreach(obj, qdev_build_hotpluggable_device_list, opaque);
return 0;
}
GSList *qdev_build_hotpluggable_device_list(Object *peripheral)
{
GSList *list = NULL;
object_child_foreach(peripheral, qdev_add_hotpluggable_device, &list);
return list;
}
static bool device_get_realized(Object *obj, Error **errp)
{
DeviceState *dev = DEVICE(obj);

View File

@@ -173,20 +173,6 @@
#define CIRRUS_PNPMMIO_SIZE 0x1000
#define BLTUNSAFE(s) \
( \
( /* check dst is within bounds */ \
(s)->cirrus_blt_height * ABS((s)->cirrus_blt_dstpitch) \
+ ((s)->cirrus_blt_dstaddr & (s)->cirrus_addr_mask) > \
(s)->vga.vram_size \
) || \
( /* check src is within bounds */ \
(s)->cirrus_blt_height * ABS((s)->cirrus_blt_srcpitch) \
+ ((s)->cirrus_blt_srcaddr & (s)->cirrus_addr_mask) > \
(s)->vga.vram_size \
) \
)
struct CirrusVGAState;
typedef void (*cirrus_bitblt_rop_t) (struct CirrusVGAState *s,
uint8_t * dst, const uint8_t * src,
@@ -279,6 +265,50 @@ static void cirrus_update_memory_access(CirrusVGAState *s);
*
***************************************/
static bool blit_region_is_unsafe(struct CirrusVGAState *s,
int32_t pitch, int32_t addr)
{
if (pitch < 0) {
int64_t min = addr
+ ((int64_t)s->cirrus_blt_height-1) * pitch;
int32_t max = addr
+ s->cirrus_blt_width;
if (min < 0 || max >= s->vga.vram_size) {
return true;
}
} else {
int64_t max = addr
+ ((int64_t)s->cirrus_blt_height-1) * pitch
+ s->cirrus_blt_width;
if (max >= s->vga.vram_size) {
return true;
}
}
return false;
}
static bool blit_is_unsafe(struct CirrusVGAState *s)
{
/* should be the case, see cirrus_bitblt_start */
assert(s->cirrus_blt_width > 0);
assert(s->cirrus_blt_height > 0);
if (s->cirrus_blt_width > CIRRUS_BLTBUFSIZE) {
return true;
}
if (blit_region_is_unsafe(s, s->cirrus_blt_dstpitch,
s->cirrus_blt_dstaddr & s->cirrus_addr_mask)) {
return true;
}
if (blit_region_is_unsafe(s, s->cirrus_blt_srcpitch,
s->cirrus_blt_srcaddr & s->cirrus_addr_mask)) {
return true;
}
return false;
}
static void cirrus_bitblt_rop_nop(CirrusVGAState *s,
uint8_t *dst,const uint8_t *src,
int dstpitch,int srcpitch,
@@ -636,7 +666,7 @@ static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s,
dst = s->vga.vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask);
if (BLTUNSAFE(s))
if (blit_is_unsafe(s))
return 0;
(*s->cirrus_rop) (s, dst, src,
@@ -654,8 +684,9 @@ static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop)
{
cirrus_fill_t rop_func;
if (BLTUNSAFE(s))
if (blit_is_unsafe(s)) {
return 0;
}
rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
rop_func(s, s->vga.vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
s->cirrus_blt_dstpitch,
@@ -752,7 +783,7 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
{
if (BLTUNSAFE(s))
if (blit_is_unsafe(s))
return 0;
cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->vga.start_addr,

View File

@@ -56,6 +56,7 @@
#include "qapi/qmp/qint.h"
#include "qom/qom-qobject.h"
#include "exec/ram_addr.h"
/* These are used to size the ACPI tables for -M pc-i440fx-1.7 and
* -M pc-i440fx-2.0. Even if the actual amount of AML generated grows
@@ -1269,8 +1270,7 @@ acpi_build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base,
}
static void
build_srat(GArray *table_data, GArray *linker,
AcpiCpuInfo *cpu, PcGuestInfo *guest_info)
build_srat(GArray *table_data, GArray *linker, PcGuestInfo *guest_info)
{
AcpiSystemResourceAffinityTable *srat;
AcpiSratProcessorAffinity *core;
@@ -1300,11 +1300,7 @@ build_srat(GArray *table_data, GArray *linker,
core->proximity_lo = curnode;
memset(core->proximity_hi, 0, 3);
core->local_sapic_eid = 0;
if (test_bit(i, cpu->found_cpus)) {
core->flags = cpu_to_le32(1);
} else {
core->flags = cpu_to_le32(0);
}
core->flags = cpu_to_le32(1);
}
@@ -1511,7 +1507,7 @@ static inline void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
typedef
struct AcpiBuildState {
/* Copy of table in RAM (for patching). */
uint8_t *table_ram;
ram_addr_t table_ram;
uint32_t table_size;
/* Is table patched? */
uint8_t patched;
@@ -1622,7 +1618,7 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
}
if (guest_info->numa_nodes) {
acpi_add_table(table_offsets, tables->table_data);
build_srat(tables->table_data, tables->linker, &cpu, guest_info);
build_srat(tables->table_data, tables->linker, guest_info);
}
if (acpi_get_mcfg(&mcfg)) {
acpi_add_table(table_offsets, tables->table_data);
@@ -1716,9 +1712,12 @@ static void acpi_build_update(void *build_opaque, uint32_t offset)
acpi_build(build_state->guest_info, &tables);
assert(acpi_data_len(tables.table_data) == build_state->table_size);
memcpy(build_state->table_ram, tables.table_data->data,
memcpy(qemu_get_ram_ptr(build_state->table_ram), tables.table_data->data,
build_state->table_size);
cpu_physical_memory_set_dirty_range_nocode(build_state->table_ram,
build_state->table_size);
acpi_build_tables_cleanup(&tables, true);
}
@@ -1728,7 +1727,7 @@ static void acpi_build_reset(void *build_opaque)
build_state->patched = 0;
}
static void *acpi_add_rom_blob(AcpiBuildState *build_state, GArray *blob,
static ram_addr_t acpi_add_rom_blob(AcpiBuildState *build_state, GArray *blob,
const char *name)
{
return rom_add_blob(name, blob->data, acpi_data_len(blob), -1, name,
@@ -1777,6 +1776,7 @@ void acpi_setup(PcGuestInfo *guest_info)
/* Now expose it all to Guest */
build_state->table_ram = acpi_add_rom_blob(build_state, tables.table_data,
ACPI_BUILD_TABLE_FILE);
assert(build_state->table_ram != RAM_ADDR_MAX);
build_state->table_size = acpi_data_len(tables.table_data);
acpi_add_rom_blob(NULL, tables.linker, "etc/table-loader");

View File

@@ -0,0 +1,176 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License along
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
External(MEMORY_SLOT_NOTIFY_METHOD, MethodObj)
Scope(\_SB.PCI0) {
Device(MEMORY_HOTPLUG_DEVICE) {
Name(_HID, "PNP0A06")
Name(_UID, "Memory hotplug resources")
External(MEMORY_SLOTS_NUMBER, IntObj)
/* Memory hotplug IO registers */
OperationRegion(MEMORY_HOTPLUG_IO_REGION, SystemIO,
ACPI_MEMORY_HOTPLUG_BASE,
ACPI_MEMORY_HOTPLUG_IO_LEN)
Name(_CRS, ResourceTemplate() {
IO(Decode16, ACPI_MEMORY_HOTPLUG_BASE, ACPI_MEMORY_HOTPLUG_BASE,
0, ACPI_MEMORY_HOTPLUG_IO_LEN, IO)
})
Method(_STA, 0) {
If (LEqual(MEMORY_SLOTS_NUMBER, Zero)) {
Return(0x0)
}
/* present, functioning, decoding, not shown in UI */
Return(0xB)
}
Field(MEMORY_HOTPLUG_IO_REGION, DWordAcc, NoLock, Preserve) {
MEMORY_SLOT_ADDR_LOW, 32, // read only
MEMORY_SLOT_ADDR_HIGH, 32, // read only
MEMORY_SLOT_SIZE_LOW, 32, // read only
MEMORY_SLOT_SIZE_HIGH, 32, // read only
MEMORY_SLOT_PROXIMITY, 32, // read only
}
Field(MEMORY_HOTPLUG_IO_REGION, ByteAcc, NoLock, Preserve) {
Offset(20),
MEMORY_SLOT_ENABLED, 1, // 1 if enabled, read only
MEMORY_SLOT_INSERT_EVENT, 1, // (read) 1 if has a insert event. (write) 1 to clear event
}
Mutex (MEMORY_SLOT_LOCK, 0)
Field (MEMORY_HOTPLUG_IO_REGION, DWordAcc, NoLock, Preserve) {
MEMORY_SLOT_SLECTOR, 32, // DIMM selector, write only
MEMORY_SLOT_OST_EVENT, 32, // _OST event code, write only
MEMORY_SLOT_OST_STATUS, 32, // _OST status code, write only
}
Method(MEMORY_SLOT_SCAN_METHOD, 0) {
If (LEqual(MEMORY_SLOTS_NUMBER, Zero)) {
Return(Zero)
}
Store(Zero, Local0) // Mem devs iterrator
Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
while (LLess(Local0, MEMORY_SLOTS_NUMBER)) {
Store(Local0, MEMORY_SLOT_SLECTOR) // select Local0 DIMM
If (LEqual(MEMORY_SLOT_INSERT_EVENT, One)) { // Memory device needs check
MEMORY_SLOT_NOTIFY_METHOD(Local0, 1)
Store(1, MEMORY_SLOT_INSERT_EVENT)
}
// TODO: handle memory eject request
Add(Local0, One, Local0) // goto next DIMM
}
Release(MEMORY_SLOT_LOCK)
Return(One)
}
Method(MEMORY_SLOT_STATUS_METHOD, 1) {
Store(Zero, Local0)
Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
If (LEqual(MEMORY_SLOT_ENABLED, One)) {
Store(0xF, Local0)
}
Release(MEMORY_SLOT_LOCK)
Return(Local0)
}
Method(MEMORY_SLOT_CRS_METHOD, 1, Serialized) {
Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
Name(MR64, ResourceTemplate() {
QWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x0000000000000000, // Address Space Granularity
0x0000000000000000, // Address Range Minimum
0xFFFFFFFFFFFFFFFE, // Address Range Maximum
0x0000000000000000, // Address Translation Offset
0xFFFFFFFFFFFFFFFF, // Address Length
,, MW64, AddressRangeMemory, TypeStatic)
})
CreateDWordField(MR64, 14, MINL)
CreateDWordField(MR64, 18, MINH)
CreateDWordField(MR64, 38, LENL)
CreateDWordField(MR64, 42, LENH)
CreateDWordField(MR64, 22, MAXL)
CreateDWordField(MR64, 26, MAXH)
Store(MEMORY_SLOT_ADDR_HIGH, MINH)
Store(MEMORY_SLOT_ADDR_LOW, MINL)
Store(MEMORY_SLOT_SIZE_HIGH, LENH)
Store(MEMORY_SLOT_SIZE_LOW, LENL)
// 64-bit math: MAX = MIN + LEN - 1
Add(MINL, LENL, MAXL)
Add(MINH, LENH, MAXH)
If (LLess(MAXL, MINL)) {
Add(MAXH, One, MAXH)
}
If (LLess(MAXL, One)) {
Subtract(MAXH, One, MAXH)
}
Subtract(MAXL, One, MAXL)
If (LEqual(MAXH, Zero)){
Name(MR32, ResourceTemplate() {
DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, // Address Space Granularity
0x00000000, // Address Range Minimum
0xFFFFFFFE, // Address Range Maximum
0x00000000, // Address Translation Offset
0xFFFFFFFF, // Address Length
,, MW32, AddressRangeMemory, TypeStatic)
})
CreateDWordField(MR32, MW32._MIN, MIN)
CreateDWordField(MR32, MW32._MAX, MAX)
CreateDWordField(MR32, MW32._LEN, LEN)
Store(MINL, MIN)
Store(MAXL, MAX)
Store(LENL, LEN)
Release(MEMORY_SLOT_LOCK)
Return(MR32)
}
Release(MEMORY_SLOT_LOCK)
Return(MR64)
}
Method(MEMORY_SLOT_PROXIMITY_METHOD, 1) {
Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
Store(MEMORY_SLOT_PROXIMITY, Local0)
Release(MEMORY_SLOT_LOCK)
Return(Local0)
}
Method(MEMORY_SLOT_OST_METHOD, 4) {
Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
Store(Arg1, MEMORY_SLOT_OST_EVENT)
Store(Arg2, MEMORY_SLOT_OST_STATUS)
Release(MEMORY_SLOT_LOCK)
}
} // Device()
} // Scope()

View File

@@ -297,13 +297,12 @@ DefinitionBlock (
#include "hw/acpi/pc-hotplug.h"
#define CPU_STATUS_BASE PIIX4_CPU_HOTPLUG_IO_BASE
#include "acpi-dsdt-cpu-hotplug.dsl"
#include "acpi-dsdt-mem-hotplug.dsl"
/****************************************************************
* General purpose events
****************************************************************/
External(\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_SCAN_METHOD, MethodObj)
Scope(\_GPE) {
Name(_HID, "ACPI0006")

View File

@@ -3,12 +3,12 @@ static unsigned char AcpiDsdtAmlCode[] = {
0x53,
0x44,
0x54,
0xf7,
0xa,
0x8,
0xe,
0x0,
0x0,
0x1,
0x1f,
0xfc,
0x42,
0x58,
0x50,
@@ -32,8 +32,8 @@ static unsigned char AcpiDsdtAmlCode[] = {
0x54,
0x4c,
0x28,
0x5,
0x10,
0x8,
0x14,
0x20,
0x10,
0x49,
@@ -2593,6 +2593,791 @@ static unsigned char AcpiDsdtAmlCode[] = {
0xa,
0xb,
0x10,
0x40,
0x31,
0x2e,
0x5f,
0x53,
0x42,
0x5f,
0x50,
0x43,
0x49,
0x30,
0x5b,
0x82,
0x43,
0x30,
0x4d,
0x48,
0x50,
0x44,
0x8,
0x5f,
0x48,
0x49,
0x44,
0xd,
0x50,
0x4e,
0x50,
0x30,
0x41,
0x30,
0x36,
0x0,
0x8,
0x5f,
0x55,
0x49,
0x44,
0xd,
0x4d,
0x65,
0x6d,
0x6f,
0x72,
0x79,
0x20,
0x68,
0x6f,
0x74,
0x70,
0x6c,
0x75,
0x67,
0x20,
0x72,
0x65,
0x73,
0x6f,
0x75,
0x72,
0x63,
0x65,
0x73,
0x0,
0x5b,
0x80,
0x48,
0x50,
0x4d,
0x52,
0x1,
0xb,
0x0,
0xa,
0xa,
0x18,
0x8,
0x5f,
0x43,
0x52,
0x53,
0x11,
0xd,
0xa,
0xa,
0x47,
0x1,
0x0,
0xa,
0x0,
0xa,
0x0,
0x18,
0x79,
0x0,
0x14,
0x13,
0x5f,
0x53,
0x54,
0x41,
0x0,
0xa0,
0x9,
0x93,
0x4d,
0x44,
0x4e,
0x52,
0x0,
0xa4,
0x0,
0xa4,
0xa,
0xb,
0x5b,
0x81,
0x1f,
0x48,
0x50,
0x4d,
0x52,
0x3,
0x4d,
0x52,
0x42,
0x4c,
0x20,
0x4d,
0x52,
0x42,
0x48,
0x20,
0x4d,
0x52,
0x4c,
0x4c,
0x20,
0x4d,
0x52,
0x4c,
0x48,
0x20,
0x4d,
0x50,
0x58,
0x5f,
0x20,
0x5b,
0x81,
0x13,
0x48,
0x50,
0x4d,
0x52,
0x1,
0x0,
0x40,
0xa,
0x4d,
0x45,
0x53,
0x5f,
0x1,
0x4d,
0x49,
0x4e,
0x53,
0x1,
0x5b,
0x1,
0x4d,
0x4c,
0x43,
0x4b,
0x0,
0x5b,
0x81,
0x15,
0x48,
0x50,
0x4d,
0x52,
0x3,
0x4d,
0x53,
0x45,
0x4c,
0x20,
0x4d,
0x4f,
0x45,
0x56,
0x20,
0x4d,
0x4f,
0x53,
0x43,
0x20,
0x14,
0x4a,
0x4,
0x4d,
0x53,
0x43,
0x4e,
0x0,
0xa0,
0x9,
0x93,
0x4d,
0x44,
0x4e,
0x52,
0x0,
0xa4,
0x0,
0x70,
0x0,
0x60,
0x5b,
0x23,
0x4d,
0x4c,
0x43,
0x4b,
0xff,
0xff,
0xa2,
0x25,
0x95,
0x60,
0x4d,
0x44,
0x4e,
0x52,
0x70,
0x60,
0x4d,
0x53,
0x45,
0x4c,
0xa0,
0x13,
0x93,
0x4d,
0x49,
0x4e,
0x53,
0x1,
0x4d,
0x54,
0x46,
0x59,
0x60,
0x1,
0x70,
0x1,
0x4d,
0x49,
0x4e,
0x53,
0x72,
0x60,
0x1,
0x60,
0x5b,
0x27,
0x4d,
0x4c,
0x43,
0x4b,
0xa4,
0x1,
0x14,
0x2d,
0x4d,
0x52,
0x53,
0x54,
0x1,
0x70,
0x0,
0x60,
0x5b,
0x23,
0x4d,
0x4c,
0x43,
0x4b,
0xff,
0xff,
0x70,
0x99,
0x68,
0x0,
0x4d,
0x53,
0x45,
0x4c,
0xa0,
0xb,
0x93,
0x4d,
0x45,
0x53,
0x5f,
0x1,
0x70,
0xa,
0xf,
0x60,
0x5b,
0x27,
0x4d,
0x4c,
0x43,
0x4b,
0xa4,
0x60,
0x14,
0x41,
0x18,
0x4d,
0x43,
0x52,
0x53,
0x9,
0x5b,
0x23,
0x4d,
0x4c,
0x43,
0x4b,
0xff,
0xff,
0x70,
0x99,
0x68,
0x0,
0x4d,
0x53,
0x45,
0x4c,
0x8,
0x4d,
0x52,
0x36,
0x34,
0x11,
0x33,
0xa,
0x30,
0x8a,
0x2b,
0x0,
0x0,
0xc,
0x3,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0xfe,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0x79,
0x0,
0x8a,
0x4d,
0x52,
0x36,
0x34,
0xa,
0xe,
0x4d,
0x49,
0x4e,
0x4c,
0x8a,
0x4d,
0x52,
0x36,
0x34,
0xa,
0x12,
0x4d,
0x49,
0x4e,
0x48,
0x8a,
0x4d,
0x52,
0x36,
0x34,
0xa,
0x26,
0x4c,
0x45,
0x4e,
0x4c,
0x8a,
0x4d,
0x52,
0x36,
0x34,
0xa,
0x2a,
0x4c,
0x45,
0x4e,
0x48,
0x8a,
0x4d,
0x52,
0x36,
0x34,
0xa,
0x16,
0x4d,
0x41,
0x58,
0x4c,
0x8a,
0x4d,
0x52,
0x36,
0x34,
0xa,
0x1a,
0x4d,
0x41,
0x58,
0x48,
0x70,
0x4d,
0x52,
0x42,
0x48,
0x4d,
0x49,
0x4e,
0x48,
0x70,
0x4d,
0x52,
0x42,
0x4c,
0x4d,
0x49,
0x4e,
0x4c,
0x70,
0x4d,
0x52,
0x4c,
0x48,
0x4c,
0x45,
0x4e,
0x48,
0x70,
0x4d,
0x52,
0x4c,
0x4c,
0x4c,
0x45,
0x4e,
0x4c,
0x72,
0x4d,
0x49,
0x4e,
0x4c,
0x4c,
0x45,
0x4e,
0x4c,
0x4d,
0x41,
0x58,
0x4c,
0x72,
0x4d,
0x49,
0x4e,
0x48,
0x4c,
0x45,
0x4e,
0x48,
0x4d,
0x41,
0x58,
0x48,
0xa0,
0x14,
0x95,
0x4d,
0x41,
0x58,
0x4c,
0x4d,
0x49,
0x4e,
0x4c,
0x72,
0x4d,
0x41,
0x58,
0x48,
0x1,
0x4d,
0x41,
0x58,
0x48,
0xa0,
0x11,
0x95,
0x4d,
0x41,
0x58,
0x4c,
0x1,
0x74,
0x4d,
0x41,
0x58,
0x48,
0x1,
0x4d,
0x41,
0x58,
0x48,
0x74,
0x4d,
0x41,
0x58,
0x4c,
0x1,
0x4d,
0x41,
0x58,
0x4c,
0xa0,
0x44,
0x7,
0x93,
0x4d,
0x41,
0x58,
0x48,
0x0,
0x8,
0x4d,
0x52,
0x33,
0x32,
0x11,
0x1f,
0xa,
0x1c,
0x87,
0x17,
0x0,
0x0,
0xc,
0x3,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0xfe,
0xff,
0xff,
0xff,
0x0,
0x0,
0x0,
0x0,
0xff,
0xff,
0xff,
0xff,
0x79,
0x0,
0x8a,
0x4d,
0x52,
0x33,
0x32,
0xa,
0xa,
0x4d,
0x49,
0x4e,
0x5f,
0x8a,
0x4d,
0x52,
0x33,
0x32,
0xa,
0xe,
0x4d,
0x41,
0x58,
0x5f,
0x8a,
0x4d,
0x52,
0x33,
0x32,
0xa,
0x16,
0x4c,
0x45,
0x4e,
0x5f,
0x70,
0x4d,
0x49,
0x4e,
0x4c,
0x4d,
0x49,
0x4e,
0x5f,
0x70,
0x4d,
0x41,
0x58,
0x4c,
0x4d,
0x41,
0x58,
0x5f,
0x70,
0x4c,
0x45,
0x4e,
0x4c,
0x4c,
0x45,
0x4e,
0x5f,
0x5b,
0x27,
0x4d,
0x4c,
0x43,
0x4b,
0xa4,
0x4d,
0x52,
0x33,
0x32,
0x5b,
0x27,
0x4d,
0x4c,
0x43,
0x4b,
0xa4,
0x4d,
0x52,
0x36,
0x34,
0x14,
0x24,
0x4d,
0x50,
0x58,
0x4d,
0x1,
0x5b,
0x23,
0x4d,
0x4c,
0x43,
0x4b,
0xff,
0xff,
0x70,
0x99,
0x68,
0x0,
0x4d,
0x53,
0x45,
0x4c,
0x70,
0x4d,
0x50,
0x58,
0x5f,
0x60,
0x5b,
0x27,
0x4d,
0x4c,
0x43,
0x4b,
0xa4,
0x60,
0x14,
0x28,
0x4d,
0x4f,
0x53,
0x54,
0x4,
0x5b,
0x23,
0x4d,
0x4c,
0x43,
0x4b,
0xff,
0xff,
0x70,
0x99,
0x68,
0x0,
0x4d,
0x53,
0x45,
0x4c,
0x70,
0x69,
0x4d,
0x4f,
0x45,
0x56,
0x70,
0x6a,
0x4d,
0x4f,
0x53,
0x43,
0x5b,
0x27,
0x4d,
0x4c,
0x43,
0x4b,
0x10,
0x45,
0xd,
0x5f,

View File

@@ -61,6 +61,7 @@
#include "hw/mem/pc-dimm.h"
#include "trace.h"
#include "qapi/visitor.h"
#include "qapi-visit.h"
/* debug PC/ISA interrupts */
//#define DEBUG_IRQ
@@ -1247,6 +1248,11 @@ FWCfgState *pc_memory_init(MachineState *machine,
pcms->hotplug_memory_base =
ROUND_UP(0x100000000ULL + above_4g_mem_size, 1ULL << 30);
if (pcms->enforce_aligned_dimm) {
/* size hotplug region assuming 1G page max alignment per slot */
hotplug_mem_size += (1ULL << 30) * machine->ram_slots;
}
if ((pcms->hotplug_memory_base + hotplug_mem_size) <
hotplug_mem_size) {
error_report("unsupported amount of maximum memory: " RAM_ADDR_FMT,
@@ -1545,6 +1551,37 @@ void qemu_register_pc_machine(QEMUMachine *m)
g_free(name);
}
static int pc_dimm_count(Object *obj, void *opaque)
{
int *count = opaque;
if (object_dynamic_cast(obj, TYPE_PC_DIMM)) {
(*count)++;
}
object_child_foreach(obj, pc_dimm_count, opaque);
return 0;
}
static int pc_existing_dimms_capacity(Object *obj, void *opaque)
{
Error *local_err = NULL;
uint64_t *size = opaque;
if (object_dynamic_cast(obj, TYPE_PC_DIMM)) {
(*size) += object_property_get_int(obj, PC_DIMM_SIZE_PROP, &local_err);
if (local_err) {
qerror_report_err(local_err);
error_free(local_err);
return 1;
}
}
object_child_foreach(obj, pc_dimm_count, opaque);
return 0;
}
static void pc_dimm_plug(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
@@ -1556,20 +1593,40 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev,
PCDIMMDevice *dimm = PC_DIMM(dev);
PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);
MemoryRegion *mr = ddc->get_memory_region(dimm);
uint64_t addr = object_property_get_int(OBJECT(dimm), PC_DIMM_ADDR_PROP,
&local_err);
uint64_t existing_dimms_capacity = 0;
uint64_t align = TARGET_PAGE_SIZE;
uint64_t addr;
addr = object_property_get_int(OBJECT(dimm), PC_DIMM_ADDR_PROP, &local_err);
if (local_err) {
goto out;
}
if (memory_region_get_alignment(mr) && pcms->enforce_aligned_dimm) {
align = memory_region_get_alignment(mr);
}
addr = pc_dimm_get_free_addr(pcms->hotplug_memory_base,
memory_region_size(&pcms->hotplug_memory),
!addr ? NULL : &addr,
!addr ? NULL : &addr, align,
memory_region_size(mr), &local_err);
if (local_err) {
goto out;
}
if (pc_existing_dimms_capacity(OBJECT(machine), &existing_dimms_capacity)) {
error_setg(&local_err, "failed to get total size of existing DIMMs");
goto out;
}
if (existing_dimms_capacity + memory_region_size(mr) >
machine->maxram_size - machine->ram_size) {
error_setg(&local_err, "not enough space, currently 0x%" PRIx64
" in use of total 0x" RAM_ADDR_FMT,
existing_dimms_capacity, machine->maxram_size);
goto out;
}
object_property_set_int(OBJECT(dev), addr, PC_DIMM_ADDR_PROP, &local_err);
if (local_err) {
goto out;
@@ -1598,6 +1655,11 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev,
goto out;
}
if (kvm_enabled() && !kvm_has_free_slot(machine)) {
error_setg(&local_err, "hypervisor has no free memory slots left");
goto out;
}
memory_region_add_subregion(&pcms->hotplug_memory,
addr - pcms->hotplug_memory_base, mr);
vmstate_register_ram(mr, dev);
@@ -1711,18 +1773,28 @@ static void pc_machine_set_max_ram_below_4g(Object *obj, Visitor *v,
pcms->max_ram_below_4g = value;
}
static bool pc_machine_get_vmport(Object *obj, Error **errp)
static void pc_machine_get_vmport(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
PCMachineState *pcms = PC_MACHINE(obj);
OnOffAuto vmport = pcms->vmport;
return pcms->vmport;
visit_type_OnOffAuto(v, &vmport, name, errp);
}
static void pc_machine_set_vmport(Object *obj, bool value, Error **errp)
static void pc_machine_set_vmport(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
PCMachineState *pcms = PC_MACHINE(obj);
pcms->vmport = value;
visit_type_OnOffAuto(v, &pcms->vmport, name, errp);
}
static bool pc_machine_get_aligned_dimm(Object *obj, Error **errp)
{
PCMachineState *pcms = PC_MACHINE(obj);
return pcms->enforce_aligned_dimm;
}
static void pc_machine_initfn(Object *obj)
@@ -1737,11 +1809,17 @@ static void pc_machine_initfn(Object *obj)
pc_machine_get_max_ram_below_4g,
pc_machine_set_max_ram_below_4g,
NULL, NULL, NULL);
pcms->vmport = !xen_enabled();
object_property_add_bool(obj, PC_MACHINE_VMPORT,
pc_machine_get_vmport,
pc_machine_set_vmport,
NULL);
pcms->vmport = ON_OFF_AUTO_AUTO;
object_property_add(obj, PC_MACHINE_VMPORT, "OnOffAuto",
pc_machine_get_vmport,
pc_machine_set_vmport,
NULL, NULL, NULL);
pcms->enforce_aligned_dimm = true;
object_property_add_bool(obj, PC_MACHINE_ENFORCE_ALIGNED_DIMM,
pc_machine_get_aligned_dimm,
NULL, NULL);
}
static void pc_machine_class_init(ObjectClass *oc, void *data)

View File

@@ -234,9 +234,14 @@ static void pc_init1(MachineState *machine,
pc_vga_init(isa_bus, pci_enabled ? pci_bus : NULL);
assert(pc_machine->vmport != ON_OFF_AUTO_MAX);
if (pc_machine->vmport == ON_OFF_AUTO_AUTO) {
pc_machine->vmport = xen_enabled() ? ON_OFF_AUTO_OFF : ON_OFF_AUTO_ON;
}
/* init basic PC hardware */
pc_basic_device_init(isa_bus, gsi, &rtc_state, &floppy,
!pc_machine->vmport, 0x4);
(pc_machine->vmport != ON_OFF_AUTO_ON), 0x4);
pc_nic_init(isa_bus, pci_bus);
@@ -305,10 +310,12 @@ static void pc_init_pci(MachineState *machine)
static void pc_compat_2_1(MachineState *machine)
{
PCMachineState *pcms = PC_MACHINE(machine);
smbios_uuid_encoded = false;
x86_cpu_compat_set_features("coreduo", FEAT_1_ECX, CPUID_EXT_VMX, 0);
x86_cpu_compat_set_features("core2duo", FEAT_1_ECX, CPUID_EXT_VMX, 0);
x86_cpu_compat_kvm_no_autodisable(FEAT_8000_0001_ECX, CPUID_EXT3_SVM);
pcms->enforce_aligned_dimm = false;
}
static void pc_compat_2_0(MachineState *machine)

View File

@@ -242,9 +242,14 @@ static void pc_q35_init(MachineState *machine)
pc_register_ferr_irq(gsi[13]);
assert(pc_machine->vmport != ON_OFF_AUTO_MAX);
if (pc_machine->vmport == ON_OFF_AUTO_AUTO) {
pc_machine->vmport = xen_enabled() ? ON_OFF_AUTO_OFF : ON_OFF_AUTO_ON;
}
/* init basic PC hardware */
pc_basic_device_init(isa_bus, gsi, &rtc_state, &floppy,
!pc_machine->vmport, 0xff0104);
(pc_machine->vmport != ON_OFF_AUTO_ON), 0xff0104);
/* connect pm stuff to lpc */
ich9_lpc_pm_init(lpc);
@@ -284,6 +289,9 @@ static void pc_q35_init(MachineState *machine)
static void pc_compat_2_1(MachineState *machine)
{
PCMachineState *pcms = PC_MACHINE(machine);
pcms->enforce_aligned_dimm = false;
smbios_uuid_encoded = false;
x86_cpu_compat_set_features("coreduo", FEAT_1_ECX, CPUID_EXT_VMX, 0);
x86_cpu_compat_set_features("core2duo", FEAT_1_ECX, CPUID_EXT_VMX, 0);

View File

@@ -405,13 +405,12 @@ DefinitionBlock (
#include "hw/acpi/pc-hotplug.h"
#define CPU_STATUS_BASE ICH9_CPU_HOTPLUG_IO_BASE
#include "acpi-dsdt-cpu-hotplug.dsl"
#include "acpi-dsdt-mem-hotplug.dsl"
/****************************************************************
* General purpose events
****************************************************************/
External(\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_SCAN_METHOD, MethodObj)
Scope(\_GPE) {
Name(_HID, "ACPI0006")

View File

@@ -3,12 +3,12 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
0x53,
0x44,
0x54,
0xe5,
0x1c,
0xf6,
0x1f,
0x0,
0x0,
0x1,
0xb7,
0x91,
0x42,
0x58,
0x50,
@@ -31,9 +31,9 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
0x4e,
0x54,
0x4c,
0x15,
0x11,
0x13,
0x28,
0x8,
0x14,
0x20,
0x10,
0x49,
@@ -7234,6 +7234,791 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
0xa,
0xb,
0x10,
0x40,
0x31,
0x2e,
0x5f,
0x53,
0x42,
0x5f,
0x50,
0x43,
0x49,
0x30,
0x5b,
0x82,
0x43,
0x30,
0x4d,
0x48,
0x50,
0x44,
0x8,
0x5f,
0x48,
0x49,
0x44,
0xd,
0x50,
0x4e,
0x50,
0x30,
0x41,
0x30,
0x36,
0x0,
0x8,
0x5f,
0x55,
0x49,
0x44,
0xd,
0x4d,
0x65,
0x6d,
0x6f,
0x72,
0x79,
0x20,
0x68,
0x6f,
0x74,
0x70,
0x6c,
0x75,
0x67,
0x20,
0x72,
0x65,
0x73,
0x6f,
0x75,
0x72,
0x63,
0x65,
0x73,
0x0,
0x5b,
0x80,
0x48,
0x50,
0x4d,
0x52,
0x1,
0xb,
0x0,
0xa,
0xa,
0x18,
0x8,
0x5f,
0x43,
0x52,
0x53,
0x11,
0xd,
0xa,
0xa,
0x47,
0x1,
0x0,
0xa,
0x0,
0xa,
0x0,
0x18,
0x79,
0x0,
0x14,
0x13,
0x5f,
0x53,
0x54,
0x41,
0x0,
0xa0,
0x9,
0x93,
0x4d,
0x44,
0x4e,
0x52,
0x0,
0xa4,
0x0,
0xa4,
0xa,
0xb,
0x5b,
0x81,
0x1f,
0x48,
0x50,
0x4d,
0x52,
0x3,
0x4d,
0x52,
0x42,
0x4c,
0x20,
0x4d,
0x52,
0x42,
0x48,
0x20,
0x4d,
0x52,
0x4c,
0x4c,
0x20,
0x4d,
0x52,
0x4c,
0x48,
0x20,
0x4d,
0x50,
0x58,
0x5f,
0x20,
0x5b,
0x81,
0x13,
0x48,
0x50,
0x4d,
0x52,
0x1,
0x0,
0x40,
0xa,
0x4d,
0x45,
0x53,
0x5f,
0x1,
0x4d,
0x49,
0x4e,
0x53,
0x1,
0x5b,
0x1,
0x4d,
0x4c,
0x43,
0x4b,
0x0,
0x5b,
0x81,
0x15,
0x48,
0x50,
0x4d,
0x52,
0x3,
0x4d,
0x53,
0x45,
0x4c,
0x20,
0x4d,
0x4f,
0x45,
0x56,
0x20,
0x4d,
0x4f,
0x53,
0x43,
0x20,
0x14,
0x4a,
0x4,
0x4d,
0x53,
0x43,
0x4e,
0x0,
0xa0,
0x9,
0x93,
0x4d,
0x44,
0x4e,
0x52,
0x0,
0xa4,
0x0,
0x70,
0x0,
0x60,
0x5b,
0x23,
0x4d,
0x4c,
0x43,
0x4b,
0xff,
0xff,
0xa2,
0x25,
0x95,
0x60,
0x4d,
0x44,
0x4e,
0x52,
0x70,
0x60,
0x4d,
0x53,
0x45,
0x4c,
0xa0,
0x13,
0x93,
0x4d,
0x49,
0x4e,
0x53,
0x1,
0x4d,
0x54,
0x46,
0x59,
0x60,
0x1,
0x70,
0x1,
0x4d,
0x49,
0x4e,
0x53,
0x72,
0x60,
0x1,
0x60,
0x5b,
0x27,
0x4d,
0x4c,
0x43,
0x4b,
0xa4,
0x1,
0x14,
0x2d,
0x4d,
0x52,
0x53,
0x54,
0x1,
0x70,
0x0,
0x60,
0x5b,
0x23,
0x4d,
0x4c,
0x43,
0x4b,
0xff,
0xff,
0x70,
0x99,
0x68,
0x0,
0x4d,
0x53,
0x45,
0x4c,
0xa0,
0xb,
0x93,
0x4d,
0x45,
0x53,
0x5f,
0x1,
0x70,
0xa,
0xf,
0x60,
0x5b,
0x27,
0x4d,
0x4c,
0x43,
0x4b,
0xa4,
0x60,
0x14,
0x41,
0x18,
0x4d,
0x43,
0x52,
0x53,
0x9,
0x5b,
0x23,
0x4d,
0x4c,
0x43,
0x4b,
0xff,
0xff,
0x70,
0x99,
0x68,
0x0,
0x4d,
0x53,
0x45,
0x4c,
0x8,
0x4d,
0x52,
0x36,
0x34,
0x11,
0x33,
0xa,
0x30,
0x8a,
0x2b,
0x0,
0x0,
0xc,
0x3,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0xfe,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0x79,
0x0,
0x8a,
0x4d,
0x52,
0x36,
0x34,
0xa,
0xe,
0x4d,
0x49,
0x4e,
0x4c,
0x8a,
0x4d,
0x52,
0x36,
0x34,
0xa,
0x12,
0x4d,
0x49,
0x4e,
0x48,
0x8a,
0x4d,
0x52,
0x36,
0x34,
0xa,
0x26,
0x4c,
0x45,
0x4e,
0x4c,
0x8a,
0x4d,
0x52,
0x36,
0x34,
0xa,
0x2a,
0x4c,
0x45,
0x4e,
0x48,
0x8a,
0x4d,
0x52,
0x36,
0x34,
0xa,
0x16,
0x4d,
0x41,
0x58,
0x4c,
0x8a,
0x4d,
0x52,
0x36,
0x34,
0xa,
0x1a,
0x4d,
0x41,
0x58,
0x48,
0x70,
0x4d,
0x52,
0x42,
0x48,
0x4d,
0x49,
0x4e,
0x48,
0x70,
0x4d,
0x52,
0x42,
0x4c,
0x4d,
0x49,
0x4e,
0x4c,
0x70,
0x4d,
0x52,
0x4c,
0x48,
0x4c,
0x45,
0x4e,
0x48,
0x70,
0x4d,
0x52,
0x4c,
0x4c,
0x4c,
0x45,
0x4e,
0x4c,
0x72,
0x4d,
0x49,
0x4e,
0x4c,
0x4c,
0x45,
0x4e,
0x4c,
0x4d,
0x41,
0x58,
0x4c,
0x72,
0x4d,
0x49,
0x4e,
0x48,
0x4c,
0x45,
0x4e,
0x48,
0x4d,
0x41,
0x58,
0x48,
0xa0,
0x14,
0x95,
0x4d,
0x41,
0x58,
0x4c,
0x4d,
0x49,
0x4e,
0x4c,
0x72,
0x4d,
0x41,
0x58,
0x48,
0x1,
0x4d,
0x41,
0x58,
0x48,
0xa0,
0x11,
0x95,
0x4d,
0x41,
0x58,
0x4c,
0x1,
0x74,
0x4d,
0x41,
0x58,
0x48,
0x1,
0x4d,
0x41,
0x58,
0x48,
0x74,
0x4d,
0x41,
0x58,
0x4c,
0x1,
0x4d,
0x41,
0x58,
0x4c,
0xa0,
0x44,
0x7,
0x93,
0x4d,
0x41,
0x58,
0x48,
0x0,
0x8,
0x4d,
0x52,
0x33,
0x32,
0x11,
0x1f,
0xa,
0x1c,
0x87,
0x17,
0x0,
0x0,
0xc,
0x3,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0xfe,
0xff,
0xff,
0xff,
0x0,
0x0,
0x0,
0x0,
0xff,
0xff,
0xff,
0xff,
0x79,
0x0,
0x8a,
0x4d,
0x52,
0x33,
0x32,
0xa,
0xa,
0x4d,
0x49,
0x4e,
0x5f,
0x8a,
0x4d,
0x52,
0x33,
0x32,
0xa,
0xe,
0x4d,
0x41,
0x58,
0x5f,
0x8a,
0x4d,
0x52,
0x33,
0x32,
0xa,
0x16,
0x4c,
0x45,
0x4e,
0x5f,
0x70,
0x4d,
0x49,
0x4e,
0x4c,
0x4d,
0x49,
0x4e,
0x5f,
0x70,
0x4d,
0x41,
0x58,
0x4c,
0x4d,
0x41,
0x58,
0x5f,
0x70,
0x4c,
0x45,
0x4e,
0x4c,
0x4c,
0x45,
0x4e,
0x5f,
0x5b,
0x27,
0x4d,
0x4c,
0x43,
0x4b,
0xa4,
0x4d,
0x52,
0x33,
0x32,
0x5b,
0x27,
0x4d,
0x4c,
0x43,
0x4b,
0xa4,
0x4d,
0x52,
0x36,
0x34,
0x14,
0x24,
0x4d,
0x50,
0x58,
0x4d,
0x1,
0x5b,
0x23,
0x4d,
0x4c,
0x43,
0x4b,
0xff,
0xff,
0x70,
0x99,
0x68,
0x0,
0x4d,
0x53,
0x45,
0x4c,
0x70,
0x4d,
0x50,
0x58,
0x5f,
0x60,
0x5b,
0x27,
0x4d,
0x4c,
0x43,
0x4b,
0xa4,
0x60,
0x14,
0x28,
0x4d,
0x4f,
0x53,
0x54,
0x4,
0x5b,
0x23,
0x4d,
0x4c,
0x43,
0x4b,
0xff,
0xff,
0x70,
0x99,
0x68,
0x0,
0x4d,
0x53,
0x45,
0x4c,
0x70,
0x69,
0x4d,
0x4f,
0x45,
0x56,
0x70,
0x6a,
0x4d,
0x4f,
0x53,
0x43,
0x5b,
0x27,
0x4d,
0x4c,
0x43,
0x4b,
0x10,
0x42,
0xa,
0x5f,

View File

@@ -11,7 +11,7 @@ static unsigned char ssdm_mem_aml[] = {
0x0,
0x0,
0x2,
0x71,
0x66,
0x42,
0x58,
0x50,
@@ -34,9 +34,9 @@ static unsigned char ssdm_mem_aml[] = {
0x4e,
0x54,
0x4c,
0x15,
0x11,
0x13,
0x28,
0x8,
0x14,
0x20,
0x10,
0x42,

View File

@@ -36,6 +36,8 @@ DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1)
Name(P1E, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })
ACPI_EXTRACT_NAME_BUFFER8 acpi_pci64_length
Name(P1L, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })
ACPI_EXTRACT_NAME_DWORD_CONST ssdt_mctrl_nr_slots
Name(MEMORY_SLOTS_NUMBER, 0x12345678)
}
@@ -117,167 +119,4 @@ DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1)
}
}
}
External(MEMORY_SLOT_NOTIFY_METHOD, MethodObj)
Scope(\_SB.PCI0) {
Device(MEMORY_HOTPLUG_DEVICE) {
Name(_HID, "PNP0A06")
Name(_UID, "Memory hotplug resources")
ACPI_EXTRACT_NAME_DWORD_CONST ssdt_mctrl_nr_slots
Name(MEMORY_SLOTS_NUMBER, 0x12345678)
/* Memory hotplug IO registers */
OperationRegion(MEMORY_HOTPLUG_IO_REGION, SystemIO,
ACPI_MEMORY_HOTPLUG_BASE,
ACPI_MEMORY_HOTPLUG_IO_LEN)
Name(_CRS, ResourceTemplate() {
IO(Decode16, ACPI_MEMORY_HOTPLUG_BASE, ACPI_MEMORY_HOTPLUG_BASE,
0, ACPI_MEMORY_HOTPLUG_IO_LEN, IO)
})
Method(_STA, 0) {
If (LEqual(MEMORY_SLOTS_NUMBER, Zero)) {
Return(0x0)
}
/* present, functioning, decoding, not shown in UI */
Return(0xB)
}
Field(MEMORY_HOTPLUG_IO_REGION, DWordAcc, NoLock, Preserve) {
MEMORY_SLOT_ADDR_LOW, 32, // read only
MEMORY_SLOT_ADDR_HIGH, 32, // read only
MEMORY_SLOT_SIZE_LOW, 32, // read only
MEMORY_SLOT_SIZE_HIGH, 32, // read only
MEMORY_SLOT_PROXIMITY, 32, // read only
}
Field(MEMORY_HOTPLUG_IO_REGION, ByteAcc, NoLock, Preserve) {
Offset(20),
MEMORY_SLOT_ENABLED, 1, // 1 if enabled, read only
MEMORY_SLOT_INSERT_EVENT, 1, // (read) 1 if has a insert event. (write) 1 to clear event
}
Mutex (MEMORY_SLOT_LOCK, 0)
Field (MEMORY_HOTPLUG_IO_REGION, DWordAcc, NoLock, Preserve) {
MEMORY_SLOT_SLECTOR, 32, // DIMM selector, write only
MEMORY_SLOT_OST_EVENT, 32, // _OST event code, write only
MEMORY_SLOT_OST_STATUS, 32, // _OST status code, write only
}
Method(MEMORY_SLOT_SCAN_METHOD, 0) {
If (LEqual(MEMORY_SLOTS_NUMBER, Zero)) {
Return(Zero)
}
Store(Zero, Local0) // Mem devs iterrator
Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
while (LLess(Local0, MEMORY_SLOTS_NUMBER)) {
Store(Local0, MEMORY_SLOT_SLECTOR) // select Local0 DIMM
If (LEqual(MEMORY_SLOT_INSERT_EVENT, One)) { // Memory device needs check
MEMORY_SLOT_NOTIFY_METHOD(Local0, 1)
Store(1, MEMORY_SLOT_INSERT_EVENT)
}
// TODO: handle memory eject request
Add(Local0, One, Local0) // goto next DIMM
}
Release(MEMORY_SLOT_LOCK)
Return(One)
}
Method(MEMORY_SLOT_STATUS_METHOD, 1) {
Store(Zero, Local0)
Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
If (LEqual(MEMORY_SLOT_ENABLED, One)) {
Store(0xF, Local0)
}
Release(MEMORY_SLOT_LOCK)
Return(Local0)
}
Method(MEMORY_SLOT_CRS_METHOD, 1, Serialized) {
Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
Name(MR64, ResourceTemplate() {
QWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x0000000000000000, // Address Space Granularity
0x0000000000000000, // Address Range Minimum
0xFFFFFFFFFFFFFFFE, // Address Range Maximum
0x0000000000000000, // Address Translation Offset
0xFFFFFFFFFFFFFFFF, // Address Length
,, MW64, AddressRangeMemory, TypeStatic)
})
CreateDWordField(MR64, 14, MINL)
CreateDWordField(MR64, 18, MINH)
CreateDWordField(MR64, 38, LENL)
CreateDWordField(MR64, 42, LENH)
CreateDWordField(MR64, 22, MAXL)
CreateDWordField(MR64, 26, MAXH)
Store(MEMORY_SLOT_ADDR_HIGH, MINH)
Store(MEMORY_SLOT_ADDR_LOW, MINL)
Store(MEMORY_SLOT_SIZE_HIGH, LENH)
Store(MEMORY_SLOT_SIZE_LOW, LENL)
// 64-bit math: MAX = MIN + LEN - 1
Add(MINL, LENL, MAXL)
Add(MINH, LENH, MAXH)
If (LLess(MAXL, MINL)) {
Add(MAXH, One, MAXH)
}
If (LLess(MAXL, One)) {
Subtract(MAXH, One, MAXH)
}
Subtract(MAXL, One, MAXL)
If (LEqual(MAXH, Zero)){
Name(MR32, ResourceTemplate() {
DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, // Address Space Granularity
0x00000000, // Address Range Minimum
0xFFFFFFFE, // Address Range Maximum
0x00000000, // Address Translation Offset
0xFFFFFFFF, // Address Length
,, MW32, AddressRangeMemory, TypeStatic)
})
CreateDWordField(MR32, MW32._MIN, MIN)
CreateDWordField(MR32, MW32._MAX, MAX)
CreateDWordField(MR32, MW32._LEN, LEN)
Store(MINL, MIN)
Store(MAXL, MAX)
Store(LENL, LEN)
Release(MEMORY_SLOT_LOCK)
Return(MR32)
}
Release(MEMORY_SLOT_LOCK)
Return(MR64)
}
Method(MEMORY_SLOT_PROXIMITY_METHOD, 1) {
Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
Store(MEMORY_SLOT_PROXIMITY, Local0)
Release(MEMORY_SLOT_LOCK)
Return(Local0)
}
Method(MEMORY_SLOT_OST_METHOD, 4) {
Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
Store(Arg1, MEMORY_SLOT_OST_EVENT)
Store(Arg2, MEMORY_SLOT_OST_STATUS)
Release(MEMORY_SLOT_LOCK)
}
} // Device()
} // Scope()
}

View File

@@ -2,13 +2,13 @@ static unsigned char acpi_pci64_length[] = {
0x6f
};
static unsigned char acpi_s4_pkg[] = {
0x8f
0x99
};
static unsigned short ssdt_mctrl_nr_slots[] = {
0x1aa
static unsigned char ssdt_mctrl_nr_slots[] = {
0x7d
};
static unsigned char acpi_s3_name[] = {
0x7c
0x86
};
static unsigned char acpi_pci32_start[] = {
0x2f
@@ -21,12 +21,12 @@ static unsigned char ssdp_misc_aml[] = {
0x53,
0x44,
0x54,
0x7e,
0x4,
0x6c,
0x1,
0x0,
0x0,
0x1,
0x8b,
0x3,
0x42,
0x58,
0x50,
@@ -49,12 +49,12 @@ static unsigned char ssdp_misc_aml[] = {
0x4e,
0x54,
0x4c,
0x15,
0x11,
0x13,
0x28,
0x8,
0x14,
0x20,
0x10,
0x42,
0x4c,
0x5,
0x5c,
0x0,
@@ -136,6 +136,16 @@ static unsigned char ssdp_misc_aml[] = {
0x0,
0x0,
0x0,
0x8,
0x4d,
0x44,
0x4e,
0x52,
0xc,
0x78,
0x56,
0x34,
0x12,
0x10,
0x29,
0x5c,
@@ -370,809 +380,13 @@ static unsigned char ssdp_misc_aml[] = {
0x49,
0x4f,
0x4d,
0x58,
0x10,
0x4b,
0x31,
0x5c,
0x2e,
0x5f,
0x53,
0x42,
0x5f,
0x50,
0x43,
0x49,
0x30,
0x5b,
0x82,
0x4d,
0x30,
0x4d,
0x48,
0x50,
0x44,
0x8,
0x5f,
0x48,
0x49,
0x44,
0xd,
0x50,
0x4e,
0x50,
0x30,
0x41,
0x30,
0x36,
0x0,
0x8,
0x5f,
0x55,
0x49,
0x44,
0xd,
0x4d,
0x65,
0x6d,
0x6f,
0x72,
0x79,
0x20,
0x68,
0x6f,
0x74,
0x70,
0x6c,
0x75,
0x67,
0x20,
0x72,
0x65,
0x73,
0x6f,
0x75,
0x72,
0x63,
0x65,
0x73,
0x0,
0x8,
0x4d,
0x44,
0x4e,
0x52,
0xc,
0x78,
0x56,
0x34,
0x12,
0x5b,
0x80,
0x48,
0x50,
0x4d,
0x52,
0x1,
0xb,
0x0,
0xa,
0xa,
0x18,
0x8,
0x5f,
0x43,
0x52,
0x53,
0x11,
0xd,
0xa,
0xa,
0x47,
0x1,
0x0,
0xa,
0x0,
0xa,
0x0,
0x18,
0x79,
0x0,
0x14,
0x13,
0x5f,
0x53,
0x54,
0x41,
0x0,
0xa0,
0x9,
0x93,
0x4d,
0x44,
0x4e,
0x52,
0x0,
0xa4,
0x0,
0xa4,
0xa,
0xb,
0x5b,
0x81,
0x1f,
0x48,
0x50,
0x4d,
0x52,
0x3,
0x4d,
0x52,
0x42,
0x4c,
0x20,
0x4d,
0x52,
0x42,
0x48,
0x20,
0x4d,
0x52,
0x4c,
0x4c,
0x20,
0x4d,
0x52,
0x4c,
0x48,
0x20,
0x4d,
0x50,
0x58,
0x5f,
0x20,
0x5b,
0x81,
0x13,
0x48,
0x50,
0x4d,
0x52,
0x1,
0x0,
0x40,
0xa,
0x4d,
0x45,
0x53,
0x5f,
0x1,
0x4d,
0x49,
0x4e,
0x53,
0x1,
0x5b,
0x1,
0x4d,
0x4c,
0x43,
0x4b,
0x0,
0x5b,
0x81,
0x15,
0x48,
0x50,
0x4d,
0x52,
0x3,
0x4d,
0x53,
0x45,
0x4c,
0x20,
0x4d,
0x4f,
0x45,
0x56,
0x20,
0x4d,
0x4f,
0x53,
0x43,
0x20,
0x14,
0x4a,
0x4,
0x4d,
0x53,
0x43,
0x4e,
0x0,
0xa0,
0x9,
0x93,
0x4d,
0x44,
0x4e,
0x52,
0x0,
0xa4,
0x0,
0x70,
0x0,
0x60,
0x5b,
0x23,
0x4d,
0x4c,
0x43,
0x4b,
0xff,
0xff,
0xa2,
0x25,
0x95,
0x60,
0x4d,
0x44,
0x4e,
0x52,
0x70,
0x60,
0x4d,
0x53,
0x45,
0x4c,
0xa0,
0x13,
0x93,
0x4d,
0x49,
0x4e,
0x53,
0x1,
0x4d,
0x54,
0x46,
0x59,
0x60,
0x1,
0x70,
0x1,
0x4d,
0x49,
0x4e,
0x53,
0x72,
0x60,
0x1,
0x60,
0x5b,
0x27,
0x4d,
0x4c,
0x43,
0x4b,
0xa4,
0x1,
0x14,
0x2d,
0x4d,
0x52,
0x53,
0x54,
0x1,
0x70,
0x0,
0x60,
0x5b,
0x23,
0x4d,
0x4c,
0x43,
0x4b,
0xff,
0xff,
0x70,
0x99,
0x68,
0x0,
0x4d,
0x53,
0x45,
0x4c,
0xa0,
0xb,
0x93,
0x4d,
0x45,
0x53,
0x5f,
0x1,
0x70,
0xa,
0xf,
0x60,
0x5b,
0x27,
0x4d,
0x4c,
0x43,
0x4b,
0xa4,
0x60,
0x14,
0x41,
0x18,
0x4d,
0x43,
0x52,
0x53,
0x9,
0x5b,
0x23,
0x4d,
0x4c,
0x43,
0x4b,
0xff,
0xff,
0x70,
0x99,
0x68,
0x0,
0x4d,
0x53,
0x45,
0x4c,
0x8,
0x4d,
0x52,
0x36,
0x34,
0x11,
0x33,
0xa,
0x30,
0x8a,
0x2b,
0x0,
0x0,
0xc,
0x3,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0xfe,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0x79,
0x0,
0x8a,
0x4d,
0x52,
0x36,
0x34,
0xa,
0xe,
0x4d,
0x49,
0x4e,
0x4c,
0x8a,
0x4d,
0x52,
0x36,
0x34,
0xa,
0x12,
0x4d,
0x49,
0x4e,
0x48,
0x8a,
0x4d,
0x52,
0x36,
0x34,
0xa,
0x26,
0x4c,
0x45,
0x4e,
0x4c,
0x8a,
0x4d,
0x52,
0x36,
0x34,
0xa,
0x2a,
0x4c,
0x45,
0x4e,
0x48,
0x8a,
0x4d,
0x52,
0x36,
0x34,
0xa,
0x16,
0x4d,
0x41,
0x58,
0x4c,
0x8a,
0x4d,
0x52,
0x36,
0x34,
0xa,
0x1a,
0x4d,
0x41,
0x58,
0x48,
0x70,
0x4d,
0x52,
0x42,
0x48,
0x4d,
0x49,
0x4e,
0x48,
0x70,
0x4d,
0x52,
0x42,
0x4c,
0x4d,
0x49,
0x4e,
0x4c,
0x70,
0x4d,
0x52,
0x4c,
0x48,
0x4c,
0x45,
0x4e,
0x48,
0x70,
0x4d,
0x52,
0x4c,
0x4c,
0x4c,
0x45,
0x4e,
0x4c,
0x72,
0x4d,
0x49,
0x4e,
0x4c,
0x4c,
0x45,
0x4e,
0x4c,
0x4d,
0x41,
0x58,
0x4c,
0x72,
0x4d,
0x49,
0x4e,
0x48,
0x4c,
0x45,
0x4e,
0x48,
0x4d,
0x41,
0x58,
0x48,
0xa0,
0x14,
0x95,
0x4d,
0x41,
0x58,
0x4c,
0x4d,
0x49,
0x4e,
0x4c,
0x72,
0x4d,
0x41,
0x58,
0x48,
0x1,
0x4d,
0x41,
0x58,
0x48,
0xa0,
0x11,
0x95,
0x4d,
0x41,
0x58,
0x4c,
0x1,
0x74,
0x4d,
0x41,
0x58,
0x48,
0x1,
0x4d,
0x41,
0x58,
0x48,
0x74,
0x4d,
0x41,
0x58,
0x4c,
0x1,
0x4d,
0x41,
0x58,
0x4c,
0xa0,
0x44,
0x7,
0x93,
0x4d,
0x41,
0x58,
0x48,
0x0,
0x8,
0x4d,
0x52,
0x33,
0x32,
0x11,
0x1f,
0xa,
0x1c,
0x87,
0x17,
0x0,
0x0,
0xc,
0x3,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0x0,
0xfe,
0xff,
0xff,
0xff,
0x0,
0x0,
0x0,
0x0,
0xff,
0xff,
0xff,
0xff,
0x79,
0x0,
0x8a,
0x4d,
0x52,
0x33,
0x32,
0xa,
0xa,
0x4d,
0x49,
0x4e,
0x5f,
0x8a,
0x4d,
0x52,
0x33,
0x32,
0xa,
0xe,
0x4d,
0x41,
0x58,
0x5f,
0x8a,
0x4d,
0x52,
0x33,
0x32,
0xa,
0x16,
0x4c,
0x45,
0x4e,
0x5f,
0x70,
0x4d,
0x49,
0x4e,
0x4c,
0x4d,
0x49,
0x4e,
0x5f,
0x70,
0x4d,
0x41,
0x58,
0x4c,
0x4d,
0x41,
0x58,
0x5f,
0x70,
0x4c,
0x45,
0x4e,
0x4c,
0x4c,
0x45,
0x4e,
0x5f,
0x5b,
0x27,
0x4d,
0x4c,
0x43,
0x4b,
0xa4,
0x4d,
0x52,
0x33,
0x32,
0x5b,
0x27,
0x4d,
0x4c,
0x43,
0x4b,
0xa4,
0x4d,
0x52,
0x36,
0x34,
0x14,
0x24,
0x4d,
0x50,
0x58,
0x4d,
0x1,
0x5b,
0x23,
0x4d,
0x4c,
0x43,
0x4b,
0xff,
0xff,
0x70,
0x99,
0x68,
0x0,
0x4d,
0x53,
0x45,
0x4c,
0x70,
0x4d,
0x50,
0x58,
0x5f,
0x60,
0x5b,
0x27,
0x4d,
0x4c,
0x43,
0x4b,
0xa4,
0x60,
0x14,
0x28,
0x4d,
0x4f,
0x53,
0x54,
0x4,
0x5b,
0x23,
0x4d,
0x4c,
0x43,
0x4b,
0xff,
0xff,
0x70,
0x99,
0x68,
0x0,
0x4d,
0x53,
0x45,
0x4c,
0x70,
0x69,
0x4d,
0x4f,
0x45,
0x56,
0x70,
0x6a,
0x4d,
0x4f,
0x53,
0x43,
0x5b,
0x27,
0x4d,
0x4c,
0x43,
0x4b
0x58
};
static unsigned char ssdt_isa_pest[] = {
0xd0
0xda
};
static unsigned char acpi_s4_name[] = {
0x88
0x92
};
static unsigned char acpi_pci64_start[] = {
0x4d

View File

@@ -188,7 +188,7 @@ void apic_deliver_pic_intr(DeviceState *dev, int level)
apic_reset_bit(s->irr, lvt & 0xff);
/* fall through */
case APIC_DM_EXTINT:
cpu_reset_interrupt(CPU(s->cpu), CPU_INTERRUPT_HARD);
apic_update_irq(s);
break;
}
}
@@ -349,6 +349,11 @@ static int apic_get_arb_pri(APICCommonState *s)
static int apic_irq_pending(APICCommonState *s)
{
int irrv, ppr;
if (!(s->spurious_vec & APIC_SV_ENABLE)) {
return 0;
}
irrv = get_highest_priority_int(s->irr);
if (irrv < 0) {
return 0;
@@ -366,14 +371,13 @@ static void apic_update_irq(APICCommonState *s)
{
CPUState *cpu;
if (!(s->spurious_vec & APIC_SV_ENABLE)) {
return;
}
cpu = CPU(s->cpu);
if (!qemu_cpu_is_self(cpu)) {
cpu_interrupt(cpu, CPU_INTERRUPT_POLL);
} else if (apic_irq_pending(s) > 0) {
cpu_interrupt(cpu, CPU_INTERRUPT_HARD);
} else if (!apic_accept_pic_intr(&s->busdev.qdev) || !pic_get_output(isa_pic)) {
cpu_reset_interrupt(cpu, CPU_INTERRUPT_HARD);
}
}
@@ -567,7 +571,10 @@ int apic_get_interrupt(DeviceState *dev)
apic_sync_vapic(s, SYNC_FROM_VAPIC);
intno = apic_irq_pending(s);
if (intno == 0) {
/* if there is an interrupt from the 8259, let the caller handle
* that first since ExtINT interrupts ignore the priority.
*/
if (intno == 0 || apic_check_pic(s)) {
apic_sync_vapic(s, SYNC_TO_VAPIC);
return -1;
} else if (intno < 0) {
@@ -578,9 +585,6 @@ int apic_get_interrupt(DeviceState *dev)
apic_set_bit(s->isr, intno);
apic_sync_vapic(s, SYNC_TO_VAPIC);
/* re-inject if there is still a pending PIC interrupt */
apic_check_pic(s);
apic_update_irq(s);
return intno;

View File

@@ -139,19 +139,34 @@ static int pc_dimm_built_list(Object *obj, void *opaque)
uint64_t pc_dimm_get_free_addr(uint64_t address_space_start,
uint64_t address_space_size,
uint64_t *hint, uint64_t size,
uint64_t *hint, uint64_t align, uint64_t size,
Error **errp)
{
GSList *list = NULL, *item;
uint64_t new_addr, ret = 0;
uint64_t address_space_end = address_space_start + address_space_size;
g_assert(QEMU_ALIGN_UP(address_space_start, align) == address_space_start);
g_assert(QEMU_ALIGN_UP(address_space_size, align) == address_space_size);
if (!address_space_size) {
error_setg(errp, "memory hotplug is not enabled, "
"please add maxmem option");
goto out;
}
if (hint && QEMU_ALIGN_UP(*hint, align) != *hint) {
error_setg(errp, "address must be aligned to 0x%" PRIx64 " bytes",
align);
goto out;
}
if (QEMU_ALIGN_UP(size, align) != size) {
error_setg(errp, "backend memory size must be multiple of 0x%"
PRIx64, align);
goto out;
}
assert(address_space_end > address_space_start);
object_child_foreach(qdev_get_machine(), pc_dimm_built_list, &list);
@@ -177,7 +192,7 @@ uint64_t pc_dimm_get_free_addr(uint64_t address_space_start,
error_setg(errp, "address range conflicts with '%s'", d->id);
goto out;
}
new_addr = dimm->addr + dimm_size;
new_addr = QEMU_ALIGN_UP(dimm->addr + dimm_size, align);
}
}
ret = new_addr;

View File

@@ -1212,7 +1212,7 @@ static void pcnet_transmit(PCNetState *s)
hwaddr xmit_cxda = 0;
int count = CSR_XMTRL(s)-1;
int add_crc = 0;
int bcnt;
s->xmit_pos = -1;
if (!CSR_TXON(s)) {
@@ -1247,35 +1247,40 @@ static void pcnet_transmit(PCNetState *s)
s->xmit_pos = -1;
goto txdone;
}
if (!GET_FIELD(tmd.status, TMDS, ENP)) {
int bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr),
s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s));
s->xmit_pos += bcnt;
} else if (s->xmit_pos >= 0) {
int bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr),
s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s));
s->xmit_pos += bcnt;
#ifdef PCNET_DEBUG
printf("pcnet_transmit size=%d\n", s->xmit_pos);
#endif
if (CSR_LOOP(s)) {
if (BCR_SWSTYLE(s) == 1)
add_crc = !GET_FIELD(tmd.status, TMDS, NOFCS);
s->looptest = add_crc ? PCNET_LOOPTEST_CRC : PCNET_LOOPTEST_NOCRC;
pcnet_receive(qemu_get_queue(s->nic), s->buffer, s->xmit_pos);
s->looptest = 0;
} else
if (s->nic)
qemu_send_packet(qemu_get_queue(s->nic), s->buffer,
s->xmit_pos);
s->csr[0] &= ~0x0008; /* clear TDMD */
s->csr[4] |= 0x0004; /* set TXSTRT */
s->xmit_pos = -1;
if (s->xmit_pos < 0) {
goto txdone;
}
bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr),
s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s));
s->xmit_pos += bcnt;
if (!GET_FIELD(tmd.status, TMDS, ENP)) {
goto txdone;
}
#ifdef PCNET_DEBUG
printf("pcnet_transmit size=%d\n", s->xmit_pos);
#endif
if (CSR_LOOP(s)) {
if (BCR_SWSTYLE(s) == 1)
add_crc = !GET_FIELD(tmd.status, TMDS, NOFCS);
s->looptest = add_crc ? PCNET_LOOPTEST_CRC : PCNET_LOOPTEST_NOCRC;
pcnet_receive(qemu_get_queue(s->nic), s->buffer, s->xmit_pos);
s->looptest = 0;
} else {
if (s->nic) {
qemu_send_packet(qemu_get_queue(s->nic), s->buffer,
s->xmit_pos);
}
}
s->csr[0] &= ~0x0008; /* clear TDMD */
s->csr[4] |= 0x0004; /* set TXSTRT */
s->xmit_pos = -1;
txdone:
SET_FIELD(&tmd.status, TMDS, OWN, 0);
TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));

View File

@@ -1775,6 +1775,7 @@ static void rtl8139_transfer_frame(RTL8139State *s, uint8_t *buf, int size,
int do_interrupt, const uint8_t *dot1q_buf)
{
struct iovec *iov = NULL;
struct iovec vlan_iov[3];
if (!size)
{
@@ -1789,6 +1790,9 @@ static void rtl8139_transfer_frame(RTL8139State *s, uint8_t *buf, int size,
{ .iov_base = buf + ETHER_ADDR_LEN * 2,
.iov_len = size - ETHER_ADDR_LEN * 2 },
};
memcpy(vlan_iov, iov, sizeof(vlan_iov));
iov = vlan_iov;
}
if (TxLoopBack == (s->TxConfig & TxLoopBack))

View File

@@ -798,7 +798,7 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
virtio_net_ctrl_ack status = VIRTIO_NET_ERR;
VirtQueueElement elem;
size_t s;
struct iovec *iov;
struct iovec *iov, *iov2;
unsigned int iov_cnt;
while (virtqueue_pop(vq, &elem)) {
@@ -808,8 +808,8 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
exit(1);
}
iov = elem.out_sg;
iov_cnt = elem.out_num;
iov2 = iov = g_memdup(elem.out_sg, sizeof(struct iovec) * elem.out_num);
s = iov_to_buf(iov, iov_cnt, 0, &ctrl, sizeof(ctrl));
iov_discard_front(&iov, &iov_cnt, sizeof(ctrl));
if (s != sizeof(ctrl)) {
@@ -833,6 +833,7 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
virtqueue_push(vq, &elem, sizeof(status));
virtio_notify(vdev, vq);
g_free(iov2);
}
}

View File

@@ -523,6 +523,7 @@ void *fw_cfg_modify_file(FWCfgState *s, const char *filename,
void *data, size_t len)
{
int i, index;
void *ptr = NULL;
assert(s->files);
@@ -531,8 +532,10 @@ void *fw_cfg_modify_file(FWCfgState *s, const char *filename,
for (i = 0; i < index; i++) {
if (strcmp(filename, s->files->f[i].name) == 0) {
return fw_cfg_modify_bytes_read(s, FW_CFG_FILE_FIRST + i,
data, len);
ptr = fw_cfg_modify_bytes_read(s, FW_CFG_FILE_FIRST + i,
data, len);
s->files->f[i].size = cpu_to_be32(len);
return ptr;
}
}
/* add new one */

View File

@@ -145,7 +145,7 @@ void pcie_cap_deverr_init(PCIDevice *dev)
PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE);
pci_long_test_and_set_mask(dev->w1cmask + pos + PCI_EXP_DEVSTA,
PCI_EXP_DEVSTA_CED | PCI_EXP_DEVSTA_NFED |
PCI_EXP_DEVSTA_URD | PCI_EXP_DEVSTA_URD);
PCI_EXP_DEVSTA_FED | PCI_EXP_DEVSTA_URD);
}
void pcie_cap_deverr_reset(PCIDevice *dev)
@@ -229,7 +229,7 @@ static void pcie_cap_slot_hotplug_common(PCIDevice *hotplug_dev,
/* the slot is electromechanically locked.
* This error is propagated up to qdev and then to HMP/QMP.
*/
error_setg_errno(errp, -EBUSY, "slot is electromechanically locked");
error_setg_errno(errp, EBUSY, "slot is electromechanically locked");
}
}

View File

@@ -663,6 +663,7 @@ void shpc_cleanup(PCIDevice *d, MemoryRegion *bar)
SHPCDevice *shpc = d->shpc;
d->cap_present &= ~QEMU_PCI_CAP_SHPC;
memory_region_del_subregion(bar, &shpc->mmio);
object_unparent(OBJECT(&shpc->mmio));
/* TODO: cleanup config space changes? */
g_free(shpc->config);
g_free(shpc->cmask);

View File

@@ -233,6 +233,7 @@ static void vhost_scsi_realize(DeviceState *dev, Error **errp)
vhost_dummy_handle_output);
if (err != NULL) {
error_propagate(errp, err);
close(vhostfd);
return;
}

View File

@@ -817,10 +817,12 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
int i, r;
if (vhost_set_backend_type(hdev, backend_type) < 0) {
close((uintptr_t)opaque);
return -1;
}
if (hdev->vhost_ops->vhost_backend_init(hdev, opaque) < 0) {
close((uintptr_t)opaque);
return -errno;
}

View File

@@ -113,20 +113,22 @@ static void virtio_rng_save(QEMUFile *f, void *opaque)
static int virtio_rng_load(QEMUFile *f, void *opaque, int version_id)
{
VirtIORNG *vrng = opaque;
int ret;
if (version_id != 1) {
return -EINVAL;
}
return virtio_load(VIRTIO_DEVICE(opaque), f, version_id);
}
ret = virtio_load(VIRTIO_DEVICE(vrng), f, version_id);
if (ret != 0) {
return ret;
}
static int virtio_rng_load_device(VirtIODevice *vdev, QEMUFile *f,
int version_id)
{
/* We may have an element ready but couldn't process it due to a quota
* limit. Make sure to try again after live migration when the quota may
* have been reset.
*/
virtio_rng_process(VIRTIO_RNG(vdev));
virtio_rng_process(vrng);
return 0;
}
@@ -231,7 +233,6 @@ static void virtio_rng_class_init(ObjectClass *klass, void *data)
vdc->realize = virtio_rng_device_realize;
vdc->unrealize = virtio_rng_device_unrealize;
vdc->get_features = get_features;
vdc->load = virtio_rng_load_device;
}
static void virtio_rng_initfn(Object *obj)

View File

@@ -333,7 +333,7 @@ extern uintptr_t tci_tb_ptr;
#if !defined(CONFIG_USER_ONLY)
void phys_mem_set_alloc(void *(*alloc)(size_t));
void phys_mem_set_alloc(void *(*alloc)(size_t, uint64_t *align));
struct MemoryRegion *iotlb_to_region(AddressSpace *as, hwaddr index);
bool io_mem_read(struct MemoryRegion *mr, hwaddr addr,

View File

@@ -146,6 +146,7 @@ struct MemoryRegion {
hwaddr addr;
void (*destructor)(MemoryRegion *mr);
ram_addr_t ram_addr;
uint64_t align;
bool subpage;
bool terminates;
bool romd_mode;
@@ -838,6 +839,7 @@ void memory_region_add_subregion_overlap(MemoryRegion *mr,
*/
ram_addr_t memory_region_get_ram_addr(MemoryRegion *mr);
uint64_t memory_region_get_alignment(const MemoryRegion *mr);
/**
* memory_region_del_subregion: Remove a subregion.
*

View File

@@ -24,6 +24,8 @@
* address space begins.
* @hotplug_memory: hotplug memory addess space container
* @acpi_dev: link to ACPI PM device that performs ACPI hotplug handling
* @enforce_aligned_dimm: check that DIMM's address/size is aligned by
* backend's alignment value if provided
*/
struct PCMachineState {
/*< private >*/
@@ -37,13 +39,15 @@ struct PCMachineState {
ISADevice *rtc;
uint64_t max_ram_below_4g;
bool vmport;
OnOffAuto vmport;
bool enforce_aligned_dimm;
};
#define PC_MACHINE_ACPI_DEVICE_PROP "acpi-device"
#define PC_MACHINE_MEMHP_REGION_SIZE "hotplug-memory-region-size"
#define PC_MACHINE_MAX_RAM_BELOW_4G "max-ram-below-4g"
#define PC_MACHINE_VMPORT "vmport"
#define PC_MACHINE_ENFORCE_ALIGNED_DIMM "enforce-aligned-dimm"
/**
* PCMachineClass:

View File

@@ -59,7 +59,7 @@ extern bool rom_file_has_mr;
int rom_add_file(const char *file, const char *fw_dir,
hwaddr addr, int32_t bootindex,
bool option_rom);
void *rom_add_blob(const char *name, const void *blob, size_t len,
ram_addr_t rom_add_blob(const char *name, const void *blob, size_t len,
hwaddr addr, const char *fw_file_name,
FWCfgReadCallback fw_callback, void *callback_opaque);
int rom_add_elf_program(const char *name, void *data, size_t datasize,

View File

@@ -72,7 +72,7 @@ typedef struct PCDIMMDeviceClass {
uint64_t pc_dimm_get_free_addr(uint64_t address_space_start,
uint64_t address_space_size,
uint64_t *hint, uint64_t size,
uint64_t *hint, uint64_t align, uint64_t size,
Error **errp);
int pc_dimm_get_free_slot(const int *hint, int max_slots, Error **errp);

View File

@@ -365,7 +365,7 @@ extern int qdev_hotplug;
char *qdev_get_dev_path(DeviceState *dev);
int qdev_build_hotpluggable_device_list(Object *obj, void *opaque);
GSList *qdev_build_hotpluggable_device_list(Object *peripheral);
void qbus_set_hotplug_handler(BusState *bus, DeviceState *handler,
Error **errp);

View File

@@ -5,6 +5,7 @@
#include <stdarg.h>
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include <sys/types.h>
#ifdef __OpenBSD__
#include <sys/signal.h>
@@ -103,7 +104,7 @@ typedef signed int int_fast16_t;
int qemu_daemon(int nochdir, int noclose);
void *qemu_try_memalign(size_t alignment, size_t size);
void *qemu_memalign(size_t alignment, size_t size);
void *qemu_anon_ram_alloc(size_t size);
void *qemu_anon_ram_alloc(size_t size, uint64_t *align);
void qemu_vfree(void *ptr);
void qemu_anon_ram_free(void *ptr, size_t size);

View File

@@ -163,6 +163,7 @@ extern KVMState *kvm_state;
/* external API */
bool kvm_has_free_slot(MachineState *ms);
int kvm_has_sync_mmu(void);
int kvm_has_vcpu_events(void);
int kvm_has_robust_singlestep(void);

View File

@@ -132,7 +132,7 @@ static const KVMCapabilityInfo kvm_required_capabilites[] = {
KVM_CAP_LAST_INFO
};
static KVMSlot *kvm_alloc_slot(KVMState *s)
static KVMSlot *kvm_get_free_slot(KVMState *s)
{
int i;
@@ -142,6 +142,22 @@ static KVMSlot *kvm_alloc_slot(KVMState *s)
}
}
return NULL;
}
bool kvm_has_free_slot(MachineState *ms)
{
return kvm_get_free_slot(KVM_STATE(ms->accelerator));
}
static KVMSlot *kvm_alloc_slot(KVMState *s)
{
KVMSlot *slot = kvm_get_free_slot(s);
if (slot) {
return slot;
}
fprintf(stderr, "%s: no free slot available\n", __func__);
abort();
}
@@ -634,8 +650,10 @@ static void kvm_set_phys_mem(MemoryRegionSection *section, bool add)
unsigned delta;
/* kvm works in page size chunks, but the function may be called
with sub-page size and unaligned start address. */
delta = TARGET_PAGE_ALIGN(size) - size;
with sub-page size and unaligned start address. Pad the start
address to next and truncate size to previous page boundary. */
delta = (TARGET_PAGE_SIZE - (start_addr & ~TARGET_PAGE_MASK));
delta &= ~TARGET_PAGE_MASK;
if (delta > size) {
return;
}

View File

@@ -147,4 +147,9 @@ int kvm_irqchip_remove_irqfd_notifier(KVMState *s, EventNotifier *n, int virq)
{
return -ENOSYS;
}
bool kvm_has_free_slot(MachineState *ms)
{
return false;
}
#endif

View File

@@ -1749,6 +1749,11 @@ ram_addr_t memory_region_get_ram_addr(MemoryRegion *mr)
return mr->ram_addr;
}
uint64_t memory_region_get_alignment(const MemoryRegion *mr)
{
return mr->align;
}
static int cmp_flatrange_addr(const void *addr_, const void *fr_)
{
const AddrRange *addr = addr_;

View File

@@ -4321,17 +4321,14 @@ void object_add_completion(ReadLineState *rs, int nb_args, const char *str)
static void peripheral_device_del_completion(ReadLineState *rs,
const char *str, size_t len)
{
Object *peripheral;
GSList *list = NULL, *item;
Object *peripheral = container_get(qdev_get_machine(), "/peripheral");
GSList *list, *item;
peripheral = object_resolve_path("/machine/peripheral/", NULL);
if (peripheral == NULL) {
list = qdev_build_hotpluggable_device_list(peripheral);
if (!list) {
return;
}
object_child_foreach(peripheral, qdev_build_hotpluggable_device_list,
&list);
for (item = list; item; item = g_slist_next(item)) {
DeviceState *dev = item->data;

View File

@@ -643,17 +643,16 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str,
goto fail_syntax;
}
fwd = g_malloc(sizeof(struct GuestFwd));
snprintf(buf, sizeof(buf), "guestfwd.tcp.%d", port);
if ((strlen(p) > 4) && !strncmp(p, "cmd:", 4)) {
if (slirp_add_exec(s->slirp, 0, &p[4], &server, port) < 0) {
error_report("conflicting/invalid host:port in guest forwarding "
"rule '%s'", config_str);
g_free(fwd);
return -1;
}
} else {
fwd = g_malloc(sizeof(struct GuestFwd));
fwd->hd = qemu_chr_new(buf, p, NULL);
if (!fwd->hd) {
error_report("could not open guest forwarding device '%s'", buf);

View File

@@ -389,11 +389,6 @@ static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer,
nc = qemu_new_net_client(&net_dgram_socket_info, peer, model, name);
snprintf(nc->info_str, sizeof(nc->info_str),
"socket: fd=%d (%s mcast=%s:%d)",
fd, is_connected ? "cloned" : "",
inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
s = DO_UPCAST(NetSocketState, nc, nc);
s->fd = fd;
@@ -404,6 +399,12 @@ static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer,
/* mcast: save bound address as dst */
if (is_connected) {
s->dgram_dst = saddr;
snprintf(nc->info_str, sizeof(nc->info_str),
"socket: fd=%d (cloned mcast=%s:%d)",
fd, inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
} else {
snprintf(nc->info_str, sizeof(nc->info_str),
"socket: fd=%d", fd);
}
return s;

View File

@@ -3245,7 +3245,7 @@
'abs' : 'InputMoveEvent' } }
##
# @input-send-event
# @x-input-send-event
#
# Send input event(s) to guest.
#
@@ -3257,8 +3257,10 @@
#
# Since: 2.2
#
# Note: this command is experimental, and not a stable API.
#
##
{ 'command': 'input-send-event',
{ 'command': 'x-input-send-event',
'data': { '*console':'int', 'events': [ 'InputEvent' ] } }
##

View File

@@ -119,8 +119,6 @@
# @format-specific: #optional structure supplying additional format-specific
# information (since 1.7)
#
# @nocow: #optional info of whether NOCOW flag is set or not. (since 2.2)
#
# Since: 1.3
#
##
@@ -132,8 +130,7 @@
'*backing-filename': 'str', '*full-backing-filename': 'str',
'*backing-filename-format': 'str', '*snapshots': ['SnapshotInfo'],
'*backing-image': 'ImageInfo',
'*format-specific': 'ImageInfoSpecific',
'*nocow': 'bool' } }
'*format-specific': 'ImageInfoSpecific' } }
##
# @ImageCheck:

View File

@@ -87,3 +87,18 @@
##
{ 'command': 'query-commands', 'returns': ['CommandInfo'] }
##
# @OnOffAuto
#
# An enumeration of three options: on, off, and auto
#
# @auto: QEMU selects the value between on and off
#
# @on: Enabled
#
# @off: Disabled
#
# Since: 2.2
##
{ 'enum': 'OnOffAuto',
'data': [ 'auto', 'on', 'off' ] }

View File

@@ -88,6 +88,7 @@
#define READ_BUF_LEN 4096
#define READ_RETRIES 10
#define CHR_MAX_FILENAME_SIZE 256
#define TCP_MAX_FDS 16
/***********************************************************/
/* Socket address helpers */
@@ -2668,6 +2669,8 @@ static int tcp_get_msgfds(CharDriverState *chr, int *fds, int num)
TCPCharDriver *s = chr->opaque;
int to_copy = (s->read_msgfds_num < num) ? s->read_msgfds_num : num;
assert(num <= TCP_MAX_FDS);
if (to_copy) {
int i;
@@ -2762,7 +2765,7 @@ static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len)
struct iovec iov[1];
union {
struct cmsghdr cmsg;
char control[CMSG_SPACE(sizeof(int))];
char control[CMSG_SPACE(sizeof(int) * TCP_MAX_FDS)];
} msg_control;
int flags = 0;
ssize_t ret;

View File

@@ -33,7 +33,7 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
" property accel=accel1[:accel2[:...]] selects accelerator\n"
" supported accelerators are kvm, xen, tcg (default: tcg)\n"
" kernel_irqchip=on|off controls accelerated irqchip support\n"
" vmport=on|off controls emulation of vmport (default: on)\n"
" vmport=on|off|auto controls emulation of vmport (default: auto)\n"
" kvm_shadow_mem=size of KVM shadow MMU\n"
" dump-guest-core=on|off include guest memory in a core dump (default=on)\n"
" mem-merge=on|off controls memory merge support (default: on)\n"
@@ -52,8 +52,10 @@ than one accelerator specified, the next one is used if the previous one fails
to initialize.
@item kernel_irqchip=on|off
Enables in-kernel irqchip support for the chosen accelerator when available.
@item vmport=on|off
Enables emulation of VMWare IO port, for vmmouse etc. (enabled by default)
@item vmport=on|off|auto
Enables emulation of VMWare IO port, for vmmouse etc. auto says to select the
value based on accel. For accel=xen the default is off otherwise the default
is on.
@item kvm_shadow_mem=size
Defines the size of the KVM shadow MMU.
@item dump-guest-core=on|off

View File

@@ -314,7 +314,14 @@ int qemu_poll_ns(GPollFD *fds, guint nfds, int64_t timeout)
return ppoll((struct pollfd *)fds, nfds, NULL, NULL);
} else {
struct timespec ts;
ts.tv_sec = timeout / 1000000000LL;
int64_t tvsec = timeout / 1000000000LL;
/* Avoid possibly overflowing and specifying a negative number of
* seconds, which would turn a very long timeout into a busy-wait.
*/
if (tvsec > (int64_t)INT32_MAX) {
tvsec = INT32_MAX;
}
ts.tv_sec = tvsec;
ts.tv_nsec = timeout % 1000000000LL;
return ppoll((struct pollfd *)fds, nfds, &ts, NULL);
}

View File

@@ -3791,13 +3791,13 @@ Example:
EQMP
{
.name = "input-send-event",
.name = "x-input-send-event",
.args_type = "console:i?,events:q",
.mhandler.cmd_new = qmp_marshal_input_input_send_event,
.mhandler.cmd_new = qmp_marshal_input_x_input_send_event,
},
SQMP
@input-send-event
@x-input-send-event
-----------------
Send input event to guest.
@@ -3811,17 +3811,19 @@ The consoles are visible in the qom tree, under
/backend/console[$index]. They have a device link and head property, so
it is possible to map which console belongs to which device and display.
Note: this command is experimental, and not a stable API.
Example (1):
Press left mouse button.
-> { "execute": "input-send-event",
-> { "execute": "x-input-send-event",
"arguments": { "console": 0,
"events": [ { "type": "btn",
"data" : { "down": true, "button": "Left" } } } }
<- { "return": {} }
-> { "execute": "input-send-event",
-> { "execute": "x-input-send-event",
"arguments": { "console": 0,
"events": [ { "type": "btn",
"data" : { "down": false, "button": "Left" } } } }
@@ -3831,7 +3833,7 @@ Example (2):
Press ctrl-alt-del.
-> { "execute": "input-send-event",
-> { "execute": "x-input-send-event",
"arguments": { "console": 0, "events": [
{ "type": "key", "data" : { "down": true,
"key": {"type": "qcode", "data": "ctrl" } } },
@@ -3845,7 +3847,7 @@ Example (3):
Move mouse pointer to absolute coordinates (20000, 400).
-> { "execute": "input-send-event" ,
-> { "execute": "x-input-send-event" ,
"arguments": { "console": 0, "events": [
{ "type": "abs", "data" : { "axis": "X", "value" : 20000 } },
{ "type": "abs", "data" : { "axis": "Y", "value" : 400 } } ] } }

View File

@@ -2912,8 +2912,14 @@ static bool x86_cpu_has_work(CPUState *cs)
X86CPU *cpu = X86_CPU(cs);
CPUX86State *env = &cpu->env;
return ((cs->interrupt_request & (CPU_INTERRUPT_HARD |
CPU_INTERRUPT_POLL)) &&
#if !defined(CONFIG_USER_ONLY)
if (cs->interrupt_request & CPU_INTERRUPT_POLL) {
apic_poll_irq(cpu->apic_state);
cpu_reset_interrupt(cs, CPU_INTERRUPT_POLL);
}
#endif
return ((cs->interrupt_request & CPU_INTERRUPT_HARD) &&
(env->eflags & IF_MASK)) ||
(cs->interrupt_request & (CPU_INTERRUPT_NMI |
CPU_INTERRUPT_INIT |

View File

@@ -6848,7 +6848,7 @@ static void gen_mtvscr(DisasContext *ctx)
gen_exception(ctx, POWERPC_EXCP_VPU);
return;
}
p = gen_avr_ptr(rD(ctx->opcode));
p = gen_avr_ptr(rB(ctx->opcode));
gen_helper_mtvscr(cpu_env, p);
tcg_temp_free_ptr(p);
}

View File

@@ -4374,32 +4374,6 @@ static void init_proc_G2LE (CPUPPCState *env)
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
/* Breakpoints */
/* XXX : not implemented */
spr_register(env, SPR_DABR, "DABR",
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
/* XXX : not implemented */
spr_register(env, SPR_DABR2, "DABR2",
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
/* XXX : not implemented */
spr_register(env, SPR_IABR2, "IABR2",
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
/* XXX : not implemented */
spr_register(env, SPR_IBCR, "IBCR",
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
/* XXX : not implemented */
spr_register(env, SPR_DBCR, "DBCR",
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
/* Memory management */
gen_low_BATs(env);
@@ -4628,6 +4602,32 @@ static void init_proc_e300 (CPUPPCState *env)
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
/* Breakpoints */
/* XXX : not implemented */
spr_register(env, SPR_DABR, "DABR",
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
/* XXX : not implemented */
spr_register(env, SPR_DABR2, "DABR2",
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
/* XXX : not implemented */
spr_register(env, SPR_IABR2, "IABR2",
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
/* XXX : not implemented */
spr_register(env, SPR_IBCR, "IBCR",
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
/* XXX : not implemented */
spr_register(env, SPR_DBCR, "DBCR",
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
/* Memory management */
gen_low_BATs(env);
gen_high_BATs(env);

View File

@@ -106,7 +106,7 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
static int cap_sync_regs;
static int cap_async_pf;
static void *legacy_s390_alloc(size_t size);
static void *legacy_s390_alloc(size_t size, uint64_t *align);
static int kvm_s390_check_clear_cmma(KVMState *s)
{
@@ -404,7 +404,7 @@ int kvm_arch_get_registers(CPUState *cs)
* to grow. We also have to use MAP parameters that avoid
* read-only mapping of guest pages.
*/
static void *legacy_s390_alloc(size_t size)
static void *legacy_s390_alloc(size_t size, uint64_t *align)
{
void *mem;

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1666,10 +1666,9 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc,
QemuConsole *con, int idx,
GSList *group, GtkWidget *view_menu)
{
Error *local_err = NULL;
Object *obj;
obj = object_property_get_link(OBJECT(con), "device", &local_err);
obj = object_property_get_link(OBJECT(con), "device", NULL);
if (obj) {
vc->label = g_strdup_printf("%s", object_get_typename(obj));
} else {
@@ -1910,15 +1909,17 @@ void gtk_display_init(DisplayState *ds, bool full_screen, bool grab_on_hover)
#ifdef VTE_RESIZE_HACK
{
VirtualConsole *cur = gd_vc_find_current(s);
int i;
if (cur) {
int i;
for (i = 0; i < s->nb_vcs; i++) {
VirtualConsole *vc = &s->vc[i];
if (vc && vc->type == GD_VC_VTE && vc != cur) {
gtk_widget_hide(vc->vte.terminal);
for (i = 0; i < s->nb_vcs; i++) {
VirtualConsole *vc = &s->vc[i];
if (vc && vc->type == GD_VC_VTE && vc != cur) {
gtk_widget_hide(vc->vte.terminal);
}
}
gd_update_windowsize(cur);
}
gd_update_windowsize(cur);
}
#endif

View File

@@ -122,8 +122,8 @@ qemu_input_find_handler(uint32_t mask, QemuConsole *con)
return NULL;
}
void qmp_input_send_event(bool has_console, int64_t console,
InputEventList *events, Error **errp)
void qmp_x_input_send_event(bool has_console, int64_t console,
InputEventList *events, Error **errp)
{
InputEventList *e;
QemuConsole *con;

View File

@@ -124,7 +124,7 @@ void *qemu_memalign(size_t alignment, size_t size)
}
/* alloc shared memory pages */
void *qemu_anon_ram_alloc(size_t size)
void *qemu_anon_ram_alloc(size_t size, uint64_t *alignment)
{
size_t align = QEMU_VMALLOC_ALIGN;
size_t total = size + align - getpagesize();
@@ -136,6 +136,9 @@ void *qemu_anon_ram_alloc(size_t size)
return NULL;
}
if (alignment) {
*alignment = align;
}
ptr += offset;
total -= offset;

View File

@@ -67,7 +67,7 @@ void *qemu_memalign(size_t alignment, size_t size)
return qemu_oom_check(qemu_try_memalign(alignment, size));
}
void *qemu_anon_ram_alloc(size_t size)
void *qemu_anon_ram_alloc(size_t size, uint64_t *align)
{
void *ptr;

2
vl.c
View File

@@ -381,7 +381,7 @@ static QemuOptsList qemu_machine_opts = {
.help = "maximum ram below the 4G boundary (32bit boundary)",
}, {
.name = PC_MACHINE_VMPORT,
.type = QEMU_OPT_BOOL,
.type = QEMU_OPT_STRING,
.help = "Enable vmport (pc & q35)",
},{
.name = "iommu",