* KVM page size fix for PPC

* Support for Linux 4.4's new Hyper-V features
 * Eliminate g_slice from areas I maintain
 * checkpatch fix
 * Peter's cpu_reload_memory_map() cleanups
 * More changes to MAINTAINERS
 * Require Python 2.6
 * chardev creation fixes
 * PCI requester id for ARM KVM
 * cleanups and doc fixes
 * Allow customization of the Hyper-V vendor id
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2
 
 iQEcBAABCAAGBQJWJKYWAAoJEL/70l94x66D2yYH/Rw06gj9FFVEhfNODmJozCsK
 zRqRREo+VMo/lIGUSwzI+OCX+yUoivxnsJXchqunK0udPuQ5vZ+mVGyKedg8/SU+
 uqXzXMK7QgJK/w7qNA1n0OacNYSosZz9MpOwPgzSLPRda8FbtVKqPBOugSEs+Ymg
 APtiumz3DGWXUmt+vqRdgdiAvoGkefPODjjPjfSQFukg205KR88tf/b9oN8Z+kDW
 LtGqG9dUNS/60ulLNQdFInn3x5WpuGky5kk57f47QHpInNcN4/CH0BiguvYNkA9A
 aFFEWj5RsK7xkhcwSw6JIaSoWoTdrQVd4mB6+WTZN4tfGIIaoDeI6fp2MFmVpZU=
 =9Tf9
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging

* KVM page size fix for PPC
* Support for Linux 4.4's new Hyper-V features
* Eliminate g_slice from areas I maintain
* checkpatch fix
* Peter's cpu_reload_memory_map() cleanups
* More changes to MAINTAINERS
* Require Python 2.6
* chardev creation fixes
* PCI requester id for ARM KVM
* cleanups and doc fixes
* Allow customization of the Hyper-V vendor id

# gpg: Signature made Mon 19 Oct 2015 09:13:10 BST using RSA key ID 78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>"
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>"

* remotes/bonzini/tags/for-upstream: (49 commits)
  kvm: Allow the Hyper-V vendor ID to be specified
  kvm: Move x86-specific functions into target-i386/kvm.c
  kvm: Pass PCI device pointer to MSI routing functions
  hw/pci: Introduce pci_requester_id()
  kvm: Make KVM_CAP_SIGNAL_MSI globally available
  doc/rcu: fix g_free_rcu() usage example
  qemu-char: cleanup after completed conversion to cd->create
  qemu-char: convert ringbuf backend to data-driven creation
  qemu-char: convert vc backend to data-driven creation
  qemu-char: convert spice backend to data-driven creation
  qemu-char: convert console backend to data-driven creation
  qemu-char: convert stdio backend to data-driven creation
  qemu-char: convert testdev backend to data-driven creation
  qemu-char: convert braille backend to data-driven creation
  qemu-char: convert msmouse backend to data-driven creation
  qemu-char: convert mux backend to data-driven creation
  qemu-char: convert null backend to data-driven creation
  qemu-char: convert pty backend to data-driven creation
  qemu-char: convert UDP backend to data-driven creation
  qemu-char: convert socket backend to data-driven creation
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
stable-2.5
Peter Maydell 2015-10-19 10:52:39 +01:00
commit 526d5809a0
55 changed files with 723 additions and 444 deletions

View File

@ -255,6 +255,12 @@ L: xen-devel@lists.xensource.com
S: Supported
F: xen-*
F: */xen*
F: hw/char/xen_console.c
F: hw/display/xenfb.c
F: hw/net/xen_nic.c
F: hw/xen/
F: hw/xenpv/
F: include/hw/xen/
Hosts:
------
@ -286,6 +292,36 @@ F: hw/*/allwinner*
F: include/hw/*/allwinner*
F: hw/arm/cubieboard.c
ARM PrimeCell
M: Peter Maydell <peter.maydell@linaro.org>
S: Maintained
F: hw/char/pl011.c
F: hw/display/pl110*
F: hw/dma/pl080.c
F: hw/dma/pl330.c
F: hw/gpio/pl061.c
F: hw/input/pl050.c
F: hw/intc/pl190.c
F: hw/sd/pl181.c
F: hw/timer/pl031.c
F: include/hw/arm/primecell.h
ARM cores
M: Peter Maydell <peter.maydell@linaro.org>
S: Maintained
F: hw/intc/arm*
F: hw/intc/gic_internal.h
F: hw/misc/a9scu.c
F: hw/misc/arm11scu.c
F: hw/timer/a9gtimer*
F: hw/timer/arm_*
F: include/hw/arm/arm.h
F: include/hw/intc/arm*
F: include/hw/misc/a9scu.h
F: include/hw/misc/arm11scu.h
F: include/hw/timer/a9gtimer.h
F: include/hw/timer/arm_mptimer.h
Exynos
M: Evgeny Voevodin <e.voevodin@samsung.com>
M: Maksim Kozlov <m.kozlov@samsung.com>
@ -322,11 +358,6 @@ M: Peter Maydell <peter.maydell@linaro.org>
S: Maintained
F: hw/arm/integratorcp.c
Mainstone
L: qemu-devel@nongnu.org
S: Orphan
F: hw/arm/mainstone.c
Musicpal
M: Jan Kiszka <jan.kiszka@web.de>
S: Maintained
@ -346,11 +377,17 @@ Real View
M: Peter Maydell <peter.maydell@linaro.org>
S: Maintained
F: hw/arm/realview*
F: hw/intc/realview_gic.c
F: include/hw/intc/realview_gic.h
Spitz
PXA2XX
M: Andrzej Zaborowski <balrogg@gmail.com>
S: Maintained
F: hw/arm/mainstone.c
F: hw/arm/spitz.c
F: hw/arm/tosa.c
F: hw/arm/z2.c
F: hw/*/pxa2xx*
Stellaris
M: Peter Maydell <peter.maydell@linaro.org>
@ -726,6 +763,8 @@ M: Scott Wood <scottwood@freescale.com>
L: qemu-ppc@nongnu.org
S: Supported
F: hw/ppc/e500*
F: hw/pci-host/ppce500.c
F: hw/net/fsl_etsec/
Character devices
M: Paolo Bonzini <pbonzini@redhat.com>

108
README
View File

@ -1,3 +1,107 @@
Read the documentation in qemu-doc.html or on http://wiki.qemu-project.org
QEMU README
===========
- QEMU team
QEMU is a generic and open source machine & userspace emulator and
virtualizer.
QEMU is capable of emulating a complete machine in software without any
need for hardware virtualization support. By using dynamic translation,
it achieves very good performance. QEMU can also integrate with the Xen
and KVM hypervisors to provide emulated hardware while allowing the
hypervisor to manage the CPU. With hypervisor support, QEMU can achieve
near native performance for CPUs. When QEMU emulates CPUs directly it is
capable of running operating systems made for one machine (e.g. an ARMv7
board) on a different machine (e.g. an x86_64 PC board).
QEMU is also capable of providing userspace API virtualization for Linux
and BSD kernel interfaces. This allows binaries compiled against one
architecture ABI (e.g. the Linux PPC64 ABI) to be run on a host using a
different architecture ABI (e.g. the Linux x86_64 ABI). This does not
involve any hardware emulation, simply CPU and syscall emulation.
QEMU aims to fit into a variety of use cases. It can be invoked directly
by users wishing to have full control over its behaviour and settings.
It also aims to facilitate integration into higher level management
layers, by providing a stable command line interface and monitor API.
It is commonly invoked indirectly via the libvirt library when using
open source applications such as oVirt, OpenStack and virt-manager.
QEMU as a whole is released under the GNU General Public License,
version 2. For full licensing details, consult the LICENSE file.
Building
========
QEMU is multi-platform software intended to be buildable on all modern
Linux platforms, OS-X, Win32 (via the Mingw64 toolchain) and a variety
of other UNIX targets. The simple steps to build QEMU are:
mkdir build
cd build
../configure
make
Complete details of the process for building and configuring QEMU for
all supported host platforms can be found in the qemu-tech.html file.
Additional information can also be found online via the QEMU website:
http://qemu-project.org/Hosts/Linux
http://qemu-project.org/Hosts/W32
Submitting patches
==================
The QEMU source code is maintained under the GIT version control system.
git clone git://git.qemu-project.org/qemu.git
When submitting patches, the preferred approach is to use 'git
format-patch' and/or 'git send-email' to format & send the mail to the
qemu-devel@nongnu.org mailing list. All patches submitted must contain
a 'Signed-off-by' line from the author. Patches should follow the
guidelines set out in the HACKING and CODING_STYLE files.
Additional information on submitting patches can be found online via
the QEMU website
http://qemu-project.org/Contribute/SubmitAPatch
http://qemu-project.org/Contribute/TrivialPatches
Bug reporting
=============
The QEMU project uses Launchpad as its primary upstream bug tracker. Bugs
found when running code built from QEMU git or upstream released sources
should be reported via:
https://bugs.launchpad.net/qemu/
If using QEMU via an operating system vendor pre-built binary package, it
is preferable to report bugs to the vendor's own bug tracker first. If
the bug is also known to affect latest upstream code, it can also be
reported via launchpad.
For additional information on bug reporting consult:
http://qemu-project.org/Contribute/ReportABug
Contact
=======
The QEMU community can be contacted in a number of ways, with the two
main methods being email and IRC
- qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel
- #qemu on irc.oftc.net
Information on additional methods of contacting the community can be
found online via the QEMU website:
http://qemu-project.org/Contribute/StartHere
-- End

View File

@ -561,7 +561,10 @@ static void baum_close(struct CharDriverState *chr)
g_free(baum);
}
CharDriverState *chr_baum_init(void)
static CharDriverState *chr_baum_init(const char *id,
ChardevBackend *backend,
ChardevReturn *ret,
Error **errp)
{
BaumDriverState *baum;
CharDriverState *chr;
@ -586,14 +589,16 @@ CharDriverState *chr_baum_init(void)
baum->brlapi_fd = brlapi__openConnection(handle, NULL, NULL);
if (baum->brlapi_fd == -1) {
brlapi_perror("baum_init: brlapi_openConnection");
error_setg(errp, "brlapi__openConnection: %s",
brlapi_strerror(brlapi_error_location()));
goto fail_handle;
}
baum->cellCount_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, baum_cellCount_timer_cb, baum);
if (brlapi__getDisplaySize(handle, &baum->x, &baum->y) == -1) {
brlapi_perror("baum_init: brlapi_getDisplaySize");
error_setg(errp, "brlapi__getDisplaySize: %s",
brlapi_strerror(brlapi_error_location()));
goto fail;
}
@ -609,7 +614,8 @@ CharDriverState *chr_baum_init(void)
tty = BRLAPI_TTY_DEFAULT;
if (brlapi__enterTtyMode(handle, tty, NULL) == -1) {
brlapi_perror("baum_init: brlapi_enterTtyMode");
error_setg(errp, "brlapi__enterTtyMode: %s",
brlapi_strerror(brlapi_error_location()));
goto fail;
}
@ -629,7 +635,8 @@ fail_handle:
static void register_types(void)
{
register_char_driver("braille", CHARDEV_BACKEND_KIND_BRAILLE, NULL);
register_char_driver("braille", CHARDEV_BACKEND_KIND_BRAILLE, NULL,
chr_baum_init);
}
type_init(register_types);

View File

@ -63,7 +63,10 @@ static void msmouse_chr_close (struct CharDriverState *chr)
g_free (chr);
}
CharDriverState *qemu_chr_open_msmouse(void)
static CharDriverState *qemu_chr_open_msmouse(const char *id,
ChardevBackend *backend,
ChardevReturn *ret,
Error **errp)
{
CharDriverState *chr;
@ -79,7 +82,8 @@ CharDriverState *qemu_chr_open_msmouse(void)
static void register_types(void)
{
register_char_driver("msmouse", CHARDEV_BACKEND_KIND_MSMOUSE, NULL);
register_char_driver("msmouse", CHARDEV_BACKEND_KIND_MSMOUSE, NULL,
qemu_chr_open_msmouse);
}
type_init(register_types);

View File

@ -108,7 +108,10 @@ static void testdev_close(struct CharDriverState *chr)
g_free(testdev);
}
CharDriverState *chr_testdev_init(void)
static CharDriverState *chr_testdev_init(const char *id,
ChardevBackend *backend,
ChardevReturn *ret,
Error **errp)
{
TestdevCharState *testdev;
CharDriverState *chr;
@ -125,7 +128,8 @@ CharDriverState *chr_testdev_init(void)
static void register_types(void)
{
register_char_driver("testdev", CHARDEV_BACKEND_KIND_TESTDEV, NULL);
register_char_driver("testdev", CHARDEV_BACKEND_KIND_TESTDEV, NULL,
chr_testdev_init);
}
type_init(register_types);

12
configure vendored
View File

@ -1166,18 +1166,14 @@ fi
# Note that if the Python conditional here evaluates True we will exit
# with status 1 which is a shell 'false' value.
if ! $python -c 'import sys; sys.exit(sys.version_info < (2,4) or sys.version_info >= (3,))'; then
error_exit "Cannot use '$python', Python 2.4 or later is required." \
if ! $python -c 'import sys; sys.exit(sys.version_info < (2,6) or sys.version_info >= (3,))'; then
error_exit "Cannot use '$python', Python 2.6 or later is required." \
"Note that Python 3 or later is not yet supported." \
"Use --python=/path/to/python to specify a supported Python."
fi
# The -B switch was added in Python 2.6.
# If it is supplied, compiled files are not written.
# Use it for Python versions which support it.
if $python -B -c 'import sys; sys.exit(0)' 2>/dev/null; then
python="$python -B"
fi
# Suppress writing compiled files
python="$python -B"
case "$cpu" in
ppc)

View File

@ -37,31 +37,32 @@ void cpu_resume_from_signal(CPUState *cpu, void *puc)
siglongjmp(cpu->jmp_env, 1);
}
void cpu_reload_memory_map(CPUState *cpu)
void cpu_reloading_memory_map(void)
{
AddressSpaceDispatch *d;
if (qemu_in_vcpu_thread()) {
/* Do not let the guest prolong the critical section as much as it
* as it desires.
/* The guest can in theory prolong the RCU critical section as long
* as it feels like. The major problem with this is that because it
* can do multiple reconfigurations of the memory map within the
* critical section, we could potentially accumulate an unbounded
* collection of memory data structures awaiting reclamation.
*
* Currently, this is prevented by the I/O thread's periodinc kicking
* of the VCPU thread (iothread_requesting_mutex, qemu_cpu_kick_thread)
* but this will go away once TCG's execution moves out of the global
* mutex.
* Because the only thing we're currently protecting with RCU is the
* memory data structures, it's sufficient to break the critical section
* in this callback, which we know will get called every time the
* memory map is rearranged.
*
* (If we add anything else in the system that uses RCU to protect
* its data structures, we will need to implement some other mechanism
* to force TCG CPUs to exit the critical section, at which point this
* part of this callback might become unnecessary.)
*
* This pair matches cpu_exec's rcu_read_lock()/rcu_read_unlock(), which
* only protects cpu->as->dispatch. Since we reload it below, we can
* split the critical section.
* only protects cpu->as->dispatch. Since we know our caller is about
* to reload it, it's safe to split the critical section.
*/
rcu_read_unlock();
rcu_read_lock();
}
/* The CPU and TLB are protected by the iothread lock. */
d = atomic_rcu_read(&cpu->as->dispatch);
cpu->memory_dispatch = d;
tlb_flush(cpu, 1);
}
#endif

View File

@ -128,7 +128,7 @@ The core RCU API is small:
the callback function is g_free, in particular, g_free_rcu can be
used. In the above case, one could have written simply:
g_free_rcu(foo_reclaim, rcu);
g_free_rcu(&foo, rcu);
typeof(*p) atomic_rcu_read(p);

57
exec.c
View File

@ -161,6 +161,21 @@ static void memory_map_init(void);
static void tcg_commit(MemoryListener *listener);
static MemoryRegion io_mem_watch;
/**
* CPUAddressSpace: all the information a CPU needs about an AddressSpace
* @cpu: the CPU whose AddressSpace this is
* @as: the AddressSpace itself
* @memory_dispatch: its dispatch pointer (cached, RCU protected)
* @tcg_as_listener: listener for tracking changes to the AddressSpace
*/
struct CPUAddressSpace {
CPUState *cpu;
AddressSpace *as;
struct AddressSpaceDispatch *memory_dispatch;
MemoryListener tcg_as_listener;
};
#endif
#if !defined(CONFIG_USER_ONLY)
@ -431,7 +446,7 @@ address_space_translate_for_iotlb(CPUState *cpu, hwaddr addr,
hwaddr *xlat, hwaddr *plen)
{
MemoryRegionSection *section;
section = address_space_translate_internal(cpu->memory_dispatch,
section = address_space_translate_internal(cpu->cpu_ases[0].memory_dispatch,
addr, xlat, plen, false);
assert(!section->mr->iommu_ops);
@ -537,13 +552,16 @@ void tcg_cpu_address_space_init(CPUState *cpu, AddressSpace *as)
/* We only support one address space per cpu at the moment. */
assert(cpu->as == as);
if (cpu->tcg_as_listener) {
memory_listener_unregister(cpu->tcg_as_listener);
} else {
cpu->tcg_as_listener = g_new0(MemoryListener, 1);
if (cpu->cpu_ases) {
/* We've already registered the listener for our only AS */
return;
}
cpu->tcg_as_listener->commit = tcg_commit;
memory_listener_register(cpu->tcg_as_listener, as);
cpu->cpu_ases = g_new0(CPUAddressSpace, 1);
cpu->cpu_ases[0].cpu = cpu;
cpu->cpu_ases[0].as = as;
cpu->cpu_ases[0].tcg_as_listener.commit = tcg_commit;
memory_listener_register(&cpu->cpu_ases[0].tcg_as_listener, as);
}
#endif
@ -601,7 +619,6 @@ void cpu_exec_init(CPUState *cpu, Error **errp)
#ifndef CONFIG_USER_ONLY
cpu->as = &address_space_memory;
cpu->thread_id = qemu_get_thread_id();
cpu_reload_memory_map(cpu);
#endif
#if defined(CONFIG_USER_ONLY)
@ -2219,7 +2236,8 @@ static uint16_t dummy_section(PhysPageMap *map, AddressSpace *as,
MemoryRegion *iotlb_to_region(CPUState *cpu, hwaddr index)
{
AddressSpaceDispatch *d = atomic_rcu_read(&cpu->memory_dispatch);
CPUAddressSpace *cpuas = &cpu->cpu_ases[0];
AddressSpaceDispatch *d = atomic_rcu_read(&cpuas->memory_dispatch);
MemoryRegionSection *sections = d->map.sections;
return sections[index & ~TARGET_PAGE_MASK].mr;
@ -2278,19 +2296,20 @@ static void mem_commit(MemoryListener *listener)
static void tcg_commit(MemoryListener *listener)
{
CPUState *cpu;
CPUAddressSpace *cpuas;
AddressSpaceDispatch *d;
/* since each CPU stores ram addresses in its TLB cache, we must
reset the modified entries */
/* XXX: slow ! */
CPU_FOREACH(cpu) {
/* FIXME: Disentangle the cpu.h circular files deps so we can
directly get the right CPU from listener. */
if (cpu->tcg_as_listener != listener) {
continue;
}
cpu_reload_memory_map(cpu);
}
cpuas = container_of(listener, CPUAddressSpace, tcg_as_listener);
cpu_reloading_memory_map();
/* The CPU and TLB are protected by the iothread lock.
* We reload the dispatch pointer now because cpu_reloading_memory_map()
* may have split the RCU critical section.
*/
d = atomic_rcu_read(&cpuas->as->dispatch);
cpuas->memory_dispatch = d;
tlb_flush(cpuas->cpu, 1);
}
void address_space_init_dispatch(AddressSpace *as)

View File

@ -979,7 +979,7 @@ static void assigned_dev_update_msi(PCIDevice *pci_dev)
MSIMessage msg = msi_get_message(pci_dev, 0);
int virq;
virq = kvm_irqchip_add_msi_route(kvm_state, msg);
virq = kvm_irqchip_add_msi_route(kvm_state, msg, pci_dev);
if (virq < 0) {
perror("assigned_dev_update_msi: kvm_irqchip_add_msi_route");
return;
@ -1017,7 +1017,7 @@ static void assigned_dev_update_msi_msg(PCIDevice *pci_dev)
}
kvm_irqchip_update_msi_route(kvm_state, assigned_dev->msi_virq[0],
msi_get_message(pci_dev, 0));
msi_get_message(pci_dev, 0), pci_dev);
}
static bool assigned_dev_msix_masked(MSIXTableEntry *entry)
@ -1083,7 +1083,7 @@ static int assigned_dev_update_msix_mmio(PCIDevice *pci_dev)
msg.address = entry->addr_lo | ((uint64_t)entry->addr_hi << 32);
msg.data = entry->data;
r = kvm_irqchip_add_msi_route(kvm_state, msg);
r = kvm_irqchip_add_msi_route(kvm_state, msg, pci_dev);
if (r < 0) {
return r;
}
@ -1483,7 +1483,7 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev, Error **errp)
* error bits, leave the rest. */
status = pci_get_long(pci_dev->config + pos + PCI_X_STATUS);
status &= ~(PCI_X_STATUS_BUS | PCI_X_STATUS_DEVFN);
status |= (pci_bus_num(pci_dev->bus) << 8) | pci_dev->devfn;
status |= pci_requester_id(pci_dev);
status &= ~(PCI_X_STATUS_SPL_DISC | PCI_X_STATUS_UNX_SPL |
PCI_X_STATUS_SPL_ERR);
pci_set_long(pci_dev->config + pos + PCI_X_STATUS, status);
@ -1602,7 +1602,8 @@ static void assigned_dev_msix_mmio_write(void *opaque, hwaddr addr,
msg.data = entry->data;
ret = kvm_irqchip_update_msi_route(kvm_state,
adev->msi_virq[i], msg);
adev->msi_virq[i], msg,
pdev);
if (ret) {
error_report("Error updating irq routing entry (%d)", ret);
}

View File

@ -294,7 +294,7 @@ void msi_send_message(PCIDevice *dev, MSIMessage msg)
{
MemTxAttrs attrs = {};
attrs.stream_id = (pci_bus_num(dev->bus) << 8) | dev->devfn;
attrs.requester_id = pci_requester_id(dev);
address_space_stl_le(&dev->bus_master_as, msg.address, msg.data,
attrs, NULL);
}

View File

@ -979,7 +979,7 @@ static int do_pcie_aer_inject_error(Monitor *mon,
}
}
err.status = error_status;
err.source_id = (pci_bus_num(dev->bus) << 8) | dev->devfn;
err.source_id = pci_requester_id(dev);
err.flags = 0;
if (correctable) {

View File

@ -431,7 +431,7 @@ static uint64_t megasas_fw_time(void)
static uint64_t megasas_get_sata_addr(uint16_t id)
{
uint64_t addr = (0x1221ULL << 48);
return addr & (id << 24);
return addr | ((uint64_t)id << 24);
}
/*

View File

@ -558,7 +558,7 @@ SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops, SCSIDevice *d,
const int memset_off = offsetof(SCSIRequest, sense)
+ sizeof(req->sense);
req = g_slice_alloc(reqops->size);
req = g_malloc(reqops->size);
memset((uint8_t *)req + memset_off, 0, reqops->size - memset_off);
req->refcount = 1;
req->bus = bus;
@ -1622,7 +1622,7 @@ void scsi_req_unref(SCSIRequest *req)
}
object_unref(OBJECT(req->dev));
object_unref(OBJECT(qbus->parent));
g_slice_free1(req->ops->size, req);
g_free(req);
}
}

View File

@ -57,7 +57,7 @@ static VirtIOSCSIVring *virtio_scsi_vring_init(VirtIOSCSI *s,
return NULL;
}
r = g_slice_new(VirtIOSCSIVring);
r = g_new(VirtIOSCSIVring, 1);
r->host_notifier = *virtio_queue_get_host_notifier(vq);
r->guest_notifier = *virtio_queue_get_guest_notifier(vq);
aio_set_event_notifier(s->ctx, &r->host_notifier, handler);
@ -73,7 +73,7 @@ static VirtIOSCSIVring *virtio_scsi_vring_init(VirtIOSCSI *s,
fail_vring:
aio_set_event_notifier(s->ctx, &r->host_notifier, NULL);
k->set_host_notifier(qbus->parent, n, false);
g_slice_free(VirtIOSCSIVring, r);
g_free(r);
return NULL;
}
@ -182,18 +182,18 @@ static void virtio_scsi_vring_teardown(VirtIOSCSI *s)
if (s->ctrl_vring) {
vring_teardown(&s->ctrl_vring->vring, vdev, 0);
g_slice_free(VirtIOSCSIVring, s->ctrl_vring);
g_free(s->ctrl_vring);
s->ctrl_vring = NULL;
}
if (s->event_vring) {
vring_teardown(&s->event_vring->vring, vdev, 1);
g_slice_free(VirtIOSCSIVring, s->event_vring);
g_free(s->event_vring);
s->event_vring = NULL;
}
if (s->cmd_vrings) {
for (i = 0; i < vs->conf.num_queues && s->cmd_vrings[i]; i++) {
vring_teardown(&s->cmd_vrings[i]->vring, vdev, 2 + i);
g_slice_free(VirtIOSCSIVring, s->cmd_vrings[i]);
g_free(s->cmd_vrings[i]);
s->cmd_vrings[i] = NULL;
}
free(s->cmd_vrings);

View File

@ -47,7 +47,7 @@ VirtIOSCSIReq *virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq)
const size_t zero_skip = offsetof(VirtIOSCSIReq, elem)
+ sizeof(VirtQueueElement);
req = g_slice_alloc(sizeof(*req) + vs->cdb_size);
req = g_malloc(sizeof(*req) + vs->cdb_size);
req->vq = vq;
req->dev = s;
qemu_sglist_init(&req->qsgl, DEVICE(s), 8, &address_space_memory);
@ -58,11 +58,9 @@ VirtIOSCSIReq *virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq)
void virtio_scsi_free_req(VirtIOSCSIReq *req)
{
VirtIOSCSICommon *vs = (VirtIOSCSICommon *)req->dev;
qemu_iovec_destroy(&req->resp_iov);
qemu_sglist_destroy(&req->qsgl);
g_slice_free1(sizeof(*req) + vs->cdb_size, req);
g_free(req);
}
static void virtio_scsi_complete_req(VirtIOSCSIReq *req)
@ -250,7 +248,7 @@ static void virtio_scsi_cancel_notify(Notifier *notifier, void *data)
if (--n->tmf_req->remaining == 0) {
virtio_scsi_complete_req(n->tmf_req);
}
g_slice_free(VirtIOSCSICancelNotifier, n);
g_free(n);
}
/* Return 0 if the request is ready to be completed and return to guest;
@ -301,7 +299,7 @@ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req)
VirtIOSCSICancelNotifier *notifier;
req->remaining = 1;
notifier = g_slice_new(VirtIOSCSICancelNotifier);
notifier = g_new(VirtIOSCSICancelNotifier, 1);
notifier->tmf_req = req;
notifier->notifier.notify = virtio_scsi_cancel_notify;
scsi_req_cancel_async(r, &notifier->notifier);
@ -350,7 +348,7 @@ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req)
VirtIOSCSICancelNotifier *notifier;
req->remaining++;
notifier = g_slice_new(VirtIOSCSICancelNotifier);
notifier = g_new(VirtIOSCSICancelNotifier, 1);
notifier->notifier.notify = virtio_scsi_cancel_notify;
notifier->tmf_req = req;
scsi_req_cancel_async(r, &notifier->notifier);

View File

@ -424,7 +424,7 @@ static void vfio_add_kvm_msi_virq(VFIOPCIDevice *vdev, VFIOMSIVector *vector,
return;
}
virq = kvm_irqchip_add_msi_route(kvm_state, *msg);
virq = kvm_irqchip_add_msi_route(kvm_state, *msg, &vdev->pdev);
if (virq < 0) {
event_notifier_cleanup(&vector->kvm_interrupt);
return;
@ -449,9 +449,10 @@ static void vfio_remove_kvm_msi_virq(VFIOMSIVector *vector)
event_notifier_cleanup(&vector->kvm_interrupt);
}
static void vfio_update_kvm_msi_virq(VFIOMSIVector *vector, MSIMessage msg)
static void vfio_update_kvm_msi_virq(VFIOMSIVector *vector, MSIMessage msg,
PCIDevice *pdev)
{
kvm_irqchip_update_msi_route(kvm_state, vector->virq, msg);
kvm_irqchip_update_msi_route(kvm_state, vector->virq, msg, pdev);
}
static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,
@ -486,7 +487,7 @@ static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,
if (!msg) {
vfio_remove_kvm_msi_virq(vector);
} else {
vfio_update_kvm_msi_virq(vector, *msg);
vfio_update_kvm_msi_virq(vector, *msg, pdev);
}
} else {
vfio_add_kvm_msi_virq(vdev, vector, msg, true);
@ -760,7 +761,7 @@ static void vfio_update_msi(VFIOPCIDevice *vdev)
}
msg = msi_get_message(&vdev->pdev, i);
vfio_update_kvm_msi_virq(vector, msg);
vfio_update_kvm_msi_virq(vector, msg, &vdev->pdev);
}
}

View File

@ -590,7 +590,7 @@ static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy,
int ret;
if (irqfd->users == 0) {
ret = kvm_irqchip_add_msi_route(kvm_state, msg);
ret = kvm_irqchip_add_msi_route(kvm_state, msg, &proxy->pci_dev);
if (ret < 0) {
return ret;
}
@ -726,7 +726,8 @@ static int virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy,
if (proxy->vector_irqfd) {
irqfd = &proxy->vector_irqfd[vector];
if (irqfd->msg.data != msg.data || irqfd->msg.address != msg.address) {
ret = kvm_irqchip_update_msi_route(kvm_state, irqfd->virq, msg);
ret = kvm_irqchip_update_msi_route(kvm_state, irqfd->virq, msg,
&proxy->pci_dev);
if (ret < 0) {
return ret;
}

View File

@ -84,8 +84,7 @@ void QEMU_NORETURN cpu_loop_exit(CPUState *cpu);
void QEMU_NORETURN cpu_loop_exit_restore(CPUState *cpu, uintptr_t pc);
#if !defined(CONFIG_USER_ONLY)
bool qemu_in_vcpu_thread(void);
void cpu_reload_memory_map(CPUState *cpu);
void cpu_reloading_memory_map(void);
void tcg_cpu_address_space_init(CPUState *cpu, AddressSpace *as);
/* cputlb.c */
/**
@ -357,8 +356,6 @@ extern uintptr_t tci_tb_ptr;
#if !defined(CONFIG_USER_ONLY)
void phys_mem_set_alloc(void *(*alloc)(size_t, uint64_t *align));
struct MemoryRegion *iotlb_to_region(CPUState *cpu,
hwaddr index);
@ -408,7 +405,4 @@ extern int singlestep;
extern CPUState *tcg_current_cpu;
extern bool exit_request;
#if !defined(CONFIG_USER_ONLY)
void migration_bitmap_extend(ram_addr_t old, ram_addr_t new);
#endif
#endif

View File

@ -35,8 +35,8 @@ typedef struct MemTxAttrs {
unsigned int secure:1;
/* Memory access is usermode (unprivileged) */
unsigned int user:1;
/* Stream ID (for MSI for example) */
unsigned int stream_id:16;
/* Requester ID (for MSI for example) */
unsigned int requester_id:16;
} MemTxAttrs;
/* Bus masters which don't specify any attributes will get this,

View File

@ -289,5 +289,6 @@ uint64_t cpu_physical_memory_sync_dirty_bitmap(unsigned long *dest,
return num_dirty;
}
void migration_bitmap_extend(ram_addr_t old, ram_addr_t new);
#endif
#endif

View File

@ -677,6 +677,11 @@ static inline uint32_t pci_config_size(const PCIDevice *d)
return pci_is_express(d) ? PCIE_CONFIG_SPACE_SIZE : PCI_CONFIG_SPACE_SIZE;
}
static inline uint16_t pci_requester_id(PCIDevice *dev)
{
return (pci_bus_num(dev->bus) << 8) | dev->devfn;
}
/* DMA access functions */
static inline AddressSpace *pci_get_address_space(PCIDevice *dev)
{

View File

@ -16,6 +16,7 @@ typedef struct BusClass BusClass;
typedef struct BusState BusState;
typedef struct CharDriverState CharDriverState;
typedef struct CompatProperty CompatProperty;
typedef struct CPUAddressSpace CPUAddressSpace;
typedef struct DeviceState DeviceState;
typedef struct DeviceListener DeviceListener;
typedef struct DisplayChangeListener DisplayChangeListener;

View File

@ -234,6 +234,10 @@ struct kvm_run;
* @can_do_io: Nonzero if memory-mapped IO is safe. Deterministic execution
* requires that IO only be performed on the last instruction of a TB
* so that interrupts take effect immediately.
* @cpu_ases: Pointer to array of CPUAddressSpaces (which define the
* AddressSpaces this CPU has)
* @as: Pointer to the first AddressSpace, for the convenience of targets which
* only have a single AddressSpace
* @env_ptr: Pointer to subclass-specific CPUArchState field.
* @current_tb: Currently executing TB.
* @gdb_regs: Additional GDB registers.
@ -280,9 +284,8 @@ struct CPUState {
QemuMutex work_mutex;
struct qemu_work_item *queued_work_first, *queued_work_last;
CPUAddressSpace *cpu_ases;
AddressSpace *as;
struct AddressSpaceDispatch *memory_dispatch;
MemoryListener *tcg_as_listener;
void *env_ptr; /* CPUArchState */
struct TranslationBlock *current_tb;

View File

@ -153,6 +153,12 @@
/* MSR used to provide vcpu index */
#define HV_X64_MSR_VP_INDEX 0x40000002
/* MSR used to reset the guest OS. */
#define HV_X64_MSR_RESET 0x40000003
/* MSR used to provide vcpu runtime in 100ns units */
#define HV_X64_MSR_VP_RUNTIME 0x40000010
/* MSR used to read the per-partition time reference counter */
#define HV_X64_MSR_TIME_REF_COUNT 0x40000020

View File

@ -345,7 +345,9 @@ bool chr_is_ringbuf(const CharDriverState *chr);
QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename);
void register_char_driver(const char *name, ChardevBackendKind kind,
void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp));
void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp),
CharDriverState *(*create)(const char *id, ChardevBackend *backend,
ChardevReturn *ret, Error **errp));
/* add an eventfd to the qemu devices that are polled */
CharDriverState *qemu_chr_open_eventfd(int eventfd);
@ -354,18 +356,8 @@ extern int term_escape_char;
CharDriverState *qemu_char_get_next_serial(void);
/* msmouse */
CharDriverState *qemu_chr_open_msmouse(void);
/* testdev.c */
CharDriverState *chr_testdev_init(void);
/* baum.c */
CharDriverState *chr_baum_init(void);
/* console.c */
typedef CharDriverState *(VcHandler)(ChardevVC *vc);
typedef CharDriverState *(VcHandler)(ChardevVC *vc, Error **errp);
void register_vc_handler(VcHandler *handler);
CharDriverState *vc_init(ChardevVC *vc);
#endif

View File

@ -2,6 +2,7 @@
#define QEMU_CPUS_H
/* cpus.c */
bool qemu_in_vcpu_thread(void);
void qemu_init_cpu_loop(void);
void resume_all_vcpus(void);
void pause_all_vcpus(void);

View File

@ -52,6 +52,7 @@ extern bool kvm_msi_via_irqfd_allowed;
extern bool kvm_gsi_routing_allowed;
extern bool kvm_gsi_direct_mapping;
extern bool kvm_readonly_mem_allowed;
extern bool kvm_direct_msi_allowed;
#if defined CONFIG_KVM || !defined NEED_CPU_H
#define kvm_enabled() (kvm_allowed)
@ -145,6 +146,13 @@ extern bool kvm_readonly_mem_allowed;
*/
#define kvm_readonly_mem_enabled() (kvm_readonly_mem_allowed)
/**
* kvm_direct_msi_enabled:
*
* Returns: true if KVM allows direct MSI injection.
*/
#define kvm_direct_msi_enabled() (kvm_direct_msi_allowed)
#else
#define kvm_enabled() (0)
#define kvm_irqchip_in_kernel() (false)
@ -157,6 +165,7 @@ extern bool kvm_readonly_mem_allowed;
#define kvm_gsi_routing_allowed() (false)
#define kvm_gsi_direct_mapping() (false)
#define kvm_readonly_mem_enabled() (false)
#define kvm_direct_msi_enabled() (false)
#endif
struct kvm_run;
@ -182,8 +191,6 @@ int kvm_has_sync_mmu(void);
int kvm_has_vcpu_events(void);
int kvm_has_robust_singlestep(void);
int kvm_has_debugregs(void);
int kvm_has_xsave(void);
int kvm_has_xcrs(void);
int kvm_has_pit_state2(void);
int kvm_has_many_ioeventfds(void);
int kvm_has_gsi_routing(void);
@ -210,6 +217,10 @@ int kvm_set_signal_mask(CPUState *cpu, const sigset_t *sigset);
int kvm_on_sigbus_vcpu(CPUState *cpu, int code, void *addr);
int kvm_on_sigbus(int code, void *addr);
/* interface with exec.c */
void phys_mem_set_alloc(void *(*alloc)(size_t, uint64_t *align));
/* internal API */
int kvm_ioctl(KVMState *s, int type, ...);
@ -313,7 +324,7 @@ int kvm_arch_on_sigbus(int code, void *addr);
void kvm_arch_init_irq_routing(KVMState *s);
int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
uint64_t address, uint32_t data);
uint64_t address, uint32_t data, PCIDevice *dev);
int kvm_arch_msi_data_to_gsi(uint32_t data);
@ -438,8 +449,9 @@ static inline void cpu_clean_state(CPUState *cpu)
}
}
int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg);
int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg);
int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg, PCIDevice *dev);
int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg,
PCIDevice *dev);
void kvm_irqchip_release_virq(KVMState *s, int virq);
int kvm_irqchip_add_adapter_route(KVMState *s, AdapterInfo *adapter);

View File

@ -43,9 +43,7 @@ int qemu_spice_set_pw_expire(time_t expires);
int qemu_spice_migrate_info(const char *hostname, int port, int tls_port,
const char *subject);
CharDriverState *qemu_chr_open_spice_vmc(const char *type);
#if SPICE_SERVER_VERSION >= 0x000c02
CharDriverState *qemu_chr_open_spice_port(const char *name);
void qemu_spice_register_ports(void);
#else
static inline CharDriverState *qemu_chr_open_spice_port(const char *name)

View File

@ -77,8 +77,6 @@ struct KVMState
#ifdef KVM_CAP_SET_GUEST_DEBUG
struct kvm_sw_breakpoint_head kvm_sw_breakpoints;
#endif
int pit_state2;
int xsave, xcrs;
int many_ioeventfds;
int intx_set_mask;
/* The man page (and posix) say ioctl numbers are signed int, but
@ -93,7 +91,6 @@ struct KVMState
uint32_t *used_gsi_bitmap;
unsigned int gsi_count;
QTAILQ_HEAD(msi_hashtab, KVMMSIRoute) msi_hashtab[KVM_MSI_HASHTAB_SIZE];
bool direct_msi;
#endif
KVMMemoryListener memory_listener;
};
@ -111,6 +108,7 @@ bool kvm_gsi_direct_mapping;
bool kvm_allowed;
bool kvm_readonly_mem_allowed;
bool kvm_vm_attributes_allowed;
bool kvm_direct_msi_allowed;
static const KVMCapabilityInfo kvm_required_capabilites[] = {
KVM_CAP_INFO(USER_MEMORY),
@ -642,15 +640,15 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
/* kvm works in page size chunks, but the function may be called
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;
delta = qemu_real_host_page_size - (start_addr & ~qemu_real_host_page_mask);
delta &= ~qemu_real_host_page_mask;
if (delta > size) {
return;
}
start_addr += delta;
size -= delta;
size &= TARGET_PAGE_MASK;
if (!size || (start_addr & ~TARGET_PAGE_MASK)) {
size &= qemu_real_host_page_mask;
if (!size || (start_addr & ~qemu_real_host_page_mask)) {
return;
}
@ -979,7 +977,7 @@ void kvm_init_irq_routing(KVMState *s)
s->irq_routes = g_malloc0(sizeof(*s->irq_routes));
s->nr_allocated_irq_routes = 0;
if (!s->direct_msi) {
if (!kvm_direct_msi_allowed) {
for (i = 0; i < KVM_MSI_HASHTAB_SIZE; i++) {
QTAILQ_INIT(&s->msi_hashtab[i]);
}
@ -1113,7 +1111,7 @@ static int kvm_irqchip_get_virq(KVMState *s)
* number can succeed even though a new route entry cannot be added.
* When this happens, flush dynamic MSI entries to free IRQ route entries.
*/
if (!s->direct_msi && s->irq_routes->nr == s->gsi_count) {
if (!kvm_direct_msi_allowed && s->irq_routes->nr == s->gsi_count) {
kvm_flush_dynamic_msi_routes(s);
}
@ -1150,7 +1148,7 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg)
struct kvm_msi msi;
KVMMSIRoute *route;
if (s->direct_msi) {
if (kvm_direct_msi_allowed) {
msi.address_lo = (uint32_t)msg.address;
msi.address_hi = msg.address >> 32;
msi.data = le32_to_cpu(msg.data);
@ -1189,7 +1187,7 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg)
return kvm_set_irq(s, route->kroute.gsi, 1);
}
int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg)
int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg, PCIDevice *dev)
{
struct kvm_irq_routing_entry kroute = {};
int virq;
@ -1213,7 +1211,7 @@ int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg)
kroute.u.msi.address_lo = (uint32_t)msg.address;
kroute.u.msi.address_hi = msg.address >> 32;
kroute.u.msi.data = le32_to_cpu(msg.data);
if (kvm_arch_fixup_msi_route(&kroute, msg.address, msg.data)) {
if (kvm_arch_fixup_msi_route(&kroute, msg.address, msg.data, dev)) {
kvm_irqchip_release_virq(s, virq);
return -EINVAL;
}
@ -1224,7 +1222,8 @@ int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg)
return virq;
}
int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg)
int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg,
PCIDevice *dev)
{
struct kvm_irq_routing_entry kroute = {};
@ -1242,7 +1241,7 @@ int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg)
kroute.u.msi.address_lo = (uint32_t)msg.address;
kroute.u.msi.address_hi = msg.address >> 32;
kroute.u.msi.data = le32_to_cpu(msg.data);
if (kvm_arch_fixup_msi_route(&kroute, msg.address, msg.data)) {
if (kvm_arch_fixup_msi_route(&kroute, msg.address, msg.data, dev)) {
return -EINVAL;
}
@ -1585,20 +1584,8 @@ static int kvm_init(MachineState *ms)
s->debugregs = kvm_check_extension(s, KVM_CAP_DEBUGREGS);
#endif
#ifdef KVM_CAP_XSAVE
s->xsave = kvm_check_extension(s, KVM_CAP_XSAVE);
#endif
#ifdef KVM_CAP_XCRS
s->xcrs = kvm_check_extension(s, KVM_CAP_XCRS);
#endif
#ifdef KVM_CAP_PIT_STATE2
s->pit_state2 = kvm_check_extension(s, KVM_CAP_PIT_STATE2);
#endif
#ifdef KVM_CAP_IRQ_ROUTING
s->direct_msi = (kvm_check_extension(s, KVM_CAP_SIGNAL_MSI) > 0);
kvm_direct_msi_allowed = (kvm_check_extension(s, KVM_CAP_SIGNAL_MSI) > 0);
#endif
s->intx_set_mask = kvm_check_extension(s, KVM_CAP_PCI_2_3);
@ -2062,21 +2049,6 @@ int kvm_has_debugregs(void)
return kvm_state->debugregs;
}
int kvm_has_xsave(void)
{
return kvm_state->xsave;
}
int kvm_has_xcrs(void)
{
return kvm_state->xcrs;
}
int kvm_has_pit_state2(void)
{
return kvm_state->pit_state2;
}
int kvm_has_many_ioeventfds(void)
{
if (!kvm_enabled()) {

View File

@ -67,11 +67,6 @@ int kvm_has_many_ioeventfds(void)
return 0;
}
int kvm_has_pit_state2(void)
{
return 0;
}
void kvm_setup_guest_memory(void *start, size_t size)
{
}
@ -115,7 +110,7 @@ int kvm_on_sigbus(int code, void *addr)
}
#ifndef CONFIG_USER_ONLY
int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg)
int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg, PCIDevice *dev)
{
return -ENOSYS;
}
@ -128,7 +123,8 @@ void kvm_irqchip_release_virq(KVMState *s, int virq)
{
}
int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg)
int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg,
PCIDevice *dev)
{
return -ENOSYS;
}

View File

@ -53,14 +53,20 @@ struct kvm_regs {
struct user_fpsimd_state fp_regs;
};
/* Supported Processor Types */
/*
* Supported CPU Targets - Adding a new target type is not recommended,
* unless there are some special registers not supported by the
* genericv8 syreg table.
*/
#define KVM_ARM_TARGET_AEM_V8 0
#define KVM_ARM_TARGET_FOUNDATION_V8 1
#define KVM_ARM_TARGET_CORTEX_A57 2
#define KVM_ARM_TARGET_XGENE_POTENZA 3
#define KVM_ARM_TARGET_CORTEX_A53 4
/* Generic ARM v8 target */
#define KVM_ARM_TARGET_GENERIC_V8 5
#define KVM_ARM_NUM_TARGETS 5
#define KVM_ARM_NUM_TARGETS 6
/* KVM_ARM_SET_DEVICE_ADDR ioctl id encoding */
#define KVM_ARM_DEVICE_TYPE_SHIFT 0
@ -100,12 +106,39 @@ struct kvm_sregs {
struct kvm_fpu {
};
/*
* See v8 ARM ARM D7.3: Debug Registers
*
* The architectural limit is 16 debug registers of each type although
* in practice there are usually less (see ID_AA64DFR0_EL1).
*
* Although the control registers are architecturally defined as 32
* bits wide we use a 64 bit structure here to keep parity with
* KVM_GET/SET_ONE_REG behaviour which treats all system registers as
* 64 bit values. It also allows for the possibility of the
* architecture expanding the control registers without having to
* change the userspace ABI.
*/
#define KVM_ARM_MAX_DBG_REGS 16
struct kvm_guest_debug_arch {
__u64 dbg_bcr[KVM_ARM_MAX_DBG_REGS];
__u64 dbg_bvr[KVM_ARM_MAX_DBG_REGS];
__u64 dbg_wcr[KVM_ARM_MAX_DBG_REGS];
__u64 dbg_wvr[KVM_ARM_MAX_DBG_REGS];
};
struct kvm_debug_exit_arch {
__u32 hsr;
__u64 far; /* used for watchpoints */
};
/*
* Architecture specific defines for kvm_guest_debug->control
*/
#define KVM_GUESTDBG_USE_SW_BP (1 << 16)
#define KVM_GUESTDBG_USE_HW (1 << 17)
struct kvm_sync_regs {
};

View File

@ -183,6 +183,7 @@ struct kvm_s390_skeys {
#define KVM_EXIT_EPR 23
#define KVM_EXIT_SYSTEM_EVENT 24
#define KVM_EXIT_S390_STSI 25
#define KVM_EXIT_IOAPIC_EOI 26
/* For KVM_EXIT_INTERNAL_ERROR */
/* Emulate instruction failed. */
@ -237,6 +238,7 @@ struct kvm_run {
__u32 count;
__u64 data_offset; /* relative to kvm_run start */
} io;
/* KVM_EXIT_DEBUG */
struct {
struct kvm_debug_exit_arch arch;
} debug;
@ -285,6 +287,7 @@ struct kvm_run {
__u32 data;
__u8 is_write;
} dcr;
/* KVM_EXIT_INTERNAL_ERROR */
struct {
__u32 suberror;
/* Available with KVM_CAP_INTERNAL_ERROR_DATA: */
@ -295,6 +298,7 @@ struct kvm_run {
struct {
__u64 gprs[32];
} osi;
/* KVM_EXIT_PAPR_HCALL */
struct {
__u64 nr;
__u64 ret;
@ -330,6 +334,10 @@ struct kvm_run {
__u8 sel1;
__u16 sel2;
} s390_stsi;
/* KVM_EXIT_IOAPIC_EOI */
struct {
__u8 vector;
} eoi;
/* Fix the size of the union. */
char padding[256];
};
@ -819,6 +827,10 @@ struct kvm_ppc_smmu_info {
#define KVM_CAP_DISABLE_QUIRKS 116
#define KVM_CAP_X86_SMM 117
#define KVM_CAP_MULTI_ADDRESS_SPACE 118
#define KVM_CAP_GUEST_DEBUG_HW_BPS 119
#define KVM_CAP_GUEST_DEBUG_HW_WPS 120
#define KVM_CAP_SPLIT_IRQCHIP 121
#define KVM_CAP_IOEVENTFD_ANY_LENGTH 122
#ifdef KVM_CAP_IRQ_ROUTING

4
nbd.c
View File

@ -1005,7 +1005,7 @@ static NBDRequest *nbd_request_get(NBDClient *client)
client->nb_requests++;
nbd_update_can_read(client);
req = g_slice_new0(NBDRequest);
req = g_new0(NBDRequest, 1);
nbd_client_get(client);
req->client = client;
return req;
@ -1018,7 +1018,7 @@ static void nbd_request_put(NBDRequest *req)
if (req->data) {
qemu_vfree(req->data);
}
g_slice_free(NBDRequest, req);
g_free(req);
client->nb_requests--;
nbd_update_can_read(client);

View File

@ -383,7 +383,10 @@ static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
return len;
}
static CharDriverState *qemu_chr_open_null(void)
static CharDriverState *qemu_chr_open_null(const char *id,
ChardevBackend *backend,
ChardevReturn *ret,
Error **errp)
{
CharDriverState *chr;
@ -679,11 +682,20 @@ static GSource *mux_chr_add_watch(CharDriverState *s, GIOCondition cond)
return d->drv->chr_add_watch(d->drv, cond);
}
static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
static CharDriverState *qemu_chr_open_mux(const char *id,
ChardevBackend *backend,
ChardevReturn *ret, Error **errp)
{
CharDriverState *chr;
ChardevMux *mux = backend->mux;
CharDriverState *chr, *drv;
MuxDriver *d;
drv = qemu_chr_find(mux->chardev);
if (drv == NULL) {
error_setg(errp, "mux: base chardev %s not found", mux->chardev);
return NULL;
}
chr = qemu_chr_alloc();
d = g_new0(MuxDriver, 1);
@ -1078,18 +1090,17 @@ static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out)
return chr;
}
static CharDriverState *qemu_chr_open_pipe(ChardevHostdev *opts)
static CharDriverState *qemu_chr_open_pipe(const char *id,
ChardevBackend *backend,
ChardevReturn *ret,
Error **errp)
{
ChardevHostdev *opts = backend->pipe;
int fd_in, fd_out;
char filename_in[CHR_MAX_FILENAME_SIZE];
char filename_out[CHR_MAX_FILENAME_SIZE];
const char *filename = opts->device;
if (filename == NULL) {
fprintf(stderr, "chardev: pipe: no filename given\n");
return NULL;
}
snprintf(filename_in, CHR_MAX_FILENAME_SIZE, "%s.in", filename);
snprintf(filename_out, CHR_MAX_FILENAME_SIZE, "%s.out", filename);
TFR(fd_in = qemu_open(filename_in, O_RDWR | O_BINARY));
@ -1101,6 +1112,7 @@ static CharDriverState *qemu_chr_open_pipe(ChardevHostdev *opts)
close(fd_out);
TFR(fd_in = fd_out = qemu_open(filename, O_RDWR | O_BINARY));
if (fd_in < 0) {
error_setg_file_open(errp, errno, filename);
return NULL;
}
}
@ -1156,19 +1168,23 @@ static void qemu_chr_close_stdio(struct CharDriverState *chr)
fd_chr_close(chr);
}
static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts)
static CharDriverState *qemu_chr_open_stdio(const char *id,
ChardevBackend *backend,
ChardevReturn *ret,
Error **errp)
{
ChardevStdio *opts = backend->stdio;
CharDriverState *chr;
struct sigaction act;
if (is_daemonized()) {
error_report("cannot use stdio with -daemonize");
error_setg(errp, "cannot use stdio with -daemonize");
return NULL;
}
if (stdio_in_use) {
error_report("cannot use stdio by multiple character devices");
exit(1);
error_setg(errp, "cannot use stdio by multiple character devices");
return NULL;
}
stdio_in_use = true;
@ -1196,7 +1212,8 @@ static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts)
|| defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) \
|| defined(__GLIBC__)
#define HAVE_CHARDEV_TTY 1
#define HAVE_CHARDEV_SERIAL 1
#define HAVE_CHARDEV_PTY 1
typedef struct {
GIOChannel *fd;
@ -1389,7 +1406,9 @@ static void pty_chr_close(struct CharDriverState *chr)
}
static CharDriverState *qemu_chr_open_pty(const char *id,
ChardevReturn *ret)
ChardevBackend *backend,
ChardevReturn *ret,
Error **errp)
{
CharDriverState *chr;
PtyCharDriver *s;
@ -1398,6 +1417,7 @@ static CharDriverState *qemu_chr_open_pty(const char *id,
master_fd = qemu_openpty_raw(&slave_fd, pty_name);
if (master_fd < 0) {
error_setg_errno(errp, errno, "Failed to create PTY");
return NULL;
}
@ -1752,12 +1772,13 @@ static void pp_close(CharDriverState *chr)
qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
}
static CharDriverState *qemu_chr_open_pp_fd(int fd)
static CharDriverState *qemu_chr_open_pp_fd(int fd, Error **errp)
{
CharDriverState *chr;
ParallelCharDriver *drv;
if (ioctl(fd, PPCLAIM) < 0) {
error_setg_errno(errp, errno, "not a parallel port");
close(fd);
return NULL;
}
@ -1817,7 +1838,7 @@ static int pp_ioctl(CharDriverState *chr, int cmd, void *arg)
return 0;
}
static CharDriverState *qemu_chr_open_pp_fd(int fd)
static CharDriverState *qemu_chr_open_pp_fd(int fd, Error **errp)
{
CharDriverState *chr;
@ -1832,6 +1853,8 @@ static CharDriverState *qemu_chr_open_pp_fd(int fd)
#else /* _WIN32 */
#define HAVE_CHARDEV_SERIAL 1
typedef struct {
int max_size;
HANDLE hcom, hrecv, hsend;
@ -1883,7 +1906,7 @@ static void win_chr_close(CharDriverState *chr)
qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
}
static int win_chr_init(CharDriverState *chr, const char *filename)
static int win_chr_init(CharDriverState *chr, const char *filename, Error **errp)
{
WinCharState *s = chr->opaque;
COMMCONFIG comcfg;
@ -1894,25 +1917,25 @@ static int win_chr_init(CharDriverState *chr, const char *filename)
s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!s->hsend) {
fprintf(stderr, "Failed CreateEvent\n");
error_setg(errp, "Failed CreateEvent");
goto fail;
}
s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!s->hrecv) {
fprintf(stderr, "Failed CreateEvent\n");
error_setg(errp, "Failed CreateEvent");
goto fail;
}
s->hcom = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
if (s->hcom == INVALID_HANDLE_VALUE) {
fprintf(stderr, "Failed CreateFile (%lu)\n", GetLastError());
error_setg(errp, "Failed CreateFile (%lu)", GetLastError());
s->hcom = NULL;
goto fail;
}
if (!SetupComm(s->hcom, NRECVBUF, NSENDBUF)) {
fprintf(stderr, "Failed SetupComm\n");
error_setg(errp, "Failed SetupComm");
goto fail;
}
@ -1923,23 +1946,23 @@ static int win_chr_init(CharDriverState *chr, const char *filename)
CommConfigDialog(filename, NULL, &comcfg);
if (!SetCommState(s->hcom, &comcfg.dcb)) {
fprintf(stderr, "Failed SetCommState\n");
error_setg(errp, "Failed SetCommState");
goto fail;
}
if (!SetCommMask(s->hcom, EV_ERR)) {
fprintf(stderr, "Failed SetCommMask\n");
error_setg(errp, "Failed SetCommMask");
goto fail;
}
cto.ReadIntervalTimeout = MAXDWORD;
if (!SetCommTimeouts(s->hcom, &cto)) {
fprintf(stderr, "Failed SetCommTimeouts\n");
error_setg(errp, "Failed SetCommTimeouts");
goto fail;
}
if (!ClearCommError(s->hcom, &err, &comstat)) {
fprintf(stderr, "Failed ClearCommError\n");
error_setg(errp, "Failed ClearCommError");
goto fail;
}
qemu_add_polling_cb(win_chr_poll, chr);
@ -2044,7 +2067,8 @@ static int win_chr_poll(void *opaque)
return 0;
}
static CharDriverState *qemu_chr_open_win_path(const char *filename)
static CharDriverState *qemu_chr_open_win_path(const char *filename,
Error **errp)
{
CharDriverState *chr;
WinCharState *s;
@ -2055,7 +2079,7 @@ static CharDriverState *qemu_chr_open_win_path(const char *filename)
chr->chr_write = win_chr_write;
chr->chr_close = win_chr_close;
if (win_chr_init(chr, filename) < 0) {
if (win_chr_init(chr, filename, errp) < 0) {
g_free(s);
g_free(chr);
return NULL;
@ -2079,7 +2103,8 @@ static int win_chr_pipe_poll(void *opaque)
return 0;
}
static int win_chr_pipe_init(CharDriverState *chr, const char *filename)
static int win_chr_pipe_init(CharDriverState *chr, const char *filename,
Error **errp)
{
WinCharState *s = chr->opaque;
OVERLAPPED ov;
@ -2091,12 +2116,12 @@ static int win_chr_pipe_init(CharDriverState *chr, const char *filename)
s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!s->hsend) {
fprintf(stderr, "Failed CreateEvent\n");
error_setg(errp, "Failed CreateEvent");
goto fail;
}
s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!s->hrecv) {
fprintf(stderr, "Failed CreateEvent\n");
error_setg(errp, "Failed CreateEvent");
goto fail;
}
@ -2106,7 +2131,7 @@ static int win_chr_pipe_init(CharDriverState *chr, const char *filename)
PIPE_WAIT,
MAXCONNECT, NSENDBUF, NRECVBUF, NTIMEOUT, NULL);
if (s->hcom == INVALID_HANDLE_VALUE) {
fprintf(stderr, "Failed CreateNamedPipe (%lu)\n", GetLastError());
error_setg(errp, "Failed CreateNamedPipe (%lu)", GetLastError());
s->hcom = NULL;
goto fail;
}
@ -2115,13 +2140,13 @@ static int win_chr_pipe_init(CharDriverState *chr, const char *filename)
ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
ret = ConnectNamedPipe(s->hcom, &ov);
if (ret) {
fprintf(stderr, "Failed ConnectNamedPipe\n");
error_setg(errp, "Failed ConnectNamedPipe");
goto fail;
}
ret = GetOverlappedResult(s->hcom, &ov, &size, TRUE);
if (!ret) {
fprintf(stderr, "Failed GetOverlappedResult\n");
error_setg(errp, "Failed GetOverlappedResult");
if (ov.hEvent) {
CloseHandle(ov.hEvent);
ov.hEvent = NULL;
@ -2142,8 +2167,12 @@ static int win_chr_pipe_init(CharDriverState *chr, const char *filename)
}
static CharDriverState *qemu_chr_open_pipe(ChardevHostdev *opts)
static CharDriverState *qemu_chr_open_pipe(const char *id,
ChardevBackend *backend,
ChardevReturn *ret,
Error **errp)
{
ChardevHostdev *opts = backend->pipe;
const char *filename = opts->device;
CharDriverState *chr;
WinCharState *s;
@ -2154,7 +2183,7 @@ static CharDriverState *qemu_chr_open_pipe(ChardevHostdev *opts)
chr->chr_write = win_chr_write;
chr->chr_close = win_chr_close;
if (win_chr_pipe_init(chr, filename) < 0) {
if (win_chr_pipe_init(chr, filename, errp) < 0) {
g_free(s);
g_free(chr);
return NULL;
@ -2175,7 +2204,10 @@ static CharDriverState *qemu_chr_open_win_file(HANDLE fd_out)
return chr;
}
static CharDriverState *qemu_chr_open_win_con(void)
static CharDriverState *qemu_chr_open_win_con(const char *id,
ChardevBackend *backend,
ChardevReturn *ret,
Error **errp)
{
return qemu_chr_open_win_file(GetStdHandle(STD_OUTPUT_HANDLE));
}
@ -2316,7 +2348,10 @@ static void win_stdio_close(CharDriverState *chr)
g_free(chr);
}
static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts)
static CharDriverState *qemu_chr_open_stdio(const char *id,
ChardevBackend *backend,
ChardevReturn *ret,
Error **errp)
{
CharDriverState *chr;
WinStdioCharState *stdio;
@ -2328,8 +2363,8 @@ static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts)
stdio->hStdIn = GetStdHandle(STD_INPUT_HANDLE);
if (stdio->hStdIn == INVALID_HANDLE_VALUE) {
fprintf(stderr, "cannot open stdio: invalid handle\n");
exit(1);
error_setg(errp, "cannot open stdio: invalid handle");
return NULL;
}
is_console = GetConsoleMode(stdio->hStdIn, &dwMode) != 0;
@ -2341,25 +2376,30 @@ static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts)
if (is_console) {
if (qemu_add_wait_object(stdio->hStdIn,
win_stdio_wait_func, chr)) {
fprintf(stderr, "qemu_add_wait_object: failed\n");
error_setg(errp, "qemu_add_wait_object: failed");
goto err1;
}
} else {
DWORD dwId;
stdio->hInputReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
stdio->hInputDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
stdio->hInputThread = CreateThread(NULL, 0, win_stdio_thread,
chr, 0, &dwId);
if (stdio->hInputThread == INVALID_HANDLE_VALUE
|| stdio->hInputReadyEvent == INVALID_HANDLE_VALUE
if (stdio->hInputReadyEvent == INVALID_HANDLE_VALUE
|| stdio->hInputDoneEvent == INVALID_HANDLE_VALUE) {
fprintf(stderr, "cannot create stdio thread or event\n");
exit(1);
error_setg(errp, "cannot create event");
goto err2;
}
if (qemu_add_wait_object(stdio->hInputReadyEvent,
win_stdio_thread_wait_func, chr)) {
fprintf(stderr, "qemu_add_wait_object: failed\n");
error_setg(errp, "qemu_add_wait_object: failed");
goto err2;
}
stdio->hInputThread = CreateThread(NULL, 0, win_stdio_thread,
chr, 0, &dwId);
if (stdio->hInputThread == INVALID_HANDLE_VALUE) {
error_setg(errp, "cannot create stdio thread");
goto err3;
}
}
@ -2377,6 +2417,15 @@ static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts)
qemu_chr_fe_set_echo(chr, false);
return chr;
err3:
qemu_del_wait_object(stdio->hInputReadyEvent, NULL, NULL);
err2:
CloseHandle(stdio->hInputReadyEvent);
CloseHandle(stdio->hInputDoneEvent);
err1:
qemu_del_wait_object(stdio->hStdIn, NULL, NULL);
return NULL;
}
#endif /* !_WIN32 */
@ -3173,9 +3222,12 @@ static void ringbuf_chr_close(struct CharDriverState *chr)
chr->opaque = NULL;
}
static CharDriverState *qemu_chr_open_ringbuf(ChardevRingbuf *opts,
static CharDriverState *qemu_chr_open_ringbuf(const char *id,
ChardevBackend *backend,
ChardevReturn *ret,
Error **errp)
{
ChardevRingbuf *opts = backend->ringbuf;
CharDriverState *chr;
RingBufCharDriver *d;
@ -3462,6 +3514,7 @@ static void qemu_chr_parse_stdio(QemuOpts *opts, ChardevBackend *backend,
backend->stdio->signal = qemu_opt_get_bool(opts, "signal", true);
}
#ifdef HAVE_CHARDEV_SERIAL
static void qemu_chr_parse_serial(QemuOpts *opts, ChardevBackend *backend,
Error **errp)
{
@ -3474,7 +3527,9 @@ static void qemu_chr_parse_serial(QemuOpts *opts, ChardevBackend *backend,
backend->serial = g_new0(ChardevHostdev, 1);
backend->serial->device = g_strdup(device);
}
#endif
#ifdef HAVE_CHARDEV_PARPORT
static void qemu_chr_parse_parallel(QemuOpts *opts, ChardevBackend *backend,
Error **errp)
{
@ -3487,6 +3542,7 @@ static void qemu_chr_parse_parallel(QemuOpts *opts, ChardevBackend *backend,
backend->parallel = g_new0(ChardevHostdev, 1);
backend->parallel->device = g_strdup(device);
}
#endif
static void qemu_chr_parse_pipe(QemuOpts *opts, ChardevBackend *backend,
Error **errp)
@ -3641,12 +3697,16 @@ typedef struct CharDriver {
const char *name;
ChardevBackendKind kind;
void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp);
CharDriverState *(*create)(const char *id, ChardevBackend *backend,
ChardevReturn *ret, Error **errp);
} CharDriver;
static GSList *backends;
void register_char_driver(const char *name, ChardevBackendKind kind,
void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp))
void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp),
CharDriverState *(*create)(const char *id, ChardevBackend *backend,
ChardevReturn *ret, Error **errp))
{
CharDriver *s;
@ -3654,6 +3714,7 @@ void register_char_driver(const char *name, ChardevBackendKind kind,
s->name = g_strdup(name);
s->kind = kind;
s->parse = parse;
s->create = create;
backends = g_slist_append(backends, s);
}
@ -4002,8 +4063,12 @@ QemuOptsList qemu_chardev_opts = {
#ifdef _WIN32
static CharDriverState *qmp_chardev_open_file(ChardevFile *file, Error **errp)
static CharDriverState *qmp_chardev_open_file(const char *id,
ChardevBackend *backend,
ChardevReturn *ret,
Error **errp)
{
ChardevFile *file = backend->file;
HANDLE out;
if (file->has_in) {
@ -4020,17 +4085,13 @@ static CharDriverState *qmp_chardev_open_file(ChardevFile *file, Error **errp)
return qemu_chr_open_win_file(out);
}
static CharDriverState *qmp_chardev_open_serial(ChardevHostdev *serial,
static CharDriverState *qmp_chardev_open_serial(const char *id,
ChardevBackend *backend,
ChardevReturn *ret,
Error **errp)
{
return qemu_chr_open_win_path(serial->device);
}
static CharDriverState *qmp_chardev_open_parallel(ChardevHostdev *parallel,
Error **errp)
{
error_setg(errp, "character device backend type 'parallel' not supported");
return NULL;
ChardevHostdev *serial = backend->serial;
return qemu_chr_open_win_path(serial->device, errp);
}
#else /* WIN32 */
@ -4047,8 +4108,12 @@ static int qmp_chardev_open_file_source(char *src, int flags,
return fd;
}
static CharDriverState *qmp_chardev_open_file(ChardevFile *file, Error **errp)
static CharDriverState *qmp_chardev_open_file(const char *id,
ChardevBackend *backend,
ChardevReturn *ret,
Error **errp)
{
ChardevFile *file = backend->file;
int flags, in = -1, out;
flags = O_WRONLY | O_TRUNC | O_CREAT | O_BINARY;
@ -4069,10 +4134,13 @@ static CharDriverState *qmp_chardev_open_file(ChardevFile *file, Error **errp)
return qemu_chr_open_fd(in, out);
}
static CharDriverState *qmp_chardev_open_serial(ChardevHostdev *serial,
#ifdef HAVE_CHARDEV_SERIAL
static CharDriverState *qmp_chardev_open_serial(const char *id,
ChardevBackend *backend,
ChardevReturn *ret,
Error **errp)
{
#ifdef HAVE_CHARDEV_TTY
ChardevHostdev *serial = backend->serial;
int fd;
fd = qmp_chardev_open_file_source(serial->device, O_RDWR, errp);
@ -4081,28 +4149,25 @@ static CharDriverState *qmp_chardev_open_serial(ChardevHostdev *serial,
}
qemu_set_nonblock(fd);
return qemu_chr_open_tty_fd(fd);
#else
error_setg(errp, "character device backend type 'serial' not supported");
return NULL;
#endif
}
#endif
static CharDriverState *qmp_chardev_open_parallel(ChardevHostdev *parallel,
#ifdef HAVE_CHARDEV_PARPORT
static CharDriverState *qmp_chardev_open_parallel(const char *id,
ChardevBackend *backend,
ChardevReturn *ret,
Error **errp)
{
#ifdef HAVE_CHARDEV_PARPORT
ChardevHostdev *parallel = backend->parallel;
int fd;
fd = qmp_chardev_open_file_source(parallel->device, O_RDWR, errp);
if (fd < 0) {
return NULL;
}
return qemu_chr_open_pp_fd(fd);
#else
error_setg(errp, "character device backend type 'parallel' not supported");
return NULL;
#endif
return qemu_chr_open_pp_fd(fd, errp);
}
#endif
#endif /* WIN32 */
@ -4131,11 +4196,14 @@ static gboolean socket_reconnect_timeout(gpointer opaque)
return false;
}
static CharDriverState *qmp_chardev_open_socket(ChardevSocket *sock,
static CharDriverState *qmp_chardev_open_socket(const char *id,
ChardevBackend *backend,
ChardevReturn *ret,
Error **errp)
{
CharDriverState *chr;
TCPCharDriver *s;
ChardevSocket *sock = backend->socket;
SocketAddress *addr = sock->addr;
bool do_nodelay = sock->has_nodelay ? sock->nodelay : false;
bool is_listen = sock->has_server ? sock->server : true;
@ -4197,9 +4265,12 @@ static CharDriverState *qmp_chardev_open_socket(ChardevSocket *sock,
return chr;
}
static CharDriverState *qmp_chardev_open_udp(ChardevUdp *udp,
static CharDriverState *qmp_chardev_open_udp(const char *id,
ChardevBackend *backend,
ChardevReturn *ret,
Error **errp)
{
ChardevUdp *udp = backend->udp;
int fd;
fd = socket_dgram(udp->remote, udp->local, errp);
@ -4213,7 +4284,10 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
Error **errp)
{
ChardevReturn *ret = g_new0(ChardevReturn, 1);
CharDriverState *base, *chr = NULL;
CharDriverState *chr = NULL;
Error *local_err = NULL;
GSList *i;
CharDriver *cd;
chr = qemu_chr_find(id);
if (chr) {
@ -4222,106 +4296,40 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
return NULL;
}
switch (backend->kind) {
case CHARDEV_BACKEND_KIND_FILE:
chr = qmp_chardev_open_file(backend->file, errp);
break;
case CHARDEV_BACKEND_KIND_SERIAL:
chr = qmp_chardev_open_serial(backend->serial, errp);
break;
case CHARDEV_BACKEND_KIND_PARALLEL:
chr = qmp_chardev_open_parallel(backend->parallel, errp);
break;
case CHARDEV_BACKEND_KIND_PIPE:
chr = qemu_chr_open_pipe(backend->pipe);
break;
case CHARDEV_BACKEND_KIND_SOCKET:
chr = qmp_chardev_open_socket(backend->socket, errp);
break;
case CHARDEV_BACKEND_KIND_UDP:
chr = qmp_chardev_open_udp(backend->udp, errp);
break;
#ifdef HAVE_CHARDEV_TTY
case CHARDEV_BACKEND_KIND_PTY:
chr = qemu_chr_open_pty(id, ret);
break;
#endif
case CHARDEV_BACKEND_KIND_NULL:
chr = qemu_chr_open_null();
break;
case CHARDEV_BACKEND_KIND_MUX:
base = qemu_chr_find(backend->mux->chardev);
if (base == NULL) {
error_setg(errp, "mux: base chardev %s not found",
backend->mux->chardev);
for (i = backends; i; i = i->next) {
cd = i->data;
if (cd->kind == backend->kind) {
chr = cd->create(id, backend, ret, &local_err);
if (local_err) {
error_propagate(errp, local_err);
goto out_error;
}
break;
}
chr = qemu_chr_open_mux(base);
break;
case CHARDEV_BACKEND_KIND_MSMOUSE:
chr = qemu_chr_open_msmouse();
break;
#ifdef CONFIG_BRLAPI
case CHARDEV_BACKEND_KIND_BRAILLE:
chr = chr_baum_init();
break;
#endif
case CHARDEV_BACKEND_KIND_TESTDEV:
chr = chr_testdev_init();
break;
case CHARDEV_BACKEND_KIND_STDIO:
chr = qemu_chr_open_stdio(backend->stdio);
break;
#ifdef _WIN32
case CHARDEV_BACKEND_KIND_CONSOLE:
chr = qemu_chr_open_win_con();
break;
#endif
#ifdef CONFIG_SPICE
case CHARDEV_BACKEND_KIND_SPICEVMC:
chr = qemu_chr_open_spice_vmc(backend->spicevmc->type);
break;
case CHARDEV_BACKEND_KIND_SPICEPORT:
chr = qemu_chr_open_spice_port(backend->spiceport->fqdn);
break;
#endif
case CHARDEV_BACKEND_KIND_VC:
chr = vc_init(backend->vc);
break;
case CHARDEV_BACKEND_KIND_RINGBUF:
case CHARDEV_BACKEND_KIND_MEMORY:
chr = qemu_chr_open_ringbuf(backend->ringbuf, errp);
break;
default:
error_setg(errp, "unknown chardev backend (%d)", backend->kind);
break;
}
/*
* Character backend open hasn't been fully converted to the Error
* API. Some opens fail without setting an error. Set a generic
* error then.
* TODO full conversion to Error API
*/
if (chr == NULL && errp && !*errp) {
error_setg(errp, "Failed to create chardev");
if (chr == NULL) {
assert(!i);
error_setg(errp, "chardev backend not available");
goto out_error;
}
if (chr) {
chr->label = g_strdup(id);
chr->avail_connections =
(backend->kind == CHARDEV_BACKEND_KIND_MUX) ? MAX_MUX : 1;
if (!chr->filename) {
chr->filename = g_strdup(ChardevBackendKind_lookup[backend->kind]);
}
if (!chr->explicit_be_open) {
qemu_chr_be_event(chr, CHR_EVENT_OPENED);
}
QTAILQ_INSERT_TAIL(&chardevs, chr, next);
return ret;
} else {
g_free(ret);
return NULL;
chr->label = g_strdup(id);
chr->avail_connections =
(backend->kind == CHARDEV_BACKEND_KIND_MUX) ? MAX_MUX : 1;
if (!chr->filename) {
chr->filename = g_strdup(ChardevBackendKind_lookup[backend->kind]);
}
if (!chr->explicit_be_open) {
qemu_chr_be_event(chr, CHR_EVENT_OPENED);
}
QTAILQ_INSERT_TAIL(&chardevs, chr, next);
return ret;
out_error:
g_free(ret);
return NULL;
}
void qmp_chardev_remove(const char *id, Error **errp)
@ -4343,32 +4351,45 @@ void qmp_chardev_remove(const char *id, Error **errp)
static void register_types(void)
{
register_char_driver("null", CHARDEV_BACKEND_KIND_NULL, NULL);
register_char_driver("null", CHARDEV_BACKEND_KIND_NULL, NULL,
qemu_chr_open_null);
register_char_driver("socket", CHARDEV_BACKEND_KIND_SOCKET,
qemu_chr_parse_socket);
register_char_driver("udp", CHARDEV_BACKEND_KIND_UDP, qemu_chr_parse_udp);
qemu_chr_parse_socket, qmp_chardev_open_socket);
register_char_driver("udp", CHARDEV_BACKEND_KIND_UDP, qemu_chr_parse_udp,
qmp_chardev_open_udp);
register_char_driver("ringbuf", CHARDEV_BACKEND_KIND_RINGBUF,
qemu_chr_parse_ringbuf);
qemu_chr_parse_ringbuf, qemu_chr_open_ringbuf);
register_char_driver("file", CHARDEV_BACKEND_KIND_FILE,
qemu_chr_parse_file_out);
qemu_chr_parse_file_out, qmp_chardev_open_file);
register_char_driver("stdio", CHARDEV_BACKEND_KIND_STDIO,
qemu_chr_parse_stdio);
qemu_chr_parse_stdio, qemu_chr_open_stdio);
#if defined HAVE_CHARDEV_SERIAL
register_char_driver("serial", CHARDEV_BACKEND_KIND_SERIAL,
qemu_chr_parse_serial);
qemu_chr_parse_serial, qmp_chardev_open_serial);
register_char_driver("tty", CHARDEV_BACKEND_KIND_SERIAL,
qemu_chr_parse_serial);
qemu_chr_parse_serial, qmp_chardev_open_serial);
#endif
#ifdef HAVE_CHARDEV_PARPORT
register_char_driver("parallel", CHARDEV_BACKEND_KIND_PARALLEL,
qemu_chr_parse_parallel);
qemu_chr_parse_parallel, qmp_chardev_open_parallel);
register_char_driver("parport", CHARDEV_BACKEND_KIND_PARALLEL,
qemu_chr_parse_parallel);
register_char_driver("pty", CHARDEV_BACKEND_KIND_PTY, NULL);
register_char_driver("console", CHARDEV_BACKEND_KIND_CONSOLE, NULL);
qemu_chr_parse_parallel, qmp_chardev_open_parallel);
#endif
#ifdef HAVE_CHARDEV_PTY
register_char_driver("pty", CHARDEV_BACKEND_KIND_PTY, NULL,
qemu_chr_open_pty);
#endif
#ifdef _WIN32
register_char_driver("console", CHARDEV_BACKEND_KIND_CONSOLE, NULL,
qemu_chr_open_win_con);
#endif
register_char_driver("pipe", CHARDEV_BACKEND_KIND_PIPE,
qemu_chr_parse_pipe);
register_char_driver("mux", CHARDEV_BACKEND_KIND_MUX, qemu_chr_parse_mux);
qemu_chr_parse_pipe, qemu_chr_open_pipe);
register_char_driver("mux", CHARDEV_BACKEND_KIND_MUX, qemu_chr_parse_mux,
qemu_chr_open_mux);
/* Bug-compatibility: */
register_char_driver("memory", CHARDEV_BACKEND_KIND_MEMORY,
qemu_chr_parse_ringbuf);
qemu_chr_parse_ringbuf, qemu_chr_open_ringbuf);
/* this must be done after machine init, since we register FEs with muxes
* as part of realize functions like serial_isa_realizefn when -nographic
* is specified

View File

@ -1010,7 +1010,9 @@ sub possible {
case|
else|
asm|__asm__|
do
do|
\#|
\#\#
)(?:\s|$)|
^(?:typedef|struct|enum)\b
)}x;
@ -1704,11 +1706,6 @@ sub process {
ERROR("open brace '{' following $1 go on the same line\n" . $hereprev);
}
# ... however, open braces on typedef lines should be avoided.
if ($line =~ /^.\s*typedef\s+(enum|union|struct)(?:\s+$Ident\b)?.*[^;]$/) {
ERROR("typedefs should be separate from struct declaration\n" . $herecurr);
}
# missing space after union, struct or enum definition
if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?(?:\s+$Ident)?[=\{]/) {
ERROR("missing space after $1 definition\n" . $herecurr);

View File

@ -296,15 +296,14 @@ static CharDriverState *chr_open(const char *subtype,
return chr;
}
CharDriverState *qemu_chr_open_spice_vmc(const char *type)
static CharDriverState *qemu_chr_open_spice_vmc(const char *id,
ChardevBackend *backend,
ChardevReturn *ret,
Error **errp)
{
const char *type = backend->spicevmc->type;
const char **psubtype = spice_server_char_device_recognized_subtypes();
if (type == NULL) {
fprintf(stderr, "spice-qemu-char: missing name parameter\n");
print_allowed_subtypes();
return NULL;
}
for (; *psubtype != NULL; ++psubtype) {
if (strcmp(type, *psubtype) == 0) {
break;
@ -320,8 +319,12 @@ CharDriverState *qemu_chr_open_spice_vmc(const char *type)
}
#if SPICE_SERVER_VERSION >= 0x000c02
CharDriverState *qemu_chr_open_spice_port(const char *name)
static CharDriverState *qemu_chr_open_spice_port(const char *id,
ChardevBackend *backend,
ChardevReturn *ret,
Error **errp)
{
const char *name = backend->spiceport->fqdn;
CharDriverState *chr;
SpiceCharDriver *s;
@ -379,9 +382,9 @@ static void qemu_chr_parse_spice_port(QemuOpts *opts, ChardevBackend *backend,
static void register_types(void)
{
register_char_driver("spicevmc", CHARDEV_BACKEND_KIND_SPICEVMC,
qemu_chr_parse_spice_vmc);
qemu_chr_parse_spice_vmc, qemu_chr_open_spice_vmc);
register_char_driver("spiceport", CHARDEV_BACKEND_KIND_SPICEPORT,
qemu_chr_parse_spice_port);
qemu_chr_parse_spice_port, qemu_chr_open_spice_port);
}
type_init(register_types);

View File

@ -1,8 +1,5 @@
stub-obj-y += arch-query-cpu-def.o
stub-obj-y += bdrv-commit-all.o
stub-obj-y += chr-baum-init.o
stub-obj-y += chr-msmouse.o
stub-obj-y += chr-testdev.o
stub-obj-y += clock-warp.o
stub-obj-y += cpu-get-clock.o
stub-obj-y += cpu-get-icount.o
@ -23,7 +20,6 @@ stub-obj-y += mon-is-qmp.o
stub-obj-y += mon-printf.o
stub-obj-y += monitor-init.o
stub-obj-y += notify-event.o
stub-obj-$(CONFIG_SPICE) += qemu-chr-open-spice.o
stub-obj-y += qtest.o
stub-obj-y += reset.o
stub-obj-y += runstate-check.o
@ -31,7 +27,6 @@ stub-obj-y += set-fd-handler.o
stub-obj-y += slirp.o
stub-obj-y += sysbus.o
stub-obj-y += uuid.o
stub-obj-y += vc-init.o
stub-obj-y += vm-stop.o
stub-obj-y += vmstate.o
stub-obj-$(CONFIG_WIN32) += fd-register.o

View File

@ -1,7 +0,0 @@
#include "qemu-common.h"
#include "sysemu/char.h"
CharDriverState *chr_baum_init(void)
{
return NULL;
}

View File

@ -1,7 +0,0 @@
#include "qemu-common.h"
#include "sysemu/char.h"
CharDriverState *qemu_chr_open_msmouse(void)
{
return 0;
}

View File

@ -1,7 +0,0 @@
#include "qemu-common.h"
#include "sysemu/char.h"
CharDriverState *chr_testdev_init(void)
{
return 0;
}

View File

@ -1,14 +0,0 @@
#include "qemu-common.h"
#include "ui/qemu-spice.h"
CharDriverState *qemu_chr_open_spice_vmc(const char *type)
{
return NULL;
}
#if SPICE_SERVER_VERSION >= 0x000c02
CharDriverState *qemu_chr_open_spice_port(const char *name)
{
return NULL;
}
#endif

View File

@ -1,7 +0,0 @@
#include "qemu-common.h"
#include "sysemu/char.h"
CharDriverState *vc_init(ChardevVC *vc)
{
return 0;
}

View File

@ -605,7 +605,7 @@ int kvm_arm_vgic_probe(void)
}
int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
uint64_t address, uint32_t data)
uint64_t address, uint32_t data, PCIDevice *dev)
{
return 0;
}

View File

@ -88,8 +88,12 @@ typedef struct X86CPU {
bool hyperv_vapic;
bool hyperv_relaxed_timing;
int hyperv_spinlock_attempts;
char *hyperv_vendor_id;
bool hyperv_time;
bool hyperv_crash;
bool hyperv_reset;
bool hyperv_vpindex;
bool hyperv_runtime;
bool check_cpuid;
bool enforce_cpuid;
bool expose_kvm;

View File

@ -3140,12 +3140,16 @@ static Property x86_cpu_properties[] = {
DEFINE_PROP_BOOL("hv-vapic", X86CPU, hyperv_vapic, false),
DEFINE_PROP_BOOL("hv-time", X86CPU, hyperv_time, false),
DEFINE_PROP_BOOL("hv-crash", X86CPU, hyperv_crash, false),
DEFINE_PROP_BOOL("hv-reset", X86CPU, hyperv_reset, false),
DEFINE_PROP_BOOL("hv-vpindex", X86CPU, hyperv_vpindex, false),
DEFINE_PROP_BOOL("hv-runtime", X86CPU, hyperv_runtime, false),
DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, false),
DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false),
DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true),
DEFINE_PROP_UINT32("level", X86CPU, env.cpuid_level, 0),
DEFINE_PROP_UINT32("xlevel", X86CPU, env.cpuid_xlevel, 0),
DEFINE_PROP_UINT32("xlevel2", X86CPU, env.cpuid_xlevel2, 0),
DEFINE_PROP_STRING("hv-vendor-id", X86CPU, hyperv_vendor_id),
DEFINE_PROP_END_OF_LIST()
};

View File

@ -911,6 +911,7 @@ typedef struct CPUX86State {
uint64_t msr_hv_vapic;
uint64_t msr_hv_tsc;
uint64_t msr_hv_crash_params[HV_X64_MSR_CRASH_PARAMS];
uint64_t msr_hv_runtime;
/* exception/interrupt handling */
int error_code;

View File

@ -28,6 +28,7 @@
#include "exec/gdbstub.h"
#include "qemu/host-utils.h"
#include "qemu/config-file.h"
#include "qemu/error-report.h"
#include "hw/i386/pc.h"
#include "hw/i386/apic.h"
#include "hw/i386/apic_internal.h"
@ -82,12 +83,24 @@ static bool has_msr_hv_hypercall;
static bool has_msr_hv_vapic;
static bool has_msr_hv_tsc;
static bool has_msr_hv_crash;
static bool has_msr_hv_reset;
static bool has_msr_hv_vpindex;
static bool has_msr_hv_runtime;
static bool has_msr_mtrr;
static bool has_msr_xss;
static bool has_msr_architectural_pmu;
static uint32_t num_architectural_pmu_counters;
static int has_xsave;
static int has_xcrs;
static int has_pit_state2;
int kvm_has_pit_state2(void)
{
return has_pit_state2;
}
bool kvm_has_smm(void)
{
return kvm_check_extension(kvm_state, KVM_CAP_X86_SMM);
@ -460,7 +473,10 @@ static bool hyperv_enabled(X86CPU *cpu)
(hyperv_hypercall_available(cpu) ||
cpu->hyperv_time ||
cpu->hyperv_relaxed_timing ||
cpu->hyperv_crash);
cpu->hyperv_crash ||
cpu->hyperv_reset ||
cpu->hyperv_vpindex ||
cpu->hyperv_runtime);
}
static Error *invtsc_mig_blocker;
@ -490,7 +506,18 @@ int kvm_arch_init_vcpu(CPUState *cs)
if (hyperv_enabled(cpu)) {
c = &cpuid_data.entries[cpuid_i++];
c->function = HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS;
memcpy(signature, "Microsoft Hv", 12);
if (!cpu->hyperv_vendor_id) {
memcpy(signature, "Microsoft Hv", 12);
} else {
size_t len = strlen(cpu->hyperv_vendor_id);
if (len > 12) {
error_report("hv-vendor-id truncated to 12 characters");
len = 12;
}
memset(signature, 0, 12);
memcpy(signature, cpu->hyperv_vendor_id, len);
}
c->eax = HYPERV_CPUID_MIN;
c->ebx = signature[0];
c->ecx = signature[1];
@ -529,7 +556,15 @@ int kvm_arch_init_vcpu(CPUState *cs)
if (cpu->hyperv_crash && has_msr_hv_crash) {
c->edx |= HV_X64_GUEST_CRASH_MSR_AVAILABLE;
}
if (cpu->hyperv_reset && has_msr_hv_reset) {
c->eax |= HV_X64_MSR_RESET_AVAILABLE;
}
if (cpu->hyperv_vpindex && has_msr_hv_vpindex) {
c->eax |= HV_X64_MSR_VP_INDEX_AVAILABLE;
}
if (cpu->hyperv_runtime && has_msr_hv_runtime) {
c->eax |= HV_X64_MSR_VP_RUNTIME_AVAILABLE;
}
c = &cpuid_data.entries[cpuid_i++];
c->function = HYPERV_CPUID_ENLIGHTMENT_INFO;
if (cpu->hyperv_relaxed_timing) {
@ -752,7 +787,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
}
}
if (kvm_has_xsave()) {
if (has_xsave) {
env->kvm_xsave_buf = qemu_memalign(4096, sizeof(struct kvm_xsave));
}
@ -858,6 +893,18 @@ static int kvm_get_supported_msrs(KVMState *s)
has_msr_hv_crash = true;
continue;
}
if (kvm_msr_list->indices[i] == HV_X64_MSR_RESET) {
has_msr_hv_reset = true;
continue;
}
if (kvm_msr_list->indices[i] == HV_X64_MSR_VP_INDEX) {
has_msr_hv_vpindex = true;
continue;
}
if (kvm_msr_list->indices[i] == HV_X64_MSR_VP_RUNTIME) {
has_msr_hv_runtime = true;
continue;
}
}
}
@ -908,6 +955,18 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
int ret;
struct utsname utsname;
#ifdef KVM_CAP_XSAVE
has_xsave = kvm_check_extension(s, KVM_CAP_XSAVE);
#endif
#ifdef KVM_CAP_XCRS
has_xcrs = kvm_check_extension(s, KVM_CAP_XCRS);
#endif
#ifdef KVM_CAP_PIT_STATE2
has_pit_state2 = kvm_check_extension(s, KVM_CAP_PIT_STATE2);
#endif
ret = kvm_get_supported_msrs(s);
if (ret < 0) {
return ret;
@ -1116,7 +1175,7 @@ static int kvm_put_xsave(X86CPU *cpu)
uint8_t *xmm, *ymmh, *zmmh;
int i, r;
if (!kvm_has_xsave()) {
if (!has_xsave) {
return kvm_put_fpu(cpu);
}
@ -1170,7 +1229,7 @@ static int kvm_put_xcrs(X86CPU *cpu)
CPUX86State *env = &cpu->env;
struct kvm_xcrs xcrs = {};
if (!kvm_has_xcrs()) {
if (!has_xcrs) {
return 0;
}
@ -1403,6 +1462,10 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_CRASH_CTL,
HV_X64_MSR_CRASH_CTL_NOTIFY);
}
if (has_msr_hv_runtime) {
kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_VP_RUNTIME,
env->msr_hv_runtime);
}
if (has_msr_mtrr) {
kvm_msr_entry_set(&msrs[n++], MSR_MTRRdefType, env->mtrr_deftype);
kvm_msr_entry_set(&msrs[n++],
@ -1495,7 +1558,7 @@ static int kvm_get_xsave(X86CPU *cpu)
const uint8_t *xmm, *ymmh, *zmmh;
uint16_t cwd, swd, twd;
if (!kvm_has_xsave()) {
if (!has_xsave) {
return kvm_get_fpu(cpu);
}
@ -1554,7 +1617,7 @@ static int kvm_get_xcrs(X86CPU *cpu)
int i, ret;
struct kvm_xcrs xcrs;
if (!kvm_has_xcrs()) {
if (!has_xcrs) {
return 0;
}
@ -1768,6 +1831,9 @@ static int kvm_get_msrs(X86CPU *cpu)
msrs[n++].index = HV_X64_MSR_CRASH_P0 + j;
}
}
if (has_msr_hv_runtime) {
msrs[n++].index = HV_X64_MSR_VP_RUNTIME;
}
if (has_msr_mtrr) {
msrs[n++].index = MSR_MTRRdefType;
msrs[n++].index = MSR_MTRRfix64K_00000;
@ -1921,6 +1987,9 @@ static int kvm_get_msrs(X86CPU *cpu)
case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
env->msr_hv_crash_params[index - HV_X64_MSR_CRASH_P0] = msrs[i].data;
break;
case HV_X64_MSR_VP_RUNTIME:
env->msr_hv_runtime = msrs[i].data;
break;
case MSR_MTRRdefType:
env->mtrr_deftype = msrs[i].data;
break;
@ -2956,7 +3025,7 @@ int kvm_device_msix_deassign(KVMState *s, uint32_t dev_id)
}
int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
uint64_t address, uint32_t data)
uint64_t address, uint32_t data, PCIDevice *dev)
{
return 0;
}

View File

@ -687,6 +687,25 @@ static const VMStateDescription vmstate_msr_hyperv_crash = {
}
};
static bool hyperv_runtime_enable_needed(void *opaque)
{
X86CPU *cpu = opaque;
CPUX86State *env = &cpu->env;
return env->msr_hv_runtime != 0;
}
static const VMStateDescription vmstate_msr_hyperv_runtime = {
.name = "cpu/msr_hyperv_runtime",
.version_id = 1,
.minimum_version_id = 1,
.needed = hyperv_runtime_enable_needed,
.fields = (VMStateField[]) {
VMSTATE_UINT64(env.msr_hv_runtime, X86CPU),
VMSTATE_END_OF_LIST()
}
};
static bool avx512_needed(void *opaque)
{
X86CPU *cpu = opaque;
@ -869,6 +888,7 @@ VMStateDescription vmstate_x86_cpu = {
&vmstate_msr_hyperv_vapic,
&vmstate_msr_hyperv_time,
&vmstate_msr_hyperv_crash,
&vmstate_msr_hyperv_runtime,
&vmstate_avx512,
&vmstate_xss,
NULL

View File

@ -678,7 +678,7 @@ int kvm_arch_get_registers(CPUState *cs)
}
int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
uint64_t address, uint32_t data)
uint64_t address, uint32_t data, PCIDevice *dev)
{
return 0;
}

View File

@ -2483,7 +2483,7 @@ error_out:
}
int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
uint64_t address, uint32_t data)
uint64_t address, uint32_t data, PCIDevice *dev)
{
return 0;
}

View File

@ -2208,7 +2208,7 @@ int kvm_s390_vcpu_interrupt_post_load(S390CPU *cpu)
}
int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
uint64_t address, uint32_t data)
uint64_t address, uint32_t data, PCIDevice *dev)
{
S390PCIBusDevice *pbdev;
uint32_t fid = data >> ZPCI_MSI_VEC_BITS;

View File

@ -1962,7 +1962,7 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
chr->init(chr);
}
static CharDriverState *text_console_init(ChardevVC *vc)
static CharDriverState *text_console_init(ChardevVC *vc, Error **errp)
{
CharDriverState *chr;
QemuConsole *s;
@ -1993,6 +1993,7 @@ static CharDriverState *text_console_init(ChardevVC *vc)
if (!s) {
g_free(chr);
error_setg(errp, "cannot create text console");
return NULL;
}
@ -2012,9 +2013,10 @@ static CharDriverState *text_console_init(ChardevVC *vc)
static VcHandler *vc_handler = text_console_init;
CharDriverState *vc_init(ChardevVC *vc)
static CharDriverState *vc_init(const char *id, ChardevBackend *backend,
ChardevReturn *ret, Error **errp)
{
return vc_handler(vc);
return vc_handler(backend->vc, errp);
}
void register_vc_handler(VcHandler *handler)
@ -2093,7 +2095,8 @@ static const TypeInfo qemu_console_info = {
static void register_types(void)
{
type_register_static(&qemu_console_info);
register_char_driver("vc", CHARDEV_BACKEND_KIND_VC, qemu_chr_parse_vc);
register_char_driver("vc", CHARDEV_BACKEND_KIND_VC, qemu_chr_parse_vc,
vc_init);
}
type_init(register_types);

View File

@ -1591,7 +1591,7 @@ static int gd_vc_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
static int nb_vcs;
static CharDriverState *vcs[MAX_VCS];
static CharDriverState *gd_vc_handler(ChardevVC *unused)
static CharDriverState *gd_vc_handler(ChardevVC *unused, Error **errp)
{
CharDriverState *chr;

View File

@ -586,12 +586,15 @@ fail:
static void inet_addr_to_opts(QemuOpts *opts, const InetSocketAddress *addr)
{
bool ipv4 = addr->ipv4 || !addr->has_ipv4;
bool ipv6 = addr->ipv6 || !addr->has_ipv6;
bool ipv4 = addr->has_ipv4 && addr->ipv4;
bool ipv6 = addr->has_ipv6 && addr->ipv6;
if (!ipv4 || !ipv6) {
if (ipv4 || ipv6) {
qemu_opt_set_bool(opts, "ipv4", ipv4, &error_abort);
qemu_opt_set_bool(opts, "ipv6", ipv6, &error_abort);
} else if (addr->has_ipv4 || addr->has_ipv6) {
qemu_opt_set_bool(opts, "ipv4", !addr->has_ipv4, &error_abort);
qemu_opt_set_bool(opts, "ipv6", !addr->has_ipv6, &error_abort);
}
if (addr->has_to) {
qemu_opt_set_number(opts, "to", addr->to, &error_abort);