* More uses of RCU_READ_LOCK_GUARD (Dave, myself)

* QOM doc improvments (Greg)
 * Cleanups from the Meson conversion (Marc-André)
 * Support for multiple -accel options (myself)
 * Many x86 machine cleanup (Philippe, myself)
 * tests/migration-test cleanup (Juan)
 * PC machine removal and next round of deprecation (Thomas)
 * kernel-doc integration (Peter, myself)
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.22 (GNU/Linux)
 
 iQEcBAABAgAGBQJd+YJGAAoJEL/70l94x66D0YYIAIZpS6i6NYJC8KHCl49fjI7U
 qHDN7MiKYTU+l3i0+iGmQL6XN5ClAY0pXkY5LBFIDpsohHR5f4jdrIKjyvcHzuIM
 gx/NLsiA45/niHYrn/hEo0P7CwGTrrdWL+SVmScnKcwYiBzMO/uYblxlbUBKLPNn
 eGaKQmEkvlUBR9GS6S1+jYg8234ZRZ4+12t5dqqADBQ7Kc0wn6KC5yebIoQxCgVc
 9F5Ezdkl7befrTI7El3EC6aT18bKhIBZIs1PT/hzqzlGFhBuKM7uKDb43Yx8c7XQ
 bk5vzHmblPAgQyK4OETQ+DM745AOk6vBiJZbR9nrDUXWvUkrEXTQZMJKU0FXdlE=
 =hyYX
 -----END PGP SIGNATURE-----

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

* More uses of RCU_READ_LOCK_GUARD (Dave, myself)
* QOM doc improvments (Greg)
* Cleanups from the Meson conversion (Marc-André)
* Support for multiple -accel options (myself)
* Many x86 machine cleanup (Philippe, myself)
* tests/migration-test cleanup (Juan)
* PC machine removal and next round of deprecation (Thomas)
* kernel-doc integration (Peter, myself)

# gpg: Signature made Wed 18 Dec 2019 01:35:02 GMT
# gpg:                using RSA key BFFBD25F78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full]
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>" [full]
# 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: (87 commits)
  vga: cleanup mapping of VRAM for non-PCI VGA
  hw/display: Remove "rombar" hack from vga-pci and vmware_vga
  hw/pci: Remove the "command_serr_enable" property
  hw/audio: Remove the "use_broken_id" hack from the AC97 device
  hw/i386: Remove the deprecated machines 0.12 up to 0.15
  hw/pci-host: Add Kconfig entry to select the IGD Passthrough Host Bridge
  hw/pci-host/i440fx: Extract the IGD passthrough host bridge device
  hw/pci-host/i440fx: Use definitions instead of magic values
  hw/pci-host/i440fx: Use size_t to iterate over ARRAY_SIZE()
  hw/pci-host/i440fx: Extract PCII440FXState to "hw/pci-host/i440fx.h"
  hw/pci-host/i440fx: Correct the header description
  Fix some comment spelling errors.
  target/i386: remove unused pci-assign codes
  WHPX: refactor load library
  migration: check length directly to make sure the range is aligned
  memory: include MemoryListener documentation and some missing function parameters
  docs: add memory API reference
  memory.h: Silence kernel-doc complaints
  docs: Create bitops.rst as example of kernel-docs
  bitops.h: Silence kernel-doc complaints
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2019-12-20 11:20:25 +00:00
commit 4800819827
133 changed files with 4247 additions and 1551 deletions

View File

@ -25,6 +25,11 @@ config TPM
config VHOST_USER
bool
select VHOST
config VHOST_KERNEL
bool
select VHOST
config XEN
bool

View File

@ -420,6 +420,7 @@ F: hw/block/dataplane/xen*
F: hw/xen/
F: hw/xenpv/
F: hw/i386/xen/
F: hw/pci-host/xen_igd_pt.c
F: include/hw/block/dataplane/xen*
F: include/hw/xen/
F: include/sysemu/xen-mapcache.h

View File

@ -321,14 +321,10 @@ HELPERS-y =
HELPERS-$(call land,$(CONFIG_SOFTMMU),$(CONFIG_LINUX)) = qemu-bridge-helper$(EXESUF)
ifdef CONFIG_LINUX
ifdef CONFIG_VIRGL
ifdef CONFIG_GBM
ifeq ($(CONFIG_LINUX)$(CONFIG_VIRGL)$(CONFIG_GBM)$(CONFIG_TOOLS),yyyy)
HELPERS-y += vhost-user-gpu$(EXESUF)
vhost-user-json-y += contrib/vhost-user-gpu/50-qemu-gpu.json
endif
endif
endif
# Sphinx does not allow building manuals into the same directory as
# the source files, so if we're doing an in-tree QEMU build we must
@ -386,6 +382,7 @@ MINIKCONF_ARGS = \
CONFIG_OPENGL=$(CONFIG_OPENGL) \
CONFIG_X11=$(CONFIG_X11) \
CONFIG_VHOST_USER=$(CONFIG_VHOST_USER) \
CONFIG_VHOST_KERNEL=$(CONFIG_VHOST_KERNEL) \
CONFIG_VIRTFS=$(CONFIG_VIRTFS) \
CONFIG_LINUX=$(CONFIG_LINUX) \
CONFIG_PVRDMA=$(CONFIG_PVRDMA)
@ -440,15 +437,10 @@ dummy := $(call unnest-vars,, \
block-obj-y \
block-obj-m \
crypto-obj-y \
crypto-user-obj-y \
qom-obj-y \
io-obj-y \
common-obj-y \
common-obj-m \
ui-obj-y \
ui-obj-m \
audio-obj-y \
audio-obj-m \
trace-obj-y)
include $(SRC_PATH)/tests/Makefile.include
@ -532,7 +524,7 @@ subdir-capstone: capstone/all
subdir-slirp: slirp/all
$(filter %/all, $(TARGET_DIRS_RULES)): libqemuutil.a $(common-obj-y) \
$(qom-obj-y) $(crypto-user-obj-$(CONFIG_USER_ONLY))
$(qom-obj-y)
ROM_DIRS = $(addprefix pc-bios/, $(ROMS))
ROM_DIRS_RULES=$(foreach t, all clean, $(addsuffix /$(t), $(ROM_DIRS)))
@ -1009,7 +1001,7 @@ sphinxdocs: $(MANUAL_BUILDDIR)/devel/index.html $(MANUAL_BUILDDIR)/interop/index
# Note the use of different doctree for each (manual, builder) tuple;
# this works around Sphinx not handling parallel invocation on
# a single doctree: https://github.com/sphinx-doc/sphinx/issues/2946
build-manual = $(call quiet-command,CONFDIR="$(qemu_confdir)" sphinx-build $(if $(V),,-q) -W -n -b $2 -D version=$(VERSION) -D release="$(FULL_VERSION)" -d .doctrees/$1-$2 $(SRC_PATH)/docs/$1 $(MANUAL_BUILDDIR)/$1 ,"SPHINX","$(MANUAL_BUILDDIR)/$1")
build-manual = $(call quiet-command,CONFDIR="$(qemu_confdir)" sphinx-build $(if $(V),,-q) -W -b $2 -D version=$(VERSION) -D release="$(FULL_VERSION)" -d .doctrees/$1-$2 $(SRC_PATH)/docs/$1 $(MANUAL_BUILDDIR)/$1 ,"SPHINX","$(MANUAL_BUILDDIR)/$1")
# We assume all RST files in the manual's directory are used in it
manual-deps = $(wildcard $(SRC_PATH)/docs/$1/*.rst) $(SRC_PATH)/docs/$1/conf.py $(SRC_PATH)/docs/conf.py

View File

@ -1,7 +1,7 @@
#######################################################################
# Common libraries for tools and emulators
stub-obj-y = stubs/ util/ crypto/
util-obj-y = util/ qobject/ qapi/
stub-obj-y = stubs/
util-obj-y = crypto/ util/ qobject/ qapi/
chardev-obj-y = chardev/
@ -25,7 +25,6 @@ block-obj-m = block/
# crypto-obj-y is code used by both qemu system emulation and qemu-img
crypto-obj-y = crypto/
crypto-user-obj-y = crypto/
#######################################################################
# qom-obj-y is code used by both qemu system emulation and qemu-img
@ -55,6 +54,7 @@ common-obj-$(CONFIG_POSIX) += os-posix.o
common-obj-$(CONFIG_LINUX) += fsdev/
common-obj-y += accel/
common-obj-y += migration/
common-obj-y += audio/

View File

@ -184,7 +184,6 @@ dummy := $(call unnest-vars,.., \
block-obj-m \
chardev-obj-y \
crypto-obj-y \
crypto-user-obj-y \
qom-obj-y \
io-obj-y \
common-obj-y \
@ -193,7 +192,6 @@ all-obj-y += $(common-obj-y)
all-obj-y += $(qom-obj-y)
all-obj-$(CONFIG_SOFTMMU) += $(authz-obj-y)
all-obj-$(CONFIG_SOFTMMU) += $(block-obj-y) $(chardev-obj-y)
all-obj-$(CONFIG_USER_ONLY) += $(crypto-user-obj-y)
all-obj-$(CONFIG_SOFTMMU) += $(crypto-obj-y)
all-obj-$(CONFIG_SOFTMMU) += $(io-obj-y)

View File

@ -1,4 +1,4 @@
obj-$(CONFIG_SOFTMMU) += accel.o
common-obj-$(CONFIG_SOFTMMU) += accel.o
obj-$(call land,$(CONFIG_SOFTMMU),$(CONFIG_POSIX)) += qtest.o
obj-$(CONFIG_KVM) += kvm/
obj-$(CONFIG_TCG) += tcg/

View File

@ -28,13 +28,7 @@
#include "hw/boards.h"
#include "sysemu/arch_init.h"
#include "sysemu/sysemu.h"
#include "sysemu/kvm.h"
#include "sysemu/qtest.h"
#include "hw/xen/xen.h"
#include "qom/object.h"
#include "qemu/error-report.h"
#include "qemu/option.h"
#include "qapi/error.h"
static const TypeInfo accel_type = {
.name = TYPE_ACCEL,
@ -44,7 +38,7 @@ static const TypeInfo accel_type = {
};
/* Lookup AccelClass from opt_name. Returns NULL if not found */
static AccelClass *accel_find(const char *opt_name)
AccelClass *accel_find(const char *opt_name)
{
char *class_name = g_strdup_printf(ACCEL_CLASS_NAME("%s"), opt_name);
AccelClass *ac = ACCEL_CLASS(object_class_by_name(class_name));
@ -52,11 +46,9 @@ static AccelClass *accel_find(const char *opt_name)
return ac;
}
static int accel_init_machine(AccelClass *acc, MachineState *ms)
int accel_init_machine(AccelState *accel, MachineState *ms)
{
ObjectClass *oc = OBJECT_CLASS(acc);
const char *cname = object_class_get_name(oc);
AccelState *accel = ACCEL(object_new(cname));
AccelClass *acc = ACCEL_GET_CLASS(accel);
int ret;
ms->accelerator = accel;
*(acc->allowed) = true;
@ -71,65 +63,6 @@ static int accel_init_machine(AccelClass *acc, MachineState *ms)
return ret;
}
void configure_accelerator(MachineState *ms, const char *progname)
{
const char *accel;
char **accel_list, **tmp;
int ret;
bool accel_initialised = false;
bool init_failed = false;
AccelClass *acc = NULL;
accel = qemu_opt_get(qemu_get_machine_opts(), "accel");
if (accel == NULL) {
/* Select the default accelerator */
int pnlen = strlen(progname);
if (pnlen >= 3 && g_str_equal(&progname[pnlen - 3], "kvm")) {
/* If the program name ends with "kvm", we prefer KVM */
accel = "kvm:tcg";
} else {
#if defined(CONFIG_TCG)
accel = "tcg";
#elif defined(CONFIG_KVM)
accel = "kvm";
#else
error_report("No accelerator selected and"
" no default accelerator available");
exit(1);
#endif
}
}
accel_list = g_strsplit(accel, ":", 0);
for (tmp = accel_list; !accel_initialised && tmp && *tmp; tmp++) {
acc = accel_find(*tmp);
if (!acc) {
continue;
}
ret = accel_init_machine(acc, ms);
if (ret < 0) {
init_failed = true;
error_report("failed to initialize %s: %s",
acc->name, strerror(-ret));
} else {
accel_initialised = true;
}
}
g_strfreev(accel_list);
if (!accel_initialised) {
if (!init_failed) {
error_report("-machine accel=%s: No accelerator found", accel);
}
exit(1);
}
if (init_failed) {
error_report("Back to %s accelerator", acc->name);
}
}
void accel_setup_post(MachineState *ms)
{
AccelState *accel = ms->accelerator;

View File

@ -41,6 +41,9 @@
#include "hw/irq.h"
#include "sysemu/sev.h"
#include "sysemu/balloon.h"
#include "qapi/visitor.h"
#include "qapi/qapi-types-common.h"
#include "qapi/qapi-visit-common.h"
#include "hw/boards.h"
@ -92,6 +95,10 @@ struct KVMState
int max_nested_state_len;
int many_ioeventfds;
int intx_set_mask;
int kvm_shadow_mem;
bool kernel_irqchip_allowed;
bool kernel_irqchip_required;
bool kernel_irqchip_split;
bool sync_mmu;
bool manual_dirty_log_protect;
/* The man page (and posix) say ioctl numbers are signed int, but
@ -518,6 +525,27 @@ static int kvm_get_dirty_pages_log_range(MemoryRegionSection *section,
#define ALIGN(x, y) (((x)+(y)-1) & ~((y)-1))
/* Allocate the dirty bitmap for a slot */
static void kvm_memslot_init_dirty_bitmap(KVMSlot *mem)
{
/*
* XXX bad kernel interface alert
* For dirty bitmap, kernel allocates array of size aligned to
* bits-per-long. But for case when the kernel is 64bits and
* the userspace is 32bits, userspace can't align to the same
* bits-per-long, since sizeof(long) is different between kernel
* and user space. This way, userspace will provide buffer which
* may be 4 bytes less than the kernel will use, resulting in
* userspace memory corruption (which is not detectable by valgrind
* too, in most cases).
* So for now, let's align to 64 instead of HOST_LONG_BITS here, in
* a hope that sizeof(long) won't become >8 any time soon.
*/
hwaddr bitmap_size = ALIGN(((mem->memory_size) >> TARGET_PAGE_BITS),
/*HOST_LONG_BITS*/ 64) / 8;
mem->dirty_bmap = g_malloc0(bitmap_size);
}
/**
* kvm_physical_sync_dirty_bitmap - Sync dirty bitmap from kernel space
*
@ -550,23 +578,9 @@ static int kvm_physical_sync_dirty_bitmap(KVMMemoryListener *kml,
goto out;
}
/* XXX bad kernel interface alert
* For dirty bitmap, kernel allocates array of size aligned to
* bits-per-long. But for case when the kernel is 64bits and
* the userspace is 32bits, userspace can't align to the same
* bits-per-long, since sizeof(long) is different between kernel
* and user space. This way, userspace will provide buffer which
* may be 4 bytes less than the kernel will use, resulting in
* userspace memory corruption (which is not detectable by valgrind
* too, in most cases).
* So for now, let's align to 64 instead of HOST_LONG_BITS here, in
* a hope that sizeof(long) won't become >8 any time soon.
*/
if (!mem->dirty_bmap) {
hwaddr bitmap_size = ALIGN(((mem->memory_size) >> TARGET_PAGE_BITS),
/*HOST_LONG_BITS*/ 64) / 8;
/* Allocate on the first log_sync, once and for all */
mem->dirty_bmap = g_malloc0(bitmap_size);
kvm_memslot_init_dirty_bitmap(mem);
}
d.dirty_bitmap = mem->dirty_bmap;
@ -1067,6 +1081,13 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
mem->ram = ram;
mem->flags = kvm_mem_flags(mr);
if (mem->flags & KVM_MEM_LOG_DIRTY_PAGES) {
/*
* Reallocate the bmap; it means it doesn't disappear in
* middle of a migrate.
*/
kvm_memslot_init_dirty_bitmap(mem);
}
err = kvm_set_user_memory_region(kml, mem, true);
if (err) {
fprintf(stderr, "%s: error registering slot: %s\n", __func__,
@ -1758,7 +1779,7 @@ void kvm_irqchip_set_qemuirq_gsi(KVMState *s, qemu_irq irq, int gsi)
g_hash_table_insert(s->gsimap, irq, GINT_TO_POINTER(gsi));
}
static void kvm_irqchip_create(MachineState *machine, KVMState *s)
static void kvm_irqchip_create(KVMState *s)
{
int ret;
@ -1776,9 +1797,9 @@ static void kvm_irqchip_create(MachineState *machine, KVMState *s)
/* First probe and see if there's a arch-specific hook to create the
* in-kernel irqchip for us */
ret = kvm_arch_irqchip_create(machine, s);
ret = kvm_arch_irqchip_create(s);
if (ret == 0) {
if (machine_kernel_irqchip_split(machine)) {
if (s->kernel_irqchip_split) {
perror("Split IRQ chip mode not supported.");
exit(1);
} else {
@ -2049,8 +2070,8 @@ static int kvm_init(MachineState *ms)
goto err;
}
if (machine_kernel_irqchip_allowed(ms)) {
kvm_irqchip_create(ms, s);
if (s->kernel_irqchip_allowed) {
kvm_irqchip_create(s);
}
if (kvm_eventfds_allowed) {
@ -2940,6 +2961,93 @@ static bool kvm_accel_has_memory(MachineState *ms, AddressSpace *as,
return false;
}
static void kvm_get_kvm_shadow_mem(Object *obj, Visitor *v,
const char *name, void *opaque,
Error **errp)
{
KVMState *s = KVM_STATE(obj);
int64_t value = s->kvm_shadow_mem;
visit_type_int(v, name, &value, errp);
}
static void kvm_set_kvm_shadow_mem(Object *obj, Visitor *v,
const char *name, void *opaque,
Error **errp)
{
KVMState *s = KVM_STATE(obj);
Error *error = NULL;
int64_t value;
visit_type_int(v, name, &value, &error);
if (error) {
error_propagate(errp, error);
return;
}
s->kvm_shadow_mem = value;
}
static void kvm_set_kernel_irqchip(Object *obj, Visitor *v,
const char *name, void *opaque,
Error **errp)
{
Error *err = NULL;
KVMState *s = KVM_STATE(obj);
OnOffSplit mode;
visit_type_OnOffSplit(v, name, &mode, &err);
if (err) {
error_propagate(errp, err);
return;
} else {
switch (mode) {
case ON_OFF_SPLIT_ON:
s->kernel_irqchip_allowed = true;
s->kernel_irqchip_required = true;
s->kernel_irqchip_split = false;
break;
case ON_OFF_SPLIT_OFF:
s->kernel_irqchip_allowed = false;
s->kernel_irqchip_required = false;
s->kernel_irqchip_split = false;
break;
case ON_OFF_SPLIT_SPLIT:
s->kernel_irqchip_allowed = true;
s->kernel_irqchip_required = true;
s->kernel_irqchip_split = true;
break;
default:
/* The value was checked in visit_type_OnOffSplit() above. If
* we get here, then something is wrong in QEMU.
*/
abort();
}
}
}
bool kvm_kernel_irqchip_allowed(void)
{
return kvm_state->kernel_irqchip_allowed;
}
bool kvm_kernel_irqchip_required(void)
{
return kvm_state->kernel_irqchip_required;
}
bool kvm_kernel_irqchip_split(void)
{
return kvm_state->kernel_irqchip_split;
}
static void kvm_accel_instance_init(Object *obj)
{
KVMState *s = KVM_STATE(obj);
s->kvm_shadow_mem = -1;
}
static void kvm_accel_class_init(ObjectClass *oc, void *data)
{
AccelClass *ac = ACCEL_CLASS(oc);
@ -2947,11 +3055,24 @@ static void kvm_accel_class_init(ObjectClass *oc, void *data)
ac->init_machine = kvm_init;
ac->has_memory = kvm_accel_has_memory;
ac->allowed = &kvm_allowed;
object_class_property_add(oc, "kernel-irqchip", "on|off|split",
NULL, kvm_set_kernel_irqchip,
NULL, NULL, &error_abort);
object_class_property_set_description(oc, "kernel-irqchip",
"Configure KVM in-kernel irqchip", &error_abort);
object_class_property_add(oc, "kvm-shadow-mem", "int",
kvm_get_kvm_shadow_mem, kvm_set_kvm_shadow_mem,
NULL, NULL, &error_abort);
object_class_property_set_description(oc, "kvm-shadow-mem",
"KVM shadow MMU size", &error_abort);
}
static const TypeInfo kvm_accel_type = {
.name = TYPE_KVM_ACCEL,
.parent = TYPE_ACCEL,
.instance_init = kvm_accel_instance_init,
.class_init = kvm_accel_class_init,
.instance_size = sizeof(KVMState),
};

View File

@ -30,8 +30,23 @@
#include "cpu.h"
#include "sysemu/cpus.h"
#include "qemu/main-loop.h"
#include "tcg/tcg.h"
#include "include/qapi/error.h"
#include "include/qemu/error-report.h"
#include "include/hw/boards.h"
#include "qapi/qapi-builtin-visit.h"
unsigned long tcg_tb_size;
typedef struct TCGState {
AccelState parent_obj;
bool mttcg_enabled;
unsigned long tb_size;
} TCGState;
#define TYPE_TCG_ACCEL ACCEL_CLASS_NAME("tcg")
#define TCG_STATE(obj) \
OBJECT_CHECK(TCGState, (obj), TYPE_TCG_ACCEL)
/* mask must never be zero, except for A20 change call */
static void tcg_handle_interrupt(CPUState *cpu, int mask)
@ -58,27 +73,153 @@ static void tcg_handle_interrupt(CPUState *cpu, int mask)
}
}
/*
* We default to false if we know other options have been enabled
* which are currently incompatible with MTTCG. Otherwise when each
* guest (target) has been updated to support:
* - atomic instructions
* - memory ordering primitives (barriers)
* they can set the appropriate CONFIG flags in ${target}-softmmu.mak
*
* Once a guest architecture has been converted to the new primitives
* there are two remaining limitations to check.
*
* - The guest can't be oversized (e.g. 64 bit guest on 32 bit host)
* - The host must have a stronger memory order than the guest
*
* It may be possible in future to support strong guests on weak hosts
* but that will require tagging all load/stores in a guest with their
* implicit memory order requirements which would likely slow things
* down a lot.
*/
static bool check_tcg_memory_orders_compatible(void)
{
#if defined(TCG_GUEST_DEFAULT_MO) && defined(TCG_TARGET_DEFAULT_MO)
return (TCG_GUEST_DEFAULT_MO & ~TCG_TARGET_DEFAULT_MO) == 0;
#else
return false;
#endif
}
static bool default_mttcg_enabled(void)
{
if (use_icount || TCG_OVERSIZED_GUEST) {
return false;
} else {
#ifdef TARGET_SUPPORTS_MTTCG
return check_tcg_memory_orders_compatible();
#else
return false;
#endif
}
}
static void tcg_accel_instance_init(Object *obj)
{
TCGState *s = TCG_STATE(obj);
s->mttcg_enabled = default_mttcg_enabled();
}
static int tcg_init(MachineState *ms)
{
tcg_exec_init(tcg_tb_size * 1024 * 1024);
TCGState *s = TCG_STATE(current_machine->accelerator);
tcg_exec_init(s->tb_size * 1024 * 1024);
cpu_interrupt_handler = tcg_handle_interrupt;
mttcg_enabled = s->mttcg_enabled;
return 0;
}
static char *tcg_get_thread(Object *obj, Error **errp)
{
TCGState *s = TCG_STATE(obj);
return g_strdup(s->mttcg_enabled ? "multi" : "single");
}
static void tcg_set_thread(Object *obj, const char *value, Error **errp)
{
TCGState *s = TCG_STATE(obj);
if (strcmp(value, "multi") == 0) {
if (TCG_OVERSIZED_GUEST) {
error_setg(errp, "No MTTCG when guest word size > hosts");
} else if (use_icount) {
error_setg(errp, "No MTTCG when icount is enabled");
} else {
#ifndef TARGET_SUPPORTS_MTTCG
warn_report("Guest not yet converted to MTTCG - "
"you may get unexpected results");
#endif
if (!check_tcg_memory_orders_compatible()) {
warn_report("Guest expects a stronger memory ordering "
"than the host provides");
error_printf("This may cause strange/hard to debug errors\n");
}
s->mttcg_enabled = true;
}
} else if (strcmp(value, "single") == 0) {
s->mttcg_enabled = false;
} else {
error_setg(errp, "Invalid 'thread' setting %s", value);
}
}
static void tcg_get_tb_size(Object *obj, Visitor *v,
const char *name, void *opaque,
Error **errp)
{
TCGState *s = TCG_STATE(obj);
uint32_t value = s->tb_size;
visit_type_uint32(v, name, &value, errp);
}
static void tcg_set_tb_size(Object *obj, Visitor *v,
const char *name, void *opaque,
Error **errp)
{
TCGState *s = TCG_STATE(obj);
Error *error = NULL;
uint32_t value;
visit_type_uint32(v, name, &value, &error);
if (error) {
error_propagate(errp, error);
return;
}
s->tb_size = value;
}
static void tcg_accel_class_init(ObjectClass *oc, void *data)
{
AccelClass *ac = ACCEL_CLASS(oc);
ac->name = "tcg";
ac->init_machine = tcg_init;
ac->allowed = &tcg_allowed;
}
#define TYPE_TCG_ACCEL ACCEL_CLASS_NAME("tcg")
object_class_property_add_str(oc, "thread",
tcg_get_thread,
tcg_set_thread,
NULL);
object_class_property_add(oc, "tb-size", "int",
tcg_get_tb_size, tcg_set_tb_size,
NULL, NULL, &error_abort);
object_class_property_set_description(oc, "tb-size",
"TCG translation block cache size", &error_abort);
}
static const TypeInfo tcg_accel_type = {
.name = TYPE_TCG_ACCEL,
.parent = TYPE_ACCEL,
.instance_init = tcg_accel_instance_init,
.class_init = tcg_accel_class_init,
.instance_size = sizeof(TCGState),
};
static void register_accel_types(void)

12
configure vendored
View File

@ -101,7 +101,7 @@ update_cxxflags() {
# Set QEMU_CXXFLAGS from QEMU_CFLAGS by filtering out those
# options which some versions of GCC's C++ compiler complain about
# because they only make sense for C programs.
QEMU_CXXFLAGS="$QEMU_CXXFLAGS -D__STDC_LIMIT_MACROS"
QEMU_CXXFLAGS="$QEMU_CXXFLAGS -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS"
for arg in $QEMU_CFLAGS; do
case $arg in
@ -595,6 +595,7 @@ QEMU_CFLAGS="-Wall -Wundef -Wwrite-strings -Wmissing-prototypes $QEMU_CFLAGS"
QEMU_CFLAGS="-Wstrict-prototypes -Wredundant-decls $QEMU_CFLAGS"
QEMU_CFLAGS="-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE $QEMU_CFLAGS"
QEMU_INCLUDES="-iquote . -iquote \$(SRC_PATH) -iquote \$(SRC_PATH)/accel/tcg -iquote \$(SRC_PATH)/include"
QEMU_INCLUDES="$QEMU_INCLUDES -iquote \$(SRC_PATH)/disas/libvixl"
if test "$debug_info" = "yes"; then
CFLAGS="-g $CFLAGS"
LDFLAGS="-g $LDFLAGS"
@ -907,7 +908,7 @@ for binary in "${PYTHON-python3}" python python2
do
if has "$binary"
then
python="$binary"
python=$(command -v "$binary")
break
fi
done
@ -925,7 +926,7 @@ if test "$mingw32" = "yes" ; then
DSOSUF=".dll"
# MinGW needs -mthreads for TLS and macro _MT.
QEMU_CFLAGS="-mthreads $QEMU_CFLAGS"
LIBS="-lwinmm -lws2_32 -liphlpapi $LIBS"
LIBS="-lwinmm -lws2_32 $LIBS"
write_c_skeleton;
if compile_prog "" "-liberty" ; then
LIBS="-liberty $LIBS"
@ -6027,6 +6028,9 @@ case "$slirp" in
mkdir -p slirp
slirp_cflags="-I\$(SRC_PATH)/slirp/src -I\$(BUILD_DIR)/slirp/src"
slirp_libs="-L\$(BUILD_DIR)/slirp -lslirp"
if test "$mingw32" = "yes" ; then
slirp_libs="$slirp_libs -lws2_32 -liphlpapi"
fi
;;
system)
@ -6716,7 +6720,7 @@ if test "$l2tpv3" = "yes" ; then
echo "CONFIG_L2TPV3=y" >> $config_host_mak
fi
if test "$cap_ng" = "yes" ; then
echo "CONFIG_LIBCAP=y" >> $config_host_mak
echo "CONFIG_LIBCAP_NG=y" >> $config_host_mak
fi
echo "CONFIG_AUDIO_DRIVERS=$audio_drv_list" >> $config_host_mak
for drv in $audio_drv_list; do

View File

@ -115,7 +115,7 @@ static int get_cdb_len(uint8_t *cdb)
case 4: return 16;
case 5: return 12;
}
g_warning("Unable to determine cdb len (0x%02hhX)", cdb[0] >> 5);
g_warning("Unable to determine cdb len (0x%02hhX)", (uint8_t)(cdb[0] >> 5));
return -1;
}

72
cpus.c
View File

@ -166,78 +166,6 @@ typedef struct TimersState {
static TimersState timers_state;
bool mttcg_enabled;
/*
* We default to false if we know other options have been enabled
* which are currently incompatible with MTTCG. Otherwise when each
* guest (target) has been updated to support:
* - atomic instructions
* - memory ordering primitives (barriers)
* they can set the appropriate CONFIG flags in ${target}-softmmu.mak
*
* Once a guest architecture has been converted to the new primitives
* there are two remaining limitations to check.
*
* - The guest can't be oversized (e.g. 64 bit guest on 32 bit host)
* - The host must have a stronger memory order than the guest
*
* It may be possible in future to support strong guests on weak hosts
* but that will require tagging all load/stores in a guest with their
* implicit memory order requirements which would likely slow things
* down a lot.
*/
static bool check_tcg_memory_orders_compatible(void)
{
#if defined(TCG_GUEST_DEFAULT_MO) && defined(TCG_TARGET_DEFAULT_MO)
return (TCG_GUEST_DEFAULT_MO & ~TCG_TARGET_DEFAULT_MO) == 0;
#else
return false;
#endif
}
static bool default_mttcg_enabled(void)
{
if (use_icount || TCG_OVERSIZED_GUEST) {
return false;
} else {
#ifdef TARGET_SUPPORTS_MTTCG
return check_tcg_memory_orders_compatible();
#else
return false;
#endif
}
}
void qemu_tcg_configure(QemuOpts *opts, Error **errp)
{
const char *t = qemu_opt_get(opts, "thread");
if (t) {
if (strcmp(t, "multi") == 0) {
if (TCG_OVERSIZED_GUEST) {
error_setg(errp, "No MTTCG when guest word size > hosts");
} else if (use_icount) {
error_setg(errp, "No MTTCG when icount is enabled");
} else {
#ifndef TARGET_SUPPORTS_MTTCG
warn_report("Guest not yet converted to MTTCG - "
"you may get unexpected results");
#endif
if (!check_tcg_memory_orders_compatible()) {
warn_report("Guest expects a stronger memory ordering "
"than the host provides");
error_printf("This may cause strange/hard to debug errors\n");
}
mttcg_enabled = true;
}
} else if (strcmp(t, "single") == 0) {
mttcg_enabled = false;
} else {
error_setg(errp, "Invalid 'thread' setting %s", t);
}
} else {
mttcg_enabled = default_mttcg_enabled();
}
}
/* The current number of executed instructions is based on what we
* originally budgeted minus the current state of the decrementing

View File

@ -19,13 +19,10 @@ crypto-obj-y += tlscredspsk.o
crypto-obj-y += tlscredsx509.o
crypto-obj-y += tlssession.o
crypto-obj-y += secret.o
crypto-rng-obj-$(CONFIG_GCRYPT) += random-gcrypt.o
crypto-rng-obj-$(if $(CONFIG_GCRYPT),n,$(CONFIG_GNUTLS)) += random-gnutls.o
crypto-rng-obj-$(if $(CONFIG_GCRYPT),n,$(if $(CONFIG_GNUTLS),n,y)) += random-platform.o
crypto-obj-y += $(crypto-rng-obj-y)
crypto-obj-y += pbkdf.o
crypto-obj-$(CONFIG_NETTLE) += pbkdf-nettle.o
crypto-obj-$(if $(CONFIG_NETTLE),n,$(CONFIG_GCRYPT)) += pbkdf-gcrypt.o
crypto-obj-$(if $(CONFIG_NETTLE),n,$(if $(CONFIG_GCRYPT),n,y)) += pbkdf-stub.o
crypto-obj-y += ivgen.o
crypto-obj-y += ivgen-essiv.o
crypto-obj-y += ivgen-plain.o
@ -36,7 +33,7 @@ crypto-obj-y += block.o
crypto-obj-y += block-qcow.o
crypto-obj-y += block-luks.o
# Let the userspace emulators avoid linking stuff they won't use.
crypto-user-obj-y = aes.o $(crypto-rng-obj-y) init.o
stub-obj-y += pbkdf-stub.o
util-obj-$(CONFIG_GCRYPT) += random-gcrypt.o
util-obj-$(if $(CONFIG_GCRYPT),n,$(CONFIG_GNUTLS)) += random-gnutls.o
util-obj-$(if $(CONFIG_GCRYPT),n,$(if $(CONFIG_GNUTLS),n,y)) += random-platform.o
util-obj-y += aes.o init.o

View File

@ -1,14 +1,5 @@
libvixl_OBJS = vixl/utils.o \
common-obj-$(CONFIG_ARM_A64_DIS) = vixl/utils.o \
vixl/compiler-intrinsics.o \
vixl/a64/instructions-a64.o \
vixl/a64/decoder-a64.o \
vixl/a64/disasm-a64.o
# The -Wno-sign-compare is needed only for gcc 4.6, which complains about
# some signed-unsigned equality comparisons which later gcc versions do not.
$(addprefix $(obj)/,$(libvixl_OBJS)): QEMU_CXXFLAGS := -I$(SRC_PATH)/disas/libvixl $(QEMU_CXXFLAGS) -Wno-sign-compare
# Ensure that C99 macros are defined regardless of the inclusion order of
# headers in vixl. This is required at least on NetBSD.
$(addprefix $(obj)/,$(libvixl_OBJS)): QEMU_CXXFLAGS += -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS
common-obj-$(CONFIG_ARM_A64_DIS) += $(libvixl_OBJS)

View File

@ -54,7 +54,7 @@ needs_sphinx = '1.3'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = ['qmp_lexer']
extensions = ['kerneldoc', 'qmp_lexer']
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
@ -216,3 +216,8 @@ texinfo_documents = [
# We use paths starting from qemu_docdir here so that you can run
# sphinx-build from anywhere and the kerneldoc extension can still
# find everything.
kerneldoc_bin = os.path.join(qemu_docdir, '../scripts/kernel-doc')
kerneldoc_srctree = os.path.join(qemu_docdir, '..')

8
docs/devel/bitops.rst Normal file
View File

@ -0,0 +1,8 @@
==================
Bitwise operations
==================
The header ``qemu/bitops.h`` provides utility functions for
performing bitwise operations.
.. kernel-doc:: include/qemu/bitops.h

View File

@ -23,3 +23,4 @@ Contents:
secure-coding-practices
tcg
tcg-plugins
bitops

View File

@ -361,3 +361,8 @@ callbacks are called:
- .impl.unaligned specifies that the *implementation* supports unaligned
accesses; if false, unaligned accesses will be emulated by two aligned
accesses.
API Reference
-------------
.. kernel-doc:: include/exec/memory.h

172
docs/sphinx/kerneldoc.py Normal file
View File

@ -0,0 +1,172 @@
# coding=utf-8
#
# Copyright © 2016 Intel Corporation
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#
# Authors:
# Jani Nikula <jani.nikula@intel.com>
#
# Please make sure this works on both python2 and python3.
#
import codecs
import os
import subprocess
import sys
import re
import glob
from docutils import nodes, statemachine
from docutils.statemachine import ViewList
from docutils.parsers.rst import directives, Directive
#
# AutodocReporter is only good up to Sphinx 1.7
#
import sphinx
Use_SSI = sphinx.__version__[:3] >= '1.7'
if Use_SSI:
from sphinx.util.docutils import switch_source_input
else:
from sphinx.ext.autodoc import AutodocReporter
import kernellog
__version__ = '1.0'
class KernelDocDirective(Directive):
"""Extract kernel-doc comments from the specified file"""
required_argument = 1
optional_arguments = 4
option_spec = {
'doc': directives.unchanged_required,
'functions': directives.unchanged,
'export': directives.unchanged,
'internal': directives.unchanged,
}
has_content = False
def run(self):
env = self.state.document.settings.env
cmd = [env.config.kerneldoc_bin, '-rst', '-enable-lineno']
filename = env.config.kerneldoc_srctree + '/' + self.arguments[0]
export_file_patterns = []
# Tell sphinx of the dependency
env.note_dependency(os.path.abspath(filename))
tab_width = self.options.get('tab-width', self.state.document.settings.tab_width)
# FIXME: make this nicer and more robust against errors
if 'export' in self.options:
cmd += ['-export']
export_file_patterns = str(self.options.get('export')).split()
elif 'internal' in self.options:
cmd += ['-internal']
export_file_patterns = str(self.options.get('internal')).split()
elif 'doc' in self.options:
cmd += ['-function', str(self.options.get('doc'))]
elif 'functions' in self.options:
functions = self.options.get('functions').split()
if functions:
for f in functions:
cmd += ['-function', f]
else:
cmd += ['-no-doc-sections']
for pattern in export_file_patterns:
for f in glob.glob(env.config.kerneldoc_srctree + '/' + pattern):
env.note_dependency(os.path.abspath(f))
cmd += ['-export-file', f]
cmd += [filename]
try:
kernellog.verbose(env.app,
'calling kernel-doc \'%s\'' % (" ".join(cmd)))
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()
out, err = codecs.decode(out, 'utf-8'), codecs.decode(err, 'utf-8')
if p.returncode != 0:
sys.stderr.write(err)
kernellog.warn(env.app,
'kernel-doc \'%s\' failed with return code %d' % (" ".join(cmd), p.returncode))
return [nodes.error(None, nodes.paragraph(text = "kernel-doc missing"))]
elif env.config.kerneldoc_verbosity > 0:
sys.stderr.write(err)
lines = statemachine.string2lines(out, tab_width, convert_whitespace=True)
result = ViewList()
lineoffset = 0;
line_regex = re.compile("^#define LINENO ([0-9]+)$")
for line in lines:
match = line_regex.search(line)
if match:
# sphinx counts lines from 0
lineoffset = int(match.group(1)) - 1
# we must eat our comments since the upset the markup
else:
result.append(line, filename, lineoffset)
lineoffset += 1
node = nodes.section()
self.do_parse(result, node)
return node.children
except Exception as e: # pylint: disable=W0703
kernellog.warn(env.app, 'kernel-doc \'%s\' processing failed with: %s' %
(" ".join(cmd), str(e)))
return [nodes.error(None, nodes.paragraph(text = "kernel-doc missing"))]
def do_parse(self, result, node):
if Use_SSI:
with switch_source_input(self.state, result):
self.state.nested_parse(result, 0, node, match_titles=1)
else:
save = self.state.memo.title_styles, self.state.memo.section_level, self.state.memo.reporter
self.state.memo.reporter = AutodocReporter(result, self.state.memo.reporter)
self.state.memo.title_styles, self.state.memo.section_level = [], 0
try:
self.state.nested_parse(result, 0, node, match_titles=1)
finally:
self.state.memo.title_styles, self.state.memo.section_level, self.state.memo.reporter = save
def setup(app):
app.add_config_value('kerneldoc_bin', None, 'env')
app.add_config_value('kerneldoc_srctree', None, 'env')
app.add_config_value('kerneldoc_verbosity', 1, 'env')
app.add_directive('kernel-doc', KernelDocDirective)
return dict(
version = __version__,
parallel_read_safe = True,
parallel_write_safe = True
)

28
docs/sphinx/kernellog.py Normal file
View File

@ -0,0 +1,28 @@
# SPDX-License-Identifier: GPL-2.0
#
# Sphinx has deprecated its older logging interface, but the replacement
# only goes back to 1.6. So here's a wrapper layer to keep around for
# as long as we support 1.4.
#
import sphinx
if sphinx.__version__[:3] >= '1.6':
UseLogging = True
from sphinx.util import logging
logger = logging.getLogger('kerneldoc')
else:
UseLogging = False
def warn(app, message):
if UseLogging:
logger.warning(message)
else:
app.warn(message)
def verbose(app, message):
if UseLogging:
logger.verbose(message)
else:
app.verbose(message)

7
exec.c
View File

@ -3903,10 +3903,9 @@ int ram_block_discard_range(RAMBlock *rb, uint64_t start, size_t length)
if ((start + length) <= rb->used_length) {
bool need_madvise, need_fallocate;
uint8_t *host_endaddr = host_startaddr + length;
if ((uintptr_t)host_endaddr & (rb->page_size - 1)) {
error_report("ram_block_discard_range: Unaligned end address: %p",
host_endaddr);
if (length & (rb->page_size - 1)) {
error_report("ram_block_discard_range: Unaligned length: %zx",
length);
goto err;
}

View File

@ -8,6 +8,7 @@ common-obj-$(CONFIG_ACPI_NVDIMM) += nvdimm.o
common-obj-$(CONFIG_ACPI_VMGENID) += vmgenid.o
common-obj-$(CONFIG_ACPI_HW_REDUCED) += generic_event_device.o
common-obj-$(call lnot,$(CONFIG_ACPI_X86)) += acpi-stub.o
common-obj-$(call lnot,$(CONFIG_PC)) += acpi-x86-stub.o
common-obj-y += acpi_interface.o
common-obj-y += bios-linker-loader.o
@ -20,4 +21,4 @@ common-obj-$(call lnot,$(CONFIG_IPMI)) += ipmi-stub.o
else
common-obj-y += acpi-stub.o
endif
common-obj-$(CONFIG_ALL) += acpi-stub.o ipmi-stub.o
common-obj-$(CONFIG_ALL) += acpi-stub.o acpi-x86-stub.o ipmi-stub.o

View File

@ -7,7 +7,8 @@
#include "hw/pci/pci.h"
#include "hw/pci/pci_host.h"
#include "hw/ide.h"
#include "hw/i386/pc.h"
#include "hw/boards.h"
#include "hw/intc/i8259.h"
PCIBus *typhoon_init(ram_addr_t, ISABus **, qemu_irq *, AlphaCPU *[4],

View File

@ -19,6 +19,7 @@
#include "hw/timer/i8254.h"
#include "hw/isa/superio.h"
#include "hw/dma/i8257.h"
#include "net/net.h"
#include "qemu/cutils.h"
#define MAX_IDE_BUS 2

View File

@ -161,7 +161,6 @@ typedef struct AC97BusMasterRegs {
typedef struct AC97LinkState {
PCIDevice dev;
QEMUSoundCard card;
uint32_t use_broken_id;
uint32_t glob_cnt;
uint32_t glob_sta;
uint32_t cas;
@ -1373,13 +1372,6 @@ static void ac97_realize(PCIDevice *dev, Error **errp)
c[PCI_BASE_ADDRESS_0 + 6] = 0x00;
c[PCI_BASE_ADDRESS_0 + 7] = 0x00;
if (s->use_broken_id) {
c[PCI_SUBSYSTEM_VENDOR_ID] = 0x86;
c[PCI_SUBSYSTEM_VENDOR_ID + 1] = 0x80;
c[PCI_SUBSYSTEM_ID] = 0x00;
c[PCI_SUBSYSTEM_ID + 1] = 0x00;
}
c[PCI_INTERRUPT_LINE] = 0x00; /* intr_ln interrupt line rw */
c[PCI_INTERRUPT_PIN] = 0x01; /* intr_pn interrupt pin ro */
@ -1411,7 +1403,6 @@ static int ac97_init (PCIBus *bus)
static Property ac97_properties[] = {
DEFINE_AUDIO_PROPERTIES(AC97LinkState, card),
DEFINE_PROP_UINT32 ("use_broken_id", AC97LinkState, use_broken_id, 0),
DEFINE_PROP_END_OF_LIST (),
};

View File

@ -178,86 +178,6 @@ GlobalProperty hw_compat_2_1[] = {
};
const size_t hw_compat_2_1_len = G_N_ELEMENTS(hw_compat_2_1);
static char *machine_get_accel(Object *obj, Error **errp)
{
MachineState *ms = MACHINE(obj);
return g_strdup(ms->accel);
}
static void machine_set_accel(Object *obj, const char *value, Error **errp)
{
MachineState *ms = MACHINE(obj);
g_free(ms->accel);
ms->accel = g_strdup(value);
}
static void machine_set_kernel_irqchip(Object *obj, Visitor *v,
const char *name, void *opaque,
Error **errp)
{
Error *err = NULL;
MachineState *ms = MACHINE(obj);
OnOffSplit mode;
visit_type_OnOffSplit(v, name, &mode, &err);
if (err) {
error_propagate(errp, err);
return;
} else {
switch (mode) {
case ON_OFF_SPLIT_ON:
ms->kernel_irqchip_allowed = true;
ms->kernel_irqchip_required = true;
ms->kernel_irqchip_split = false;
break;
case ON_OFF_SPLIT_OFF:
ms->kernel_irqchip_allowed = false;
ms->kernel_irqchip_required = false;
ms->kernel_irqchip_split = false;
break;
case ON_OFF_SPLIT_SPLIT:
ms->kernel_irqchip_allowed = true;
ms->kernel_irqchip_required = true;
ms->kernel_irqchip_split = true;
break;
default:
/* The value was checked in visit_type_OnOffSplit() above. If
* we get here, then something is wrong in QEMU.
*/
abort();
}
}
}
static void machine_get_kvm_shadow_mem(Object *obj, Visitor *v,
const char *name, void *opaque,
Error **errp)
{
MachineState *ms = MACHINE(obj);
int64_t value = ms->kvm_shadow_mem;
visit_type_int(v, name, &value, errp);
}
static void machine_set_kvm_shadow_mem(Object *obj, Visitor *v,
const char *name, void *opaque,
Error **errp)
{
MachineState *ms = MACHINE(obj);
Error *error = NULL;
int64_t value;
visit_type_int(v, name, &value, &error);
if (error) {
error_propagate(errp, error);
return;
}
ms->kvm_shadow_mem = value;
}
static char *machine_get_kernel(Object *obj, Error **errp)
{
MachineState *ms = MACHINE(obj);
@ -432,20 +352,6 @@ static void machine_set_graphics(Object *obj, bool value, Error **errp)
ms->enable_graphics = value;
}
static bool machine_get_igd_gfx_passthru(Object *obj, Error **errp)
{
MachineState *ms = MACHINE(obj);
return ms->igd_gfx_passthru;
}
static void machine_set_igd_gfx_passthru(Object *obj, bool value, Error **errp)
{
MachineState *ms = MACHINE(obj);
ms->igd_gfx_passthru = value;
}
static char *machine_get_firmware(Object *obj, Error **errp)
{
MachineState *ms = MACHINE(obj);
@ -813,23 +719,6 @@ static void machine_class_init(ObjectClass *oc, void *data)
mc->numa_mem_align_shift = 23;
mc->numa_auto_assign_ram = numa_default_auto_assign_ram;
object_class_property_add_str(oc, "accel",
machine_get_accel, machine_set_accel, &error_abort);
object_class_property_set_description(oc, "accel",
"Accelerator list", &error_abort);
object_class_property_add(oc, "kernel-irqchip", "on|off|split",
NULL, machine_set_kernel_irqchip,
NULL, NULL, &error_abort);
object_class_property_set_description(oc, "kernel-irqchip",
"Configure KVM in-kernel irqchip", &error_abort);
object_class_property_add(oc, "kvm-shadow-mem", "int",
machine_get_kvm_shadow_mem, machine_set_kvm_shadow_mem,
NULL, NULL, &error_abort);
object_class_property_set_description(oc, "kvm-shadow-mem",
"KVM shadow MMU size", &error_abort);
object_class_property_add_str(oc, "kernel",
machine_get_kernel, machine_set_kernel, &error_abort);
object_class_property_set_description(oc, "kernel",
@ -887,12 +776,6 @@ static void machine_class_init(ObjectClass *oc, void *data)
object_class_property_set_description(oc, "graphics",
"Set on/off to enable/disable graphics emulation", &error_abort);
object_class_property_add_bool(oc, "igd-passthru",
machine_get_igd_gfx_passthru, machine_set_igd_gfx_passthru,
&error_abort);
object_class_property_set_description(oc, "igd-passthru",
"Set on/off to enable/disable igd passthrou", &error_abort);
object_class_property_add_str(oc, "firmware",
machine_get_firmware, machine_set_firmware,
&error_abort);
@ -935,9 +818,6 @@ static void machine_initfn(Object *obj)
MachineState *ms = MACHINE(obj);
MachineClass *mc = MACHINE_GET_CLASS(obj);
ms->kernel_irqchip_allowed = true;
ms->kernel_irqchip_split = mc->default_kernel_irqchip_split;
ms->kvm_shadow_mem = -1;
ms->dump_guest_core = true;
ms->mem_merge = true;
ms->enable_graphics = true;
@ -976,7 +856,6 @@ static void machine_finalize(Object *obj)
{
MachineState *ms = MACHINE(obj);
g_free(ms->accel);
g_free(ms->kernel_filename);
g_free(ms->initrd_filename);
g_free(ms->kernel_cmdline);
@ -994,26 +873,6 @@ bool machine_usb(MachineState *machine)
return machine->usb;
}
bool machine_kernel_irqchip_allowed(MachineState *machine)
{
return machine->kernel_irqchip_allowed;
}
bool machine_kernel_irqchip_required(MachineState *machine)
{
return machine->kernel_irqchip_required;
}
bool machine_kernel_irqchip_split(MachineState *machine)
{
return machine->kernel_irqchip_split;
}
int machine_kvm_shadow_mem(MachineState *machine)
{
return machine->kvm_shadow_mem;
}
int machine_phandle_start(MachineState *machine)
{
return machine->phandle_start;

View File

@ -106,6 +106,9 @@ int isa_vga_mm_init(hwaddr vram_base,
s->vga.con = graphic_console_init(NULL, 0, s->vga.hw_ops, s);
vga_init_vbe(&s->vga, NULL, address_space);
memory_region_add_subregion(address_space,
VBE_DISPI_LFB_PHYSICAL_ADDRESS,
&s->vga.vram);
return 0;
}

View File

@ -76,7 +76,9 @@ static void vga_isa_realizefn(DeviceState *dev, Error **errp)
memory_region_set_coalescing(vga_io_memory);
s->con = graphic_console_init(DEVICE(dev), 0, s->hw_ops, s);
vga_init_vbe(s, OBJECT(dev), isa_address_space(isadev));
memory_region_add_subregion(isa_address_space(isadev),
VBE_DISPI_LFB_PHYSICAL_ADDRESS,
&s->vram);
/* ROM BIOS */
rom_add_vga(VGABIOS_FILENAME);
}

View File

@ -264,11 +264,6 @@ static void pci_std_vga_realize(PCIDevice *dev, Error **errp)
pci_register_bar(&d->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio);
}
if (!dev->rom_bar) {
/* compatibility with pc-0.13 and older */
vga_init_vbe(s, OBJECT(dev), pci_address_space(dev));
}
}
static void pci_std_vga_init(Object *obj)

View File

@ -2301,17 +2301,3 @@ void vga_init(VGACommonState *s, Object *obj, MemoryRegion *address_space,
portio_list_add(&s->vbe_port_list, address_space_io, 0x1ce);
}
}
void vga_init_vbe(VGACommonState *s, Object *obj, MemoryRegion *system_memory)
{
/* With pc-0.12 and below we map both the PCI BAR and the fixed VBE region,
* so use an alias to avoid double-mapping the same region.
*/
memory_region_init_alias(&s->vram_vbe, obj, "vram.vbe",
&s->vram, 0, memory_region_size(&s->vram));
/* XXX: use optimized standard vga accesses */
memory_region_add_subregion(system_memory,
VBE_DISPI_LFB_PHYSICAL_ADDRESS,
&s->vram_vbe);
s->vbe_mapped = 1;
}

View File

@ -60,7 +60,6 @@ typedef struct VGACommonState {
MemoryRegion *legacy_address_space;
uint8_t *vram_ptr;
MemoryRegion vram;
MemoryRegion vram_vbe;
uint32_t vram_size;
uint32_t vram_size_mb; /* property */
uint32_t vbe_size;
@ -106,7 +105,6 @@ typedef struct VGACommonState {
uint32_t vbe_start_addr;
uint32_t vbe_line_offset;
uint32_t vbe_bank_mask;
int vbe_mapped;
/* display refresh support */
QemuConsole *con;
uint32_t font_offsets[2];
@ -178,7 +176,6 @@ void vga_invalidate_scanlines(VGACommonState *s, int y1, int y2);
int vga_ioport_invalid(VGACommonState *s, uint32_t addr);
void vga_init_vbe(VGACommonState *s, Object *obj, MemoryRegion *address_space);
uint32_t vbe_ioport_read_data(void *opaque, uint32_t addr);
void vbe_ioport_write_index(void *opaque, uint32_t addr, uint32_t val);
void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val);

View File

@ -1312,11 +1312,6 @@ static void pci_vmsvga_realize(PCIDevice *dev, Error **errp)
&s->chip.vga.vram);
pci_register_bar(dev, 2, PCI_BASE_ADDRESS_MEM_PREFETCH,
&s->chip.fifo_ram);
if (!dev->rom_bar) {
/* compatibility with pc-0.13 and older */
vga_init_vbe(&s->chip.vga, OBJECT(dev), pci_address_space(dev));
}
}
static Property vga_vmware_properties[] = {

View File

@ -6,7 +6,8 @@
#include "hw/pci/pci.h"
#include "hw/pci/pci_host.h"
#include "hw/ide.h"
#include "hw/i386/pc.h"
#include "hw/boards.h"
#include "hw/intc/i8259.h"
#include "hppa_hardware.h"

View File

@ -19,6 +19,7 @@
#include "hppa_sys.h"
#include "qemu/units.h"
#include "qapi/error.h"
#include "net/net.h"
#include "qemu/log.h"
#define MAX_IDE_BUS 2

View File

@ -546,14 +546,14 @@ uint16_t hyperv_hcall_post_message(uint64_t param, bool fast)
}
ret = HV_STATUS_INVALID_CONNECTION_ID;
rcu_read_lock();
QLIST_FOREACH_RCU(mh, &msg_handlers, link) {
if (mh->conn_id == (msg->connection_id & HV_CONNECTION_ID_MASK)) {
ret = mh->handler(msg, mh->data);
break;
WITH_RCU_READ_LOCK_GUARD() {
QLIST_FOREACH_RCU(mh, &msg_handlers, link) {
if (mh->conn_id == (msg->connection_id & HV_CONNECTION_ID_MASK)) {
ret = mh->handler(msg, mh->data);
break;
}
}
}
rcu_read_unlock();
unmap:
cpu_physical_memory_unmap(msg, len, 0, 0);
@ -619,7 +619,6 @@ int hyperv_set_event_flag_handler(uint32_t conn_id, EventNotifier *notifier)
uint16_t hyperv_hcall_signal_event(uint64_t param, bool fast)
{
uint16_t ret;
EventFlagHandler *handler;
if (unlikely(!fast)) {
@ -645,15 +644,12 @@ uint16_t hyperv_hcall_signal_event(uint64_t param, bool fast)
return HV_STATUS_INVALID_HYPERCALL_INPUT;
}
ret = HV_STATUS_INVALID_CONNECTION_ID;
rcu_read_lock();
RCU_READ_LOCK_GUARD();
QLIST_FOREACH_RCU(handler, &event_flag_handlers, link) {
if (handler->conn_id == param) {
event_notifier_set(handler->notifier);
ret = 0;
break;
return 0;
}
}
rcu_read_unlock();
return ret;
return HV_STATUS_INVALID_CONNECTION_ID;
}

View File

@ -103,11 +103,17 @@ config MICROVM
select MC146818RTC
select VIRTIO_MMIO
config X86_IOMMU
bool
depends on PC
config VTD
bool
select X86_IOMMU
config AMD_IOMMU
bool
select X86_IOMMU
config VMPORT
bool

View File

@ -1,17 +1,19 @@
obj-$(CONFIG_KVM) += kvm/
obj-y += e820_memory_layout.o multiboot.o
obj-y += x86.o
obj-y += pc.o
obj-$(CONFIG_PC) += pc.o pc_sysfw.o
obj-$(CONFIG_I440FX) += pc_piix.o
obj-$(CONFIG_Q35) += pc_q35.o
obj-$(CONFIG_MICROVM) += microvm.o
obj-y += fw_cfg.o pc_sysfw.o
obj-y += x86-iommu.o
obj-y += fw_cfg.o
obj-$(CONFIG_X86_IOMMU) += x86-iommu.o
obj-$(call lnot,$(CONFIG_X86_IOMMU)) += x86-iommu-stub.o
obj-$(CONFIG_VTD) += intel_iommu.o
obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o
obj-$(CONFIG_XEN) += ../xenpv/ xen/
obj-$(CONFIG_VMPORT) += vmport.o
obj-$(CONFIG_VMMOUSE) += vmmouse.o
obj-$(CONFIG_PC) += port92.o
obj-y += kvmvapic.o
obj-y += acpi-build.o
obj-$(CONFIG_PC) += acpi-build.o

View File

@ -53,6 +53,7 @@
/* Supported chipsets: */
#include "hw/southbridge/piix.h"
#include "hw/acpi/pcihp.h"
#include "hw/i386/fw_cfg.h"
#include "hw/i386/ich9.h"
#include "hw/pci/pci_bus.h"
#include "hw/pci-host/q35.h"

View File

@ -16,12 +16,14 @@
#include "sysemu/numa.h"
#include "hw/acpi/acpi.h"
#include "hw/firmware/smbios.h"
#include "hw/i386/pc.h"
#include "hw/i386/fw_cfg.h"
#include "hw/timer/hpet.h"
#include "hw/nvram/fw_cfg.h"
#include "e820_memory_layout.h"
#include "kvm_i386.h"
#include "config-devices.h"
struct hpet_fw_config hpet_cfg = {.count = UINT8_MAX};
const char *fw_cfg_arch_key_name(uint16_t key)
{
@ -46,6 +48,7 @@ const char *fw_cfg_arch_key_name(uint16_t key)
void fw_cfg_build_smbios(MachineState *ms, FWCfgState *fw_cfg)
{
#ifdef CONFIG_SMBIOS
uint8_t *smbios_tables, *smbios_anchor;
size_t smbios_tables_len, smbios_anchor_len;
struct smbios_phys_mem_area *mem_array;
@ -83,6 +86,7 @@ void fw_cfg_build_smbios(MachineState *ms, FWCfgState *fw_cfg)
fw_cfg_add_file(fw_cfg, "etc/smbios/smbios-anchor",
smbios_anchor, smbios_anchor_len);
}
#endif
}
FWCfgState *fw_cfg_arch_create(MachineState *ms,
@ -114,8 +118,10 @@ FWCfgState *fw_cfg_arch_create(MachineState *ms,
*/
fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, apic_id_limit);
fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
#ifdef CONFIG_ACPI
fw_cfg_add_bytes(fw_cfg, FW_CFG_ACPI_TABLES,
acpi_tables, acpi_tables_len);
#endif
fw_cfg_add_i32(fw_cfg, FW_CFG_IRQ0_OVERRIDE, kvm_allows_irq0_override());
fw_cfg_add_bytes(fw_cfg, FW_CFG_E820_TABLE,

View File

@ -12,6 +12,8 @@
#include "hw/boards.h"
#include "hw/nvram/fw_cfg.h"
#define FW_CFG_IO_BASE 0x510
#define FW_CFG_ACPI_TABLES (FW_CFG_ARCH_LOCAL + 0)
#define FW_CFG_SMBIOS_ENTRIES (FW_CFG_ARCH_LOCAL + 1)
#define FW_CFG_IRQ0_OVERRIDE (FW_CFG_ARCH_LOCAL + 2)

View File

@ -1 +1,5 @@
obj-y += clock.o apic.o i8259.o ioapic.o i8254.o
obj-y += clock.o
obj-$(CONFIG_APIC) += apic.o
obj-$(CONFIG_IOAPIC) += ioapic.o
obj-$(CONFIG_I8254) += i8254.o
obj-$(CONFIG_I8259) += i8259.o

View File

@ -12,6 +12,7 @@
#include "qemu/osdep.h"
#include "hw/isa/i8259_internal.h"
#include "hw/intc/i8259.h"
#include "qemu/module.h"
#include "hw/i386/apic_internal.h"
#include "hw/irq.h"

View File

@ -12,7 +12,7 @@
#include "qemu/osdep.h"
#include "monitor/monitor.h"
#include "hw/i386/pc.h"
#include "hw/i386/x86.h"
#include "hw/irq.h"
#include "hw/qdev-properties.h"
#include "hw/i386/ioapic_internal.h"
@ -48,18 +48,6 @@ void kvm_pc_setup_irq_routing(bool pci_enabled)
}
}
void kvm_pc_gsi_handler(void *opaque, int n, int level)
{
GSIState *s = opaque;
if (n < ISA_NUM_IRQS) {
/* Kernel will forward to both PIC and IOAPIC */
qemu_set_irq(s->i8259_irq[n], level);
} else {
qemu_set_irq(s->ioapic_irq[n], level);
}
}
typedef struct KVMIOAPICState KVMIOAPICState;
struct KVMIOAPICState {

View File

@ -32,8 +32,8 @@
#include "hw/kvm/clock.h"
#include "hw/i386/microvm.h"
#include "hw/i386/x86.h"
#include "hw/i386/pc.h"
#include "target/i386/cpu.h"
#include "hw/intc/i8259.h"
#include "hw/timer/i8254.h"
#include "hw/rtc/mc146818rtc.h"
#include "hw/char/serial.h"
@ -132,7 +132,7 @@ static void microvm_devices_init(MicrovmMachineState *mms)
if (mms->pic == ON_OFF_AUTO_ON || mms->pic == ON_OFF_AUTO_AUTO) {
qemu_irq *i8259;
i8259 = i8259_init(isa_bus, pc_allocate_cpu_irq());
i8259 = i8259_init(isa_bus, x86_allocate_cpu_irq());
for (i = 0; i < ISA_NUM_IRQS; i++) {
gsi_state->i8259_irq[i] = i8259[i];
}

View File

@ -44,6 +44,7 @@
#include "migration/vmstate.h"
#include "multiboot.h"
#include "hw/rtc/mc146818rtc.h"
#include "hw/intc/i8259.h"
#include "hw/dma/i8257.h"
#include "hw/timer/i8254.h"
#include "hw/input/i8042.h"
@ -90,18 +91,7 @@
#include "config-devices.h"
#include "e820_memory_layout.h"
#include "fw_cfg.h"
/* debug PC/ISA interrupts */
//#define DEBUG_IRQ
#ifdef DEBUG_IRQ
#define DPRINTF(fmt, ...) \
do { printf("CPUIRQ: " fmt , ## __VA_ARGS__); } while (0)
#else
#define DPRINTF(fmt, ...)
#endif
struct hpet_fw_config hpet_cfg = {.count = UINT8_MAX};
#include "trace.h"
GlobalProperty pc_compat_4_2[] = {};
const size_t pc_compat_4_2_len = G_N_ELEMENTS(pc_compat_4_2);
@ -347,17 +337,6 @@ GlobalProperty pc_compat_1_4[] = {
};
const size_t pc_compat_1_4_len = G_N_ELEMENTS(pc_compat_1_4);
void gsi_handler(void *opaque, int n, int level)
{
GSIState *s = opaque;
DPRINTF("pc: %s GSI %d\n", level ? "raising" : "lowering", n);
if (n < ISA_NUM_IRQS) {
qemu_set_irq(s->i8259_irq[n], level);
}
qemu_set_irq(s->ioapic_irq[n], level);
}
GSIState *pc_gsi_create(qemu_irq **irqs, bool pci_enabled)
{
GSIState *s;
@ -365,10 +344,8 @@ GSIState *pc_gsi_create(qemu_irq **irqs, bool pci_enabled)
s = g_new0(GSIState, 1);
if (kvm_ioapic_in_kernel()) {
kvm_pc_setup_irq_routing(pci_enabled);
*irqs = qemu_allocate_irqs(kvm_pc_gsi_handler, s, GSI_NUM_PINS);
} else {
*irqs = qemu_allocate_irqs(gsi_handler, s, GSI_NUM_PINS);
}
*irqs = qemu_allocate_irqs(gsi_handler, s, GSI_NUM_PINS);
return s;
}
@ -397,55 +374,6 @@ static uint64_t ioportF0_read(void *opaque, hwaddr addr, unsigned size)
return 0xffffffffffffffffULL;
}
/* TSC handling */
uint64_t cpu_get_tsc(CPUX86State *env)
{
return cpu_get_ticks();
}
/* IRQ handling */
int cpu_get_pic_interrupt(CPUX86State *env)
{
X86CPU *cpu = env_archcpu(env);
int intno;
if (!kvm_irqchip_in_kernel()) {
intno = apic_get_interrupt(cpu->apic_state);
if (intno >= 0) {
return intno;
}
/* read the irq from the PIC */
if (!apic_accept_pic_intr(cpu->apic_state)) {
return -1;
}
}
intno = pic_read_irq(isa_pic);
return intno;
}
static void pic_irq_request(void *opaque, int irq, int level)
{
CPUState *cs = first_cpu;
X86CPU *cpu = X86_CPU(cs);
DPRINTF("pic_irqs: %s irq %d\n", level? "raise" : "lower", irq);
if (cpu->apic_state && !kvm_irqchip_in_kernel()) {
CPU_FOREACH(cs) {
cpu = X86_CPU(cs);
if (apic_accept_pic_intr(cpu->apic_state)) {
apic_deliver_pic_intr(cpu->apic_state, level);
}
}
} else {
if (level) {
cpu_interrupt(cs, CPU_INTERRUPT_HARD);
} else {
cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
}
}
}
/* PC cmos mappings */
#define REG_EQUIPMENT_BYTE 0x14
@ -745,124 +673,6 @@ void pc_cmos_init(PCMachineState *pcms,
qemu_register_reset(pc_cmos_init_late, &arg);
}
#define TYPE_PORT92 "port92"
#define PORT92(obj) OBJECT_CHECK(Port92State, (obj), TYPE_PORT92)
/* port 92 stuff: could be split off */
typedef struct Port92State {
ISADevice parent_obj;
MemoryRegion io;
uint8_t outport;
qemu_irq a20_out;
} Port92State;
static void port92_write(void *opaque, hwaddr addr, uint64_t val,
unsigned size)
{
Port92State *s = opaque;
int oldval = s->outport;
DPRINTF("port92: write 0x%02" PRIx64 "\n", val);
s->outport = val;
qemu_set_irq(s->a20_out, (val >> 1) & 1);
if ((val & 1) && !(oldval & 1)) {
qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
}
}
static uint64_t port92_read(void *opaque, hwaddr addr,
unsigned size)
{
Port92State *s = opaque;
uint32_t ret;
ret = s->outport;
DPRINTF("port92: read 0x%02x\n", ret);
return ret;
}
static void port92_init(ISADevice *dev, qemu_irq a20_out)
{
qdev_connect_gpio_out_named(DEVICE(dev), PORT92_A20_LINE, 0, a20_out);
}
static const VMStateDescription vmstate_port92_isa = {
.name = "port92",
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
VMSTATE_UINT8(outport, Port92State),
VMSTATE_END_OF_LIST()
}
};
static void port92_reset(DeviceState *d)
{
Port92State *s = PORT92(d);
s->outport &= ~1;
}
static const MemoryRegionOps port92_ops = {
.read = port92_read,
.write = port92_write,
.impl = {
.min_access_size = 1,
.max_access_size = 1,
},
.endianness = DEVICE_LITTLE_ENDIAN,
};
static void port92_initfn(Object *obj)
{
Port92State *s = PORT92(obj);
memory_region_init_io(&s->io, OBJECT(s), &port92_ops, s, "port92", 1);
s->outport = 0;
qdev_init_gpio_out_named(DEVICE(obj), &s->a20_out, PORT92_A20_LINE, 1);
}
static void port92_realizefn(DeviceState *dev, Error **errp)
{
ISADevice *isadev = ISA_DEVICE(dev);
Port92State *s = PORT92(dev);
isa_register_ioport(isadev, &s->io, 0x92);
}
static void port92_class_initfn(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = port92_realizefn;
dc->reset = port92_reset;
dc->vmsd = &vmstate_port92_isa;
/*
* Reason: unlike ordinary ISA devices, this one needs additional
* wiring: its A20 output line needs to be wired up by
* port92_init().
*/
dc->user_creatable = false;
}
static const TypeInfo port92_info = {
.name = TYPE_PORT92,
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(Port92State),
.instance_init = port92_initfn,
.class_init = port92_class_initfn,
};
static void port92_register_types(void)
{
type_register_static(&port92_info);
}
type_init(port92_register_types)
static void handle_a20_line_change(void *opaque, int irq, int level)
{
X86CPU *cpu = opaque;
@ -889,16 +699,6 @@ void pc_init_ne2k_isa(ISABus *bus, NICInfo *nd)
nb_ne2k++;
}
DeviceState *cpu_get_current_apic(void)
{
if (current_cpu) {
X86CPU *cpu = X86_CPU(current_cpu);
return cpu->apic_state;
} else {
return NULL;
}
}
void pc_acpi_smi_interrupt(void *opaque, int irq, int level)
{
X86CPU *cpu = opaque;
@ -1294,11 +1094,6 @@ uint64_t pc_pci_hole64_start(void)
return ROUND_UP(hole64_start, 1 * GiB);
}
qemu_irq pc_allocate_cpu_irq(void)
{
return qemu_allocate_irq(pic_irq_request, NULL, 0);
}
DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus)
{
DeviceState *dev = NULL;
@ -1365,11 +1160,12 @@ static void pc_superio_init(ISABus *isa_bus, bool create_fdctrl, bool no_vmport)
qdev_prop_set_ptr(dev, "ps2_mouse", i8042);
qdev_init_nofail(dev);
}
port92 = isa_create_simple(isa_bus, "port92");
port92 = isa_create_simple(isa_bus, TYPE_PORT92);
a20_line = qemu_allocate_irqs(handle_a20_line_change, first_cpu, 2);
i8042_setup_a20_line(i8042, a20_line[0]);
port92_init(port92, a20_line[1]);
qdev_connect_gpio_out_named(DEVICE(port92),
PORT92_A20_LINE, 0, a20_line[1]);
g_free(a20_line);
}
@ -1475,7 +1271,7 @@ void pc_i8259_create(ISABus *isa_bus, qemu_irq *i8259_irqs)
} else if (xen_enabled()) {
i8259 = xen_interrupt_controller_init();
} else {
i8259 = i8259_init(isa_bus, pc_allocate_cpu_irq());
i8259 = i8259_init(isa_bus, x86_allocate_cpu_irq());
}
for (size_t i = 0; i < ISA_NUM_IRQS; i++) {
@ -1485,30 +1281,6 @@ void pc_i8259_create(ISABus *isa_bus, qemu_irq *i8259_irqs)
g_free(i8259);
}
void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name)
{
DeviceState *dev;
SysBusDevice *d;
unsigned int i;
if (kvm_ioapic_in_kernel()) {
dev = qdev_create(NULL, TYPE_KVM_IOAPIC);
} else {
dev = qdev_create(NULL, TYPE_IOAPIC);
}
if (parent_name) {
object_property_add_child(object_resolve_path(parent_name, NULL),
"ioapic", OBJECT(dev), NULL);
}
qdev_init_nofail(dev);
d = SYS_BUS_DEVICE(dev);
sysbus_mmio_map(d, 0, IO_APIC_DEFAULT_ADDRESS);
for (i = 0; i < IOAPIC_NUM_PINS; i++) {
gsi_state->ioapic_irq[i] = qdev_get_gpio_in(dev, i);
}
}
static void pc_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
Error **errp)
{
@ -2032,48 +1804,6 @@ static void pc_machine_set_vmport(Object *obj, Visitor *v, const char *name,
visit_type_OnOffAuto(v, name, &pcms->vmport, errp);
}
bool pc_machine_is_smm_enabled(PCMachineState *pcms)
{
bool smm_available = false;
if (pcms->smm == ON_OFF_AUTO_OFF) {
return false;
}
if (tcg_enabled() || qtest_enabled()) {
smm_available = true;
} else if (kvm_enabled()) {
smm_available = kvm_has_smm();
}
if (smm_available) {
return true;
}
if (pcms->smm == ON_OFF_AUTO_ON) {
error_report("System Management Mode not supported by this hypervisor.");
exit(1);
}
return false;
}
static void pc_machine_get_smm(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
PCMachineState *pcms = PC_MACHINE(obj);
OnOffAuto smm = pcms->smm;
visit_type_OnOffAuto(v, name, &smm, errp);
}
static void pc_machine_set_smm(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
PCMachineState *pcms = PC_MACHINE(obj);
visit_type_OnOffAuto(v, name, &pcms->smm, errp);
}
static bool pc_machine_get_smbus(Object *obj, Error **errp)
{
PCMachineState *pcms = PC_MACHINE(obj);
@ -2120,7 +1850,6 @@ static void pc_machine_initfn(Object *obj)
{
PCMachineState *pcms = PC_MACHINE(obj);
pcms->smm = ON_OFF_AUTO_AUTO;
#ifdef CONFIG_VMPORT
pcms->vmport = ON_OFF_AUTO_AUTO;
#else
@ -2227,12 +1956,6 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
pc_machine_get_device_memory_region_size, NULL,
NULL, NULL, &error_abort);
object_class_property_add(oc, PC_MACHINE_SMM, "OnOffAuto",
pc_machine_get_smm, pc_machine_set_smm,
NULL, NULL, &error_abort);
object_class_property_set_description(oc, PC_MACHINE_SMM,
"Enable SMM (pc & q35)", &error_abort);
object_class_property_add(oc, PC_MACHINE_VMPORT, "OnOffAuto",
pc_machine_get_vmport, pc_machine_set_vmport,
NULL, NULL, &error_abort);

View File

@ -281,7 +281,7 @@ else {
/* TODO: Populate SPD eeprom data. */
pcms->smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,
x86ms->gsi[9], smi_irq,
pc_machine_is_smm_enabled(pcms),
x86_machine_is_smm_enabled(x86ms),
&piix4_pm);
smbus_eeprom_init(pcms->smbus, 8, NULL, 0);
@ -309,9 +309,9 @@ else {
static void pc_compat_2_3_fn(MachineState *machine)
{
PCMachineState *pcms = PC_MACHINE(machine);
X86MachineState *x86ms = X86_MACHINE(machine);
if (kvm_enabled()) {
pcms->smm = ON_OFF_AUTO_OFF;
x86ms->smm = ON_OFF_AUTO_OFF;
}
}
@ -357,19 +357,13 @@ static void pc_compat_1_3(MachineState *machine)
pc_compat_1_4_fn(machine);
}
/* PC compat function for pc-0.14 to pc-1.2 */
/* PC compat function for pc-1.0 to pc-1.2 */
static void pc_compat_1_2(MachineState *machine)
{
pc_compat_1_3(machine);
x86_cpu_change_kvm_default("kvm-pv-eoi", NULL);
}
/* PC compat function for pc-0.12 and pc-0.13 */
static void pc_compat_0_13(MachineState *machine)
{
pc_compat_1_2(machine);
}
static void pc_init_isa(MachineState *machine)
{
pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, TYPE_I440FX_PCI_DEVICE);
@ -745,6 +739,7 @@ static void pc_i440fx_1_3_machine_options(MachineClass *m)
pc_i440fx_1_4_machine_options(m);
m->hw_version = "1.3.0";
m->deprecation_reason = "use a newer machine type instead";
x86mc->compat_apic_id_mode = true;
compat_props_add(m->compat_props, compat, G_N_ELEMENTS(compat));
}
@ -813,82 +808,6 @@ DEFINE_I440FX_MACHINE(v1_0, "pc-1.0", pc_compat_1_2,
pc_i440fx_1_0_machine_options);
static void pc_i440fx_0_15_machine_options(MachineClass *m)
{
static GlobalProperty compat[] = {
PC_CPU_MODEL_IDS("0.15")
};
pc_i440fx_1_0_machine_options(m);
m->hw_version = "0.15";
m->deprecation_reason = "use a newer machine type instead";
compat_props_add(m->compat_props, compat, G_N_ELEMENTS(compat));
}
DEFINE_I440FX_MACHINE(v0_15, "pc-0.15", pc_compat_1_2,
pc_i440fx_0_15_machine_options);
static void pc_i440fx_0_14_machine_options(MachineClass *m)
{
static GlobalProperty compat[] = {
PC_CPU_MODEL_IDS("0.14")
{ "virtio-blk-pci", "event_idx", "off" },
{ "virtio-serial-pci", "event_idx", "off" },
{ "virtio-net-pci", "event_idx", "off" },
{ "virtio-balloon-pci", "event_idx", "off" },
{ "qxl", "revision", "2" },
{ "qxl-vga", "revision", "2" },
};
pc_i440fx_0_15_machine_options(m);
m->hw_version = "0.14";
compat_props_add(m->compat_props, compat, G_N_ELEMENTS(compat));
}
DEFINE_I440FX_MACHINE(v0_14, "pc-0.14", pc_compat_1_2,
pc_i440fx_0_14_machine_options);
static void pc_i440fx_0_13_machine_options(MachineClass *m)
{
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
static GlobalProperty compat[] = {
PC_CPU_MODEL_IDS("0.13")
{ TYPE_PCI_DEVICE, "command_serr_enable", "off" },
{ "AC97", "use_broken_id", "1" },
{ "virtio-9p-pci", "vectors", "0" },
{ "VGA", "rombar", "0" },
{ "vmware-svga", "rombar", "0" },
};
pc_i440fx_0_14_machine_options(m);
m->hw_version = "0.13";
compat_props_add(m->compat_props, compat, G_N_ELEMENTS(compat));
pcmc->kvmclock_enabled = false;
}
DEFINE_I440FX_MACHINE(v0_13, "pc-0.13", pc_compat_0_13,
pc_i440fx_0_13_machine_options);
static void pc_i440fx_0_12_machine_options(MachineClass *m)
{
static GlobalProperty compat[] = {
PC_CPU_MODEL_IDS("0.12")
{ "virtio-serial-pci", "max_ports", "1" },
{ "virtio-serial-pci", "vectors", "0" },
{ "usb-mouse", "serial", "1" },
{ "usb-tablet", "serial", "1" },
{ "usb-kbd", "serial", "1" },
};
pc_i440fx_0_13_machine_options(m);
m->hw_version = "0.12";
compat_props_add(m->compat_props, compat, G_N_ELEMENTS(compat));
}
DEFINE_I440FX_MACHINE(v0_12, "pc-0.12", pc_compat_0_13,
pc_i440fx_0_12_machine_options);
typedef struct {
uint16_t gpu_device_id;
uint16_t pch_device_id;

View File

@ -276,7 +276,7 @@ static void pc_q35_init(MachineState *machine)
0xff0104);
/* connect pm stuff to lpc */
ich9_lpc_pm_init(lpc, pc_machine_is_smm_enabled(pcms));
ich9_lpc_pm_init(lpc, x86_machine_is_smm_enabled(x86ms));
if (pcms->sata_enabled) {
/* ahci and SATA device, for q35 1 ahci controller is built-in */

126
hw/i386/port92.c Normal file
View File

@ -0,0 +1,126 @@
/*
* QEMU I/O port 0x92 (System Control Port A, to handle Fast Gate A20)
*
* Copyright (c) 2003-2004 Fabrice Bellard
*
* SPDX-License-Identifier: MIT
*/
#include "qemu/osdep.h"
#include "sysemu/runstate.h"
#include "migration/vmstate.h"
#include "hw/irq.h"
#include "hw/i386/pc.h"
#include "trace.h"
#define PORT92(obj) OBJECT_CHECK(Port92State, (obj), TYPE_PORT92)
typedef struct Port92State {
ISADevice parent_obj;
MemoryRegion io;
uint8_t outport;
qemu_irq a20_out;
} Port92State;
static void port92_write(void *opaque, hwaddr addr, uint64_t val,
unsigned size)
{
Port92State *s = opaque;
int oldval = s->outport;
trace_port92_write(val);
s->outport = val;
qemu_set_irq(s->a20_out, (val >> 1) & 1);
if ((val & 1) && !(oldval & 1)) {
qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
}
}
static uint64_t port92_read(void *opaque, hwaddr addr,
unsigned size)
{
Port92State *s = opaque;
uint32_t ret;
ret = s->outport;
trace_port92_read(ret);
return ret;
}
static const VMStateDescription vmstate_port92_isa = {
.name = "port92",
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
VMSTATE_UINT8(outport, Port92State),
VMSTATE_END_OF_LIST()
}
};
static void port92_reset(DeviceState *d)
{
Port92State *s = PORT92(d);
s->outport &= ~1;
}
static const MemoryRegionOps port92_ops = {
.read = port92_read,
.write = port92_write,
.impl = {
.min_access_size = 1,
.max_access_size = 1,
},
.endianness = DEVICE_LITTLE_ENDIAN,
};
static void port92_initfn(Object *obj)
{
Port92State *s = PORT92(obj);
memory_region_init_io(&s->io, OBJECT(s), &port92_ops, s, "port92", 1);
s->outport = 0;
qdev_init_gpio_out_named(DEVICE(obj), &s->a20_out, PORT92_A20_LINE, 1);
}
static void port92_realizefn(DeviceState *dev, Error **errp)
{
ISADevice *isadev = ISA_DEVICE(dev);
Port92State *s = PORT92(dev);
isa_register_ioport(isadev, &s->io, 0x92);
}
static void port92_class_initfn(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = port92_realizefn;
dc->reset = port92_reset;
dc->vmsd = &vmstate_port92_isa;
/*
* Reason: unlike ordinary ISA devices, this one needs additional
* wiring: its A20 output line needs to be wired up with
* qdev_connect_gpio_out_named().
*/
dc->user_creatable = false;
}
static const TypeInfo port92_info = {
.name = TYPE_PORT92,
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(Port92State),
.instance_init = port92_initfn,
.class_init = port92_class_initfn,
};
static void port92_register_types(void)
{
type_register_static(&port92_info);
}
type_init(port92_register_types)

View File

@ -111,3 +111,11 @@ amdvi_ir_irte_ga_val(uint64_t hi, uint64_t lo) "hi 0x%"PRIx64" lo 0x%"PRIx64
# vmport.c
vmport_register(unsigned char command, void *func, void *opaque) "command: 0x%02x func: %p opaque: %p"
vmport_command(unsigned char command) "command: 0x%02x"
# x86.c
x86_gsi_interrupt(int irqn, int level) "GSI interrupt #%d level:%d"
x86_pic_interrupt(int irqn, int level) "PIC interrupt #%d level:%d"
# port92.c
port92_read(uint8_t val) "port92: read 0x%02x"
port92_write(uint8_t val) "port92: write 0x%02x"

34
hw/i386/x86-iommu-stub.c Normal file
View File

@ -0,0 +1,34 @@
/*
* Stubs for X86 IOMMU emulation
*
* Copyright (C) 2019 Red Hat, Inc.
*
* Author: Paolo Bonzini <pbonzini@redhat.com>
*
* 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/>.
*/
#include "qemu/osdep.h"
#include "hw/i386/x86-iommu.h"
void x86_iommu_iec_register_notifier(X86IOMMUState *iommu,
iec_notify_fn fn, void *data)
{
}
X86IOMMUState *x86_iommu_get_default(void)
{
return NULL;
}

View File

@ -34,18 +34,23 @@
#include "sysemu/numa.h"
#include "sysemu/replay.h"
#include "sysemu/sysemu.h"
#include "trace.h"
#include "hw/i386/x86.h"
#include "target/i386/cpu.h"
#include "hw/i386/topology.h"
#include "hw/i386/fw_cfg.h"
#include "hw/intc/i8259.h"
#include "hw/acpi/cpu_hotplug.h"
#include "hw/irq.h"
#include "hw/nmi.h"
#include "hw/loader.h"
#include "multiboot.h"
#include "elf.h"
#include "standard-headers/asm-x86/bootparam.h"
#include "config-devices.h"
#include "kvm_i386.h"
#define BIOS_FILENAME "bios.bin"
@ -220,6 +225,105 @@ static long get_file_size(FILE *f)
return size;
}
/* TSC handling */
uint64_t cpu_get_tsc(CPUX86State *env)
{
return cpu_get_ticks();
}
/* IRQ handling */
static void pic_irq_request(void *opaque, int irq, int level)
{
CPUState *cs = first_cpu;
X86CPU *cpu = X86_CPU(cs);
trace_x86_pic_interrupt(irq, level);
if (cpu->apic_state && !kvm_irqchip_in_kernel()) {
CPU_FOREACH(cs) {
cpu = X86_CPU(cs);
if (apic_accept_pic_intr(cpu->apic_state)) {
apic_deliver_pic_intr(cpu->apic_state, level);
}
}
} else {
if (level) {
cpu_interrupt(cs, CPU_INTERRUPT_HARD);
} else {
cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
}
}
}
qemu_irq x86_allocate_cpu_irq(void)
{
return qemu_allocate_irq(pic_irq_request, NULL, 0);
}
int cpu_get_pic_interrupt(CPUX86State *env)
{
X86CPU *cpu = env_archcpu(env);
int intno;
if (!kvm_irqchip_in_kernel()) {
intno = apic_get_interrupt(cpu->apic_state);
if (intno >= 0) {
return intno;
}
/* read the irq from the PIC */
if (!apic_accept_pic_intr(cpu->apic_state)) {
return -1;
}
}
intno = pic_read_irq(isa_pic);
return intno;
}
DeviceState *cpu_get_current_apic(void)
{
if (current_cpu) {
X86CPU *cpu = X86_CPU(current_cpu);
return cpu->apic_state;
} else {
return NULL;
}
}
void gsi_handler(void *opaque, int n, int level)
{
GSIState *s = opaque;
trace_x86_gsi_interrupt(n, level);
if (n < ISA_NUM_IRQS) {
/* Under KVM, Kernel will forward to both PIC and IOAPIC */
qemu_set_irq(s->i8259_irq[n], level);
}
qemu_set_irq(s->ioapic_irq[n], level);
}
void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name)
{
DeviceState *dev;
SysBusDevice *d;
unsigned int i;
assert(parent_name);
if (kvm_ioapic_in_kernel()) {
dev = qdev_create(NULL, TYPE_KVM_IOAPIC);
} else {
dev = qdev_create(NULL, TYPE_IOAPIC);
}
object_property_add_child(object_resolve_path(parent_name, NULL),
"ioapic", OBJECT(dev), NULL);
qdev_init_nofail(dev);
d = SYS_BUS_DEVICE(dev);
sysbus_mmio_map(d, 0, IO_APIC_DEFAULT_ADDRESS);
for (i = 0; i < IOAPIC_NUM_PINS; i++) {
gsi_state->ioapic_irq[i] = qdev_get_gpio_in(dev, i);
}
}
struct setup_data {
uint64_t next;
uint32_t type;
@ -745,10 +849,53 @@ static void x86_machine_set_max_ram_below_4g(Object *obj, Visitor *v,
x86ms->max_ram_below_4g = value;
}
bool x86_machine_is_smm_enabled(X86MachineState *x86ms)
{
bool smm_available = false;
if (x86ms->smm == ON_OFF_AUTO_OFF) {
return false;
}
if (tcg_enabled() || qtest_enabled()) {
smm_available = true;
} else if (kvm_enabled()) {
smm_available = kvm_has_smm();
}
if (smm_available) {
return true;
}
if (x86ms->smm == ON_OFF_AUTO_ON) {
error_report("System Management Mode not supported by this hypervisor.");
exit(1);
}
return false;
}
static void x86_machine_get_smm(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
X86MachineState *x86ms = X86_MACHINE(obj);
OnOffAuto smm = x86ms->smm;
visit_type_OnOffAuto(v, name, &smm, errp);
}
static void x86_machine_set_smm(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
X86MachineState *x86ms = X86_MACHINE(obj);
visit_type_OnOffAuto(v, name, &x86ms->smm, errp);
}
static void x86_machine_initfn(Object *obj)
{
X86MachineState *x86ms = X86_MACHINE(obj);
x86ms->smm = ON_OFF_AUTO_AUTO;
x86ms->max_ram_below_4g = 0; /* use default */
x86ms->smp_dies = 1;
}
@ -769,9 +916,14 @@ static void x86_machine_class_init(ObjectClass *oc, void *data)
object_class_property_add(oc, X86_MACHINE_MAX_RAM_BELOW_4G, "size",
x86_machine_get_max_ram_below_4g, x86_machine_set_max_ram_below_4g,
NULL, NULL, &error_abort);
object_class_property_set_description(oc, X86_MACHINE_MAX_RAM_BELOW_4G,
"Maximum ram below the 4G boundary (32bit boundary)", &error_abort);
object_class_property_add(oc, X86_MACHINE_SMM, "OnOffAuto",
x86_machine_get_smm, x86_machine_set_smm,
NULL, NULL, &error_abort);
object_class_property_set_description(oc, X86_MACHINE_SMM,
"Enable SMM", &error_abort);
}
static const TypeInfo x86_machine_info = {

View File

@ -26,7 +26,6 @@
#include "qemu/log.h"
#include "hw/isa/isa.h"
#include "migration/vmstate.h"
#include "hw/i386/pc.h"
#include "hw/input/ps2.h"
#include "hw/irq.h"
#include "hw/input/i8042.h"

View File

@ -9,6 +9,7 @@ config PL190
config IOAPIC
bool
select I8259
config ARM_GIC
bool
@ -21,6 +22,7 @@ config OPENPIC
config APIC
bool
select MSI_NONBROKEN
select I8259
config ARM_GIC_KVM
bool

View File

@ -22,10 +22,10 @@
#include "hw/i386/apic_internal.h"
#include "hw/i386/apic.h"
#include "hw/i386/ioapic.h"
#include "hw/intc/i8259.h"
#include "hw/pci/msi.h"
#include "qemu/host-utils.h"
#include "trace.h"
#include "hw/i386/pc.h"
#include "hw/i386/apic-msidef.h"
#include "qapi/error.h"

View File

@ -23,7 +23,7 @@
*/
#include "qemu/osdep.h"
#include "hw/i386/pc.h"
#include "hw/intc/i8259.h"
#include "hw/irq.h"
#include "hw/isa/isa.h"
#include "qemu/timer.h"

View File

@ -24,7 +24,7 @@
*/
#include "qemu/osdep.h"
#include "hw/i386/pc.h"
#include "hw/intc/i8259.h"
#include "hw/isa/i8259_internal.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"

View File

@ -23,10 +23,11 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "monitor/monitor.h"
#include "hw/i386/pc.h"
#include "hw/i386/apic.h"
#include "hw/i386/ioapic.h"
#include "hw/i386/ioapic_internal.h"
#include "hw/i386/x86.h"
#include "hw/intc/i8259.h"
#include "hw/pci/msi.h"
#include "hw/qdev-properties.h"
#include "sysemu/kvm.h"

View File

@ -19,8 +19,8 @@
#include "qemu/osdep.h"
#include "hw/pci/pci.h"
#include "hw/i386/pc.h"
#include "hw/irq.h"
#include "hw/intc/i8259.h"
#include "hw/timer/i8254.h"
#include "migration/vmstate.h"
#include "hw/audio/pcspk.h"

View File

@ -82,24 +82,27 @@ void isa_bus_irqs(ISABus *bus, qemu_irq *irqs)
* This function is only for special cases such as the 'ferr', and
* temporary use for normal devices until they are converted to qdev.
*/
qemu_irq isa_get_irq(ISADevice *dev, int isairq)
qemu_irq isa_get_irq(ISADevice *dev, unsigned isairq)
{
assert(!dev || ISA_BUS(qdev_get_parent_bus(DEVICE(dev))) == isabus);
if (isairq < 0 || isairq > 15) {
if (isairq >= ISA_NUM_IRQS) {
hw_error("isa irq %d invalid", isairq);
}
return isabus->irqs[isairq];
}
void isa_init_irq(ISADevice *dev, qemu_irq *p, int isairq)
void isa_init_irq(ISADevice *dev, qemu_irq *p, unsigned isairq)
{
assert(dev->nirqs < ARRAY_SIZE(dev->isairq));
if (isairq >= ISA_NUM_IRQS) {
hw_error("isa irq %d invalid", isairq);
}
dev->isairq[dev->nirqs] = isairq;
*p = isa_get_irq(dev, isairq);
dev->nirqs++;
}
void isa_connect_gpio_out(ISADevice *isadev, int gpioirq, int isairq)
void isa_connect_gpio_out(ISADevice *isadev, int gpioirq, unsigned isairq)
{
qemu_irq irq;
isa_init_irq(isadev, &irq, isairq);

View File

@ -35,7 +35,6 @@
#include "hw/isa/isa.h"
#include "hw/sysbus.h"
#include "migration/vmstate.h"
#include "hw/i386/pc.h"
#include "hw/irq.h"
#include "hw/isa/apm.h"
#include "hw/i386/ioapic.h"

View File

@ -26,11 +26,11 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "hw/irq.h"
#include "hw/i386/pc.h"
#include "hw/southbridge/piix.h"
#include "hw/pci/pci.h"
#include "hw/isa/isa.h"
#include "hw/sysbus.h"
#include "hw/intc/i8259.h"
#include "hw/dma/i8257.h"
#include "hw/timer/i8254.h"
#include "hw/rtc/mc146818rtc.h"

View File

@ -30,7 +30,7 @@
#include "hw/pci/pci_host.h"
#include "hw/southbridge/piix.h"
#include "migration/vmstate.h"
#include "hw/i386/pc.h"
#include "hw/intc/i8259.h"
#include "hw/irq.h"
#include "exec/address-spaces.h"
#include "trace.h"

View File

@ -23,7 +23,7 @@
#include "qemu/units.h"
#include "qapi/error.h"
#include "cpu.h"
#include "hw/i386/pc.h"
#include "hw/intc/i8259.h"
#include "hw/dma/i8257.h"
#include "hw/isa/superio.h"
#include "net/net.h"

View File

@ -26,7 +26,7 @@
#include "qemu-common.h"
#include "hw/mips/mips.h"
#include "hw/mips/cpudevs.h"
#include "hw/i386/pc.h"
#include "hw/intc/i8259.h"
#include "hw/dma/i8257.h"
#include "hw/char/serial.h"
#include "hw/char/parallel.h"

View File

@ -15,7 +15,7 @@
#include "cpu.h"
#include "hw/mips/mips.h"
#include "hw/mips/cpudevs.h"
#include "hw/i386/pc.h"
#include "hw/intc/i8259.h"
#include "hw/char/serial.h"
#include "hw/isa/isa.h"
#include "net/net.h"

View File

@ -1,6 +1,11 @@
config PAM
bool
config XEN_IGD_PASSTHROUGH
bool
default y
depends on XEN && PCI_I440FX
config PREP_PCI
bool
select PCI

View File

@ -14,6 +14,7 @@ common-obj-$(CONFIG_VERSATILE_PCI) += versatile.o
common-obj-$(CONFIG_PCI_SABRE) += sabre.o
common-obj-$(CONFIG_FULONG) += bonito.o
common-obj-$(CONFIG_PCI_I440FX) += i440fx.o
common-obj-$(CONFIG_XEN_IGD_PASSTHROUGH) += xen_igd_pt.o
common-obj-$(CONFIG_PCI_EXPRESS_Q35) += q35.o
common-obj-$(CONFIG_PCI_EXPRESS_GENERIC_BRIDGE) += gpex.o
common-obj-$(CONFIG_PCI_EXPRESS_XILINX) += xilinx-pcie.o

View File

@ -41,7 +41,6 @@
#include "qemu/osdep.h"
#include "qemu/error-report.h"
#include "hw/pci/pci.h"
#include "hw/i386/pc.h"
#include "hw/irq.h"
#include "hw/mips/mips.h"
#include "hw/pci/pci_host.h"

View File

@ -1,5 +1,5 @@
/*
* QEMU i440FX/PIIX3 PCI Bridge Emulation
* QEMU i440FX PCI Bridge Emulation
*
* Copyright (c) 2006 Fabrice Bellard
*
@ -31,7 +31,6 @@
#include "hw/sysbus.h"
#include "qapi/error.h"
#include "migration/vmstate.h"
#include "hw/pci-host/pam.h"
#include "qapi/visitor.h"
#include "qemu/error-report.h"
@ -51,23 +50,6 @@ typedef struct I440FXState {
uint32_t short_root_bus;
} I440FXState;
#define I440FX_PCI_DEVICE(obj) \
OBJECT_CHECK(PCII440FXState, (obj), TYPE_I440FX_PCI_DEVICE)
struct PCII440FXState {
/*< private >*/
PCIDevice parent_obj;
/*< public >*/
MemoryRegion *system_memory;
MemoryRegion *pci_address_space;
MemoryRegion *ram_memory;
PAMMemoryRegion pam_regions[13];
MemoryRegion smram_region;
MemoryRegion smram, low_smram;
};
#define I440FX_PAM 0x59
#define I440FX_PAM_SIZE 7
#define I440FX_SMRAM 0x72
@ -386,90 +368,6 @@ static const TypeInfo i440fx_info = {
},
};
/* IGD Passthrough Host Bridge. */
typedef struct {
uint8_t offset;
uint8_t len;
} IGDHostInfo;
/* Here we just expose minimal host bridge offset subset. */
static const IGDHostInfo igd_host_bridge_infos[] = {
{0x08, 2}, /* revision id */
{0x2c, 2}, /* sybsystem vendor id */
{0x2e, 2}, /* sybsystem id */
{0x50, 2}, /* SNB: processor graphics control register */
{0x52, 2}, /* processor graphics control register */
{0xa4, 4}, /* SNB: graphics base of stolen memory */
{0xa8, 4}, /* SNB: base of GTT stolen memory */
};
static void host_pci_config_read(int pos, int len, uint32_t *val, Error **errp)
{
int rc, config_fd;
/* Access real host bridge. */
char *path = g_strdup_printf("/sys/bus/pci/devices/%04x:%02x:%02x.%d/%s",
0, 0, 0, 0, "config");
config_fd = open(path, O_RDWR);
if (config_fd < 0) {
error_setg_errno(errp, errno, "Failed to open: %s", path);
goto out;
}
if (lseek(config_fd, pos, SEEK_SET) != pos) {
error_setg_errno(errp, errno, "Failed to seek: %s", path);
goto out_close_fd;
}
do {
rc = read(config_fd, (uint8_t *)val, len);
} while (rc < 0 && (errno == EINTR || errno == EAGAIN));
if (rc != len) {
error_setg_errno(errp, errno, "Failed to read: %s", path);
}
out_close_fd:
close(config_fd);
out:
g_free(path);
}
static void igd_pt_i440fx_realize(PCIDevice *pci_dev, Error **errp)
{
uint32_t val = 0;
int i, num;
int pos, len;
Error *local_err = NULL;
num = ARRAY_SIZE(igd_host_bridge_infos);
for (i = 0; i < num; i++) {
pos = igd_host_bridge_infos[i].offset;
len = igd_host_bridge_infos[i].len;
host_pci_config_read(pos, len, &val, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
}
pci_default_write_config(pci_dev, pos, val, len);
}
}
static void igd_passthrough_i440fx_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
k->realize = igd_pt_i440fx_realize;
dc->desc = "IGD Passthrough Host bridge";
}
static const TypeInfo igd_passthrough_i440fx_info = {
.name = TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE,
.parent = TYPE_I440FX_PCI_DEVICE,
.instance_size = sizeof(PCII440FXState),
.class_init = igd_passthrough_i440fx_class_init,
};
static const char *i440fx_pcihost_root_bus_path(PCIHostState *host_bridge,
PCIBus *rootbus)
{
@ -514,7 +412,6 @@ static const TypeInfo i440fx_pcihost_info = {
static void i440fx_register_types(void)
{
type_register_static(&i440fx_info);
type_register_static(&igd_passthrough_i440fx_info);
type_register_static(&i440fx_pcihost_info);
}

View File

@ -32,7 +32,7 @@
#include "hw/pci/pci_host.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
#include "hw/i386/pc.h"
#include "hw/intc/i8259.h"
#include "hw/irq.h"
#include "hw/loader.h"
#include "hw/or-irq.h"

120
hw/pci-host/xen_igd_pt.c Normal file
View File

@ -0,0 +1,120 @@
/*
* QEMU Intel IGD Passthrough Host Bridge Emulation
*
* Copyright (c) 2006 Fabrice Bellard
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "hw/pci/pci.h"
#include "hw/pci/pci_host.h"
#include "hw/pci-host/i440fx.h"
#include "qapi/error.h"
typedef struct {
uint8_t offset;
uint8_t len;
} IGDHostInfo;
/* Here we just expose minimal host bridge offset subset. */
static const IGDHostInfo igd_host_bridge_infos[] = {
{PCI_REVISION_ID, 2},
{PCI_SUBSYSTEM_VENDOR_ID, 2},
{PCI_SUBSYSTEM_ID, 2},
{0x50, 2}, /* SNB: processor graphics control register */
{0x52, 2}, /* processor graphics control register */
{0xa4, 4}, /* SNB: graphics base of stolen memory */
{0xa8, 4}, /* SNB: base of GTT stolen memory */
};
static void host_pci_config_read(int pos, int len, uint32_t *val, Error **errp)
{
int rc, config_fd;
/* Access real host bridge. */
char *path = g_strdup_printf("/sys/bus/pci/devices/%04x:%02x:%02x.%d/%s",
0, 0, 0, 0, "config");
config_fd = open(path, O_RDWR);
if (config_fd < 0) {
error_setg_errno(errp, errno, "Failed to open: %s", path);
goto out;
}
if (lseek(config_fd, pos, SEEK_SET) != pos) {
error_setg_errno(errp, errno, "Failed to seek: %s", path);
goto out_close_fd;
}
do {
rc = read(config_fd, (uint8_t *)val, len);
} while (rc < 0 && (errno == EINTR || errno == EAGAIN));
if (rc != len) {
error_setg_errno(errp, errno, "Failed to read: %s", path);
}
out_close_fd:
close(config_fd);
out:
g_free(path);
}
static void igd_pt_i440fx_realize(PCIDevice *pci_dev, Error **errp)
{
uint32_t val = 0;
size_t i;
int pos, len;
Error *local_err = NULL;
for (i = 0; i < ARRAY_SIZE(igd_host_bridge_infos); i++) {
pos = igd_host_bridge_infos[i].offset;
len = igd_host_bridge_infos[i].len;
host_pci_config_read(pos, len, &val, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
}
pci_default_write_config(pci_dev, pos, val, len);
}
}
static void igd_passthrough_i440fx_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
k->realize = igd_pt_i440fx_realize;
dc->desc = "IGD Passthrough Host bridge";
}
static const TypeInfo igd_passthrough_i440fx_info = {
.name = TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE,
.parent = TYPE_I440FX_PCI_DEVICE,
.instance_size = sizeof(PCII440FXState),
.class_init = igd_passthrough_i440fx_class_init,
};
static void igd_pt_i440fx_register_types(void)
{
type_register_static(&igd_passthrough_i440fx_info);
}
type_init(igd_pt_i440fx_register_types)

View File

@ -26,6 +26,7 @@
#include "qapi/qmp/qerror.h"
#include "hw/pci/pci.h"
#include "hw/pci/msi.h"
#include "hw/pci/msix.h"
bool msi_nonbroken;
bool pci_available;
@ -64,3 +65,29 @@ void msi_notify(PCIDevice *dev, unsigned int vector)
{
g_assert_not_reached();
}
/* Required by target/i386/kvm.c */
bool msi_is_masked(const PCIDevice *dev, unsigned vector)
{
g_assert_not_reached();
}
MSIMessage msi_get_message(PCIDevice *dev, unsigned int vector)
{
g_assert_not_reached();
}
int msix_enabled(PCIDevice *dev)
{
return false;
}
bool msix_is_masked(PCIDevice *dev, unsigned vector)
{
g_assert_not_reached();
}
MSIMessage msix_get_message(PCIDevice *dev, unsigned int vector)
{
g_assert_not_reached();
}

View File

@ -69,8 +69,6 @@ static Property pci_props[] = {
DEFINE_PROP_UINT32("rombar", PCIDevice, rom_bar, 1),
DEFINE_PROP_BIT("multifunction", PCIDevice, cap_present,
QEMU_PCI_CAP_MULTIFUNCTION_BITNR, false),
DEFINE_PROP_BIT("command_serr_enable", PCIDevice, cap_present,
QEMU_PCI_CAP_SERR_BITNR, true),
DEFINE_PROP_BIT("x-pcie-lnksta-dllla", PCIDevice, cap_present,
QEMU_PCIE_LNKSTA_DLLLA_BITNR, true),
DEFINE_PROP_BIT("x-pcie-extcap-init", PCIDevice, cap_present,
@ -751,9 +749,7 @@ static void pci_init_wmask(PCIDevice *dev)
pci_set_word(dev->wmask + PCI_COMMAND,
PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
PCI_COMMAND_INTX_DISABLE);
if (dev->cap_present & QEMU_PCI_CAP_SERR) {
pci_word_test_and_set_mask(dev->wmask + PCI_COMMAND, PCI_COMMAND_SERR);
}
pci_word_test_and_set_mask(dev->wmask + PCI_COMMAND, PCI_COMMAND_SERR);
memset(dev->wmask + PCI_CONFIG_HEADER_SIZE, 0xff,
config_size - PCI_CONFIG_HEADER_SIZE);

View File

@ -793,7 +793,6 @@ static DeviceState *ppce500_init_mpic(PPCE500MachineState *pms,
MemoryRegion *ccsr,
IrqLines *irqs)
{
MachineState *machine = MACHINE(pms);
const PPCE500MachineClass *pmc = PPCE500_MACHINE_GET_CLASS(pms);
DeviceState *dev = NULL;
SysBusDevice *s;
@ -801,10 +800,10 @@ static DeviceState *ppce500_init_mpic(PPCE500MachineState *pms,
if (kvm_enabled()) {
Error *err = NULL;
if (machine_kernel_irqchip_allowed(machine)) {
if (kvm_kernel_irqchip_allowed()) {
dev = ppce500_init_mpic_kvm(pmc, irqs, &err);
}
if (machine_kernel_irqchip_required(machine) && !dev) {
if (kvm_kernel_irqchip_required() && !dev) {
error_reportf_err(err,
"kernel_irqchip requested but unavailable: ");
exit(1);

View File

@ -75,12 +75,11 @@ int spapr_irq_init_kvm(SpaprInterruptControllerInitKvm fn,
uint32_t nr_servers,
Error **errp)
{
MachineState *machine = MACHINE(qdev_get_machine());
Error *local_err = NULL;
if (kvm_enabled() && machine_kernel_irqchip_allowed(machine)) {
if (kvm_enabled() && kvm_kernel_irqchip_allowed()) {
if (fn(intc, nr_servers, &local_err) < 0) {
if (machine_kernel_irqchip_required(machine)) {
if (kvm_kernel_irqchip_required()) {
error_prepend(&local_err,
"kernel_irqchip requested but unavailable: ");
error_propagate(errp, local_err);
@ -185,7 +184,7 @@ static int spapr_irq_check(SpaprMachineState *spapr, Error **errp)
*/
if (kvm_enabled() &&
spapr->irq == &spapr_irq_dual &&
machine_kernel_irqchip_required(machine) &&
kvm_kernel_irqchip_required() &&
xics_kvm_has_broken_disconnect(spapr)) {
error_setg(errp, "KVM is too old to support ic-mode=dual,kernel-irqchip=on");
return -1;
@ -288,20 +287,13 @@ uint32_t spapr_irq_nr_msis(SpaprMachineState *spapr)
void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
{
MachineState *machine = MACHINE(spapr);
SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
if (machine_kernel_irqchip_split(machine)) {
if (kvm_enabled() && kvm_kernel_irqchip_split()) {
error_setg(errp, "kernel_irqchip split mode not supported on pseries");
return;
}
if (!kvm_enabled() && machine_kernel_irqchip_required(machine)) {
error_setg(errp,
"kernel_irqchip requested but only available with KVM");
return;
}
if (spapr_irq_check(spapr, errp) < 0) {
return;
}

View File

@ -1,3 +1,6 @@
config VHOST
bool
config VIRTIO
bool

View File

@ -2,8 +2,8 @@ ifeq ($(CONFIG_VIRTIO),y)
common-obj-y += virtio-bus.o
obj-y += virtio.o
obj-$(call lor,$(CONFIG_VHOST_USER),$(CONFIG_VHOST_KERNEL)) += vhost.o vhost-backend.o
common-obj-$(call lnot,$(call lor,$(CONFIG_VHOST_USER),$(CONFIG_VHOST_KERNEL))) += vhost-stub.o
obj-$(CONFIG_VHOST) += vhost.o vhost-backend.o
common-obj-$(call lnot,$(CONFIG_VHOST)) += vhost-stub.o
obj-$(CONFIG_VHOST_USER) += vhost-user.o
common-obj-$(CONFIG_VIRTIO_RNG) += virtio-rng.o

View File

@ -11,7 +11,9 @@
#include "qemu/osdep.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "qapi/error.h"
#include "hw/xen/xen-legacy-backend.h"
#include "hw/xen/xen_pt.h"
#include "chardev/char.h"
#include "sysemu/accel.h"
#include "sysemu/runstate.h"
@ -124,6 +126,16 @@ static void xen_change_state_handler(void *opaque, int running,
}
}
static bool xen_get_igd_gfx_passthru(Object *obj, Error **errp)
{
return has_igd_gfx_passthru;
}
static void xen_set_igd_gfx_passthru(Object *obj, bool value, Error **errp)
{
has_igd_gfx_passthru = value;
}
static void xen_setup_post(MachineState *ms, AccelState *accel)
{
int rc;
@ -177,6 +189,12 @@ static void xen_accel_class_init(ObjectClass *oc, void *data)
ac->compat_props = g_ptr_array_new();
compat_props_add(ac->compat_props, compat, G_N_ELEMENTS(compat));
object_class_property_add_bool(oc, "igd-passthru",
xen_get_igd_gfx_passthru, xen_set_igd_gfx_passthru,
&error_abort);
object_class_property_set_description(oc, "igd-passthru",
"Set on/off to enable/disable igd passthrou", &error_abort);
}
#define TYPE_XEN_ACCEL ACCEL_CLASS_NAME("xen")

View File

@ -65,6 +65,8 @@
#include "qemu/range.h"
#include "exec/address-spaces.h"
bool has_igd_gfx_passthru;
#define XEN_PT_NR_IRQS (256)
static uint8_t xen_pt_mapped_machine_irq[XEN_PT_NR_IRQS] = {0};

View File

@ -360,10 +360,14 @@ typedef struct IOMMUMemoryRegionClass {
typedef struct CoalescedMemoryRange CoalescedMemoryRange;
typedef struct MemoryRegionIoeventfd MemoryRegionIoeventfd;
/** MemoryRegion:
*
* A struct representing a memory region.
*/
struct MemoryRegion {
Object parent_obj;
/* All fields are private - violators will be prosecuted */
/* private: */
/* The following fields should fit in a cache line */
bool romd_mode;
@ -419,30 +423,232 @@ struct IOMMUMemoryRegion {
* Use with memory_listener_register() and memory_listener_unregister().
*/
struct MemoryListener {
/**
* @begin:
*
* Called at the beginning of an address space update transaction.
* Followed by calls to #MemoryListener.region_add(),
* #MemoryListener.region_del(), #MemoryListener.region_nop(),
* #MemoryListener.log_start() and #MemoryListener.log_stop() in
* increasing address order.
*
* @listener: The #MemoryListener.
*/
void (*begin)(MemoryListener *listener);
/**
* @commit:
*
* Called at the end of an address space update transaction,
* after the last call to #MemoryListener.region_add(),
* #MemoryListener.region_del() or #MemoryListener.region_nop(),
* #MemoryListener.log_start() and #MemoryListener.log_stop().
*
* @listener: The #MemoryListener.
*/
void (*commit)(MemoryListener *listener);
/**
* @region_add:
*
* Called during an address space update transaction,
* for a section of the address space that is new in this address space
* space since the last transaction.
*
* @listener: The #MemoryListener.
* @section: The new #MemoryRegionSection.
*/
void (*region_add)(MemoryListener *listener, MemoryRegionSection *section);
/**
* @region_del:
*
* Called during an address space update transaction,
* for a section of the address space that has disappeared in the address
* space since the last transaction.
*
* @listener: The #MemoryListener.
* @section: The old #MemoryRegionSection.
*/
void (*region_del)(MemoryListener *listener, MemoryRegionSection *section);
/**
* @region_nop:
*
* Called during an address space update transaction,
* for a section of the address space that is in the same place in the address
* space as in the last transaction.
*
* @listener: The #MemoryListener.
* @section: The #MemoryRegionSection.
*/
void (*region_nop)(MemoryListener *listener, MemoryRegionSection *section);
/**
* @log_start:
*
* Called during an address space update transaction, after
* one of #MemoryListener.region_add(),#MemoryListener.region_del() or
* #MemoryListener.region_nop(), if dirty memory logging clients have
* become active since the last transaction.
*
* @listener: The #MemoryListener.
* @section: The #MemoryRegionSection.
* @old: A bitmap of dirty memory logging clients that were active in
* the previous transaction.
* @new: A bitmap of dirty memory logging clients that are active in
* the current transaction.
*/
void (*log_start)(MemoryListener *listener, MemoryRegionSection *section,
int old, int new);
/**
* @log_stop:
*
* Called during an address space update transaction, after
* one of #MemoryListener.region_add(), #MemoryListener.region_del() or
* #MemoryListener.region_nop() and possibly after
* #MemoryListener.log_start(), if dirty memory logging clients have
* become inactive since the last transaction.
*
* @listener: The #MemoryListener.
* @section: The #MemoryRegionSection.
* @old: A bitmap of dirty memory logging clients that were active in
* the previous transaction.
* @new: A bitmap of dirty memory logging clients that are active in
* the current transaction.
*/
void (*log_stop)(MemoryListener *listener, MemoryRegionSection *section,
int old, int new);
/**
* @log_sync:
*
* Called by memory_region_snapshot_and_clear_dirty() and
* memory_global_dirty_log_sync(), before accessing QEMU's "official"
* copy of the dirty memory bitmap for a #MemoryRegionSection.
*
* @listener: The #MemoryListener.
* @section: The #MemoryRegionSection.
*/
void (*log_sync)(MemoryListener *listener, MemoryRegionSection *section);
/**
* @log_clear:
*
* Called before reading the dirty memory bitmap for a
* #MemoryRegionSection.
*
* @listener: The #MemoryListener.
* @section: The #MemoryRegionSection.
*/
void (*log_clear)(MemoryListener *listener, MemoryRegionSection *section);
/**
* @log_global_start:
*
* Called by memory_global_dirty_log_start(), which
* enables the %DIRTY_LOG_MIGRATION client on all memory regions in
* the address space. #MemoryListener.log_global_start() is also
* called when a #MemoryListener is added, if global dirty logging is
* active at that time.
*
* @listener: The #MemoryListener.
*/
void (*log_global_start)(MemoryListener *listener);
/**
* @log_global_stop:
*
* Called by memory_global_dirty_log_stop(), which
* disables the %DIRTY_LOG_MIGRATION client on all memory regions in
* the address space.
*
* @listener: The #MemoryListener.
*/
void (*log_global_stop)(MemoryListener *listener);
/**
* @log_global_after_sync:
*
* Called after reading the dirty memory bitmap
* for any #MemoryRegionSection.
*
* @listener: The #MemoryListener.
*/
void (*log_global_after_sync)(MemoryListener *listener);
/**
* @eventfd_add:
*
* Called during an address space update transaction,
* for a section of the address space that has had a new ioeventfd
* registration since the last transaction.
*
* @listener: The #MemoryListener.
* @section: The new #MemoryRegionSection.
* @match_data: The @match_data parameter for the new ioeventfd.
* @data: The @data parameter for the new ioeventfd.
* @e: The #EventNotifier parameter for the new ioeventfd.
*/
void (*eventfd_add)(MemoryListener *listener, MemoryRegionSection *section,
bool match_data, uint64_t data, EventNotifier *e);
/**
* @eventfd_del:
*
* Called during an address space update transaction,
* for a section of the address space that has dropped an ioeventfd
* registration since the last transaction.
*
* @listener: The #MemoryListener.
* @section: The new #MemoryRegionSection.
* @match_data: The @match_data parameter for the dropped ioeventfd.
* @data: The @data parameter for the dropped ioeventfd.
* @e: The #EventNotifier parameter for the dropped ioeventfd.
*/
void (*eventfd_del)(MemoryListener *listener, MemoryRegionSection *section,
bool match_data, uint64_t data, EventNotifier *e);
/**
* @coalesced_io_add:
*
* Called during an address space update transaction,
* for a section of the address space that has had a new coalesced
* MMIO range registration since the last transaction.
*
* @listener: The #MemoryListener.
* @section: The new #MemoryRegionSection.
* @addr: The starting address for the coalesced MMIO range.
* @len: The length of the coalesced MMIO range.
*/
void (*coalesced_io_add)(MemoryListener *listener, MemoryRegionSection *section,
hwaddr addr, hwaddr len);
/**
* @coalesced_io_del:
*
* Called during an address space update transaction,
* for a section of the address space that has dropped a coalesced
* MMIO range since the last transaction.
*
* @listener: The #MemoryListener.
* @section: The new #MemoryRegionSection.
* @addr: The starting address for the coalesced MMIO range.
* @len: The length of the coalesced MMIO range.
*/
void (*coalesced_io_del)(MemoryListener *listener, MemoryRegionSection *section,
hwaddr addr, hwaddr len);
/* Lower = earlier (during add), later (during del) */
/**
* @priority:
*
* Govern the order in which memory listeners are invoked. Lower priorities
* are invoked earlier for "add" or "start" callbacks, and later for "delete"
* or "stop" callbacks.
*/
unsigned priority;
/* private: */
AddressSpace *address_space;
QTAILQ_ENTRY(MemoryListener) link;
QTAILQ_ENTRY(MemoryListener) link_as;
@ -452,7 +658,7 @@ struct MemoryListener {
* AddressSpace: describes a mapping of addresses to #MemoryRegion objects
*/
struct AddressSpace {
/* All fields are private. */
/* private: */
struct rcu_head rcu;
char *name;
MemoryRegion *root;
@ -936,6 +1142,7 @@ void memory_region_init_rom(MemoryRegion *mr,
* @mr: the #MemoryRegion to be initialized.
* @owner: the object that tracks the region's reference count
* @ops: callbacks for write access handling (must not be NULL).
* @opaque: passed to the read and write callbacks of the @ops structure.
* @name: Region name, becomes part of RAMBlock name used in migration stream
* must be unique within any device
* @size: size of the region.
@ -1024,7 +1231,7 @@ static inline IOMMUMemoryRegion *memory_region_get_iommu(MemoryRegion *mr)
* Returns pointer to IOMMUMemoryRegionClass if a memory region is an iommu,
* otherwise NULL. This is fast path avoiding QOM checking, use with caution.
*
* @mr: the memory region being queried
* @iommu_mr: the memory region being queried
*/
static inline IOMMUMemoryRegionClass *memory_region_get_iommu_class_nocheck(
IOMMUMemoryRegion *iommu_mr)
@ -1094,6 +1301,7 @@ void memory_region_notify_one(IOMMUNotifier *notifier,
* @n: the IOMMUNotifier to be added; the notify callback receives a
* pointer to an #IOMMUTLBEntry as the opaque value; the pointer
* ceases to be valid on exit from the notifier.
* @errp: pointer to Error*, to store an error if it happens.
*/
int memory_region_register_iommu_notifier(MemoryRegion *mr,
IOMMUNotifier *n, Error **errp);
@ -1266,9 +1474,12 @@ void *memory_region_get_ram_ptr(MemoryRegion *mr);
void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize,
Error **errp);
/**
* memory_region_do_writeback: Trigger writeback for selected address range
* [addr, addr + size]
* memory_region_do_writeback: Trigger cache writeback or msync for
* selected address range
*
* @mr: the memory region to be updated
* @addr: the initial address of the range to be written back
* @size: the size of the range to be written back
*/
void memory_region_do_writeback(MemoryRegion *mr, hwaddr addr, hwaddr size);
@ -1587,6 +1798,8 @@ void memory_region_add_subregion_overlap(MemoryRegion *mr,
/**
* memory_region_get_ram_addr: Get the ram address associated with a memory
* region
*
* @mr: the region to be queried
*/
ram_addr_t memory_region_get_ram_addr(MemoryRegion *mr);
@ -1679,8 +1892,8 @@ bool memory_region_is_mapped(MemoryRegion *mr);
*
* Returns a #MemoryRegionSection that describes a contiguous overlap.
* It will have the following characteristics:
* .@size = 0 iff no overlap was found
* .@mr is non-%NULL iff an overlap was found
* - @size = 0 iff no overlap was found
* - @mr is non-%NULL iff an overlap was found
*
* Remember that in the return value the @offset_within_region is
* relative to the returned region (in the .@mr field), not to the
@ -1691,8 +1904,8 @@ bool memory_region_is_mapped(MemoryRegion *mr);
* returned one. However, in the special case where the @mr argument
* has no container (and thus is the root of the address space), the
* following will hold:
* .@offset_within_address_space >= @addr
* .@offset_within_address_space + .@size <= @addr + @size
* - @offset_within_address_space >= @addr
* - @offset_within_address_space + .@size <= @addr + @size
*
* @mr: a MemoryRegion within which @addr is a relative address
* @addr: start of the area within @as to be searched
@ -2157,6 +2370,7 @@ static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
* @addr: address within that address space
* @attrs: memory transaction attributes
* @buf: buffer with the data transferred
* @len: length of the data transferred
*/
static inline __attribute__((__always_inline__))
MemTxResult address_space_read(AddressSpace *as, hwaddr addr,
@ -2171,7 +2385,7 @@ MemTxResult address_space_read(AddressSpace *as, hwaddr addr,
if (__builtin_constant_p(len)) {
if (len) {
rcu_read_lock();
RCU_READ_LOCK_GUARD();
fv = address_space_to_flatview(as);
l = len;
mr = flatview_translate(fv, addr, &addr1, &l, false, attrs);
@ -2182,7 +2396,6 @@ MemTxResult address_space_read(AddressSpace *as, hwaddr addr,
result = flatview_read_continue(fv, addr, attrs, buf, len,
addr1, l, mr);
}
rcu_read_unlock();
}
} else {
result = address_space_read_full(as, addr, attrs, buf, len);

View File

@ -63,10 +63,6 @@ extern MachineState *current_machine;
void machine_run_board_init(MachineState *machine);
bool machine_usb(MachineState *machine);
bool machine_kernel_irqchip_allowed(MachineState *machine);
bool machine_kernel_irqchip_required(MachineState *machine);
bool machine_kernel_irqchip_split(MachineState *machine);
int machine_kvm_shadow_mem(MachineState *machine);
int machine_phandle_start(MachineState *machine);
bool machine_dump_guest_core(MachineState *machine);
bool machine_mem_merge(MachineState *machine);
@ -275,11 +271,9 @@ struct MachineState {
/*< public >*/
char *accel;
bool kernel_irqchip_allowed;
bool kernel_irqchip_required;
bool kernel_irqchip_split;
int kvm_shadow_mem;
char *dtb;
char *dumpdtb;
int phandle_start;
@ -288,7 +282,6 @@ struct MachineState {
bool mem_merge;
bool usb;
bool usb_disabled;
bool igd_gfx_passthru;
char *firmware;
bool iommu;
bool suppress_vmdesc;

View File

@ -3,11 +3,9 @@
#include "exec/memory.h"
#include "hw/boards.h"
#include "hw/isa/isa.h"
#include "hw/block/fdc.h"
#include "hw/block/flash.h"
#include "net/net.h"
#include "hw/i386/ioapic.h"
#include "hw/i386/x86.h"
#include "qemu/range.h"
@ -43,7 +41,6 @@ struct PCMachineState {
/* Configuration options: */
OnOffAuto vmport;
OnOffAuto smm;
bool acpi_build_enabled;
bool smbus_enabled;
@ -61,7 +58,6 @@ struct PCMachineState {
#define PC_MACHINE_ACPI_DEVICE_PROP "acpi-device"
#define PC_MACHINE_DEVMEM_REGION_SIZE "device-memory-region-size"
#define PC_MACHINE_VMPORT "vmport"
#define PC_MACHINE_SMM "smm"
#define PC_MACHINE_SMBUS "smbus"
#define PC_MACHINE_SATA "sata"
#define PC_MACHINE_PIT "pit"
@ -134,27 +130,8 @@ typedef struct PCMachineClass {
#define PC_MACHINE_CLASS(klass) \
OBJECT_CLASS_CHECK(PCMachineClass, (klass), TYPE_PC_MACHINE)
/* i8259.c */
extern DeviceState *isa_pic;
qemu_irq *i8259_init(ISABus *bus, qemu_irq parent_irq);
qemu_irq *kvm_i8259_init(ISABus *bus);
int pic_read_irq(DeviceState *d);
int pic_get_output(DeviceState *d);
/* ioapic.c */
/* Global System Interrupts */
#define GSI_NUM_PINS IOAPIC_NUM_PINS
typedef struct GSIState {
qemu_irq i8259_irq[ISA_NUM_IRQS];
qemu_irq ioapic_irq[IOAPIC_NUM_PINS];
} GSIState;
void gsi_handler(void *opaque, int n, int level);
GSIState *pc_gsi_create(qemu_irq **irqs, bool pci_enabled);
/* vmport.c */
@ -173,7 +150,6 @@ void vmmouse_set_data(const uint32_t *data);
/* pc.c */
extern int fd_bootchk;
bool pc_machine_is_smm_enabled(PCMachineState *pcms);
void pc_acpi_smi_interrupt(void *opaque, int irq, int level);
void pc_hot_add_cpu(MachineState *ms, const int64_t id, Error **errp);
@ -199,7 +175,6 @@ void pc_memory_init(PCMachineState *pcms,
MemoryRegion *rom_memory,
MemoryRegion **ram_memory);
uint64_t pc_pci_hole64_start(void);
qemu_irq pc_allocate_cpu_irq(void);
DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus);
void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
ISADevice **rtc_state,
@ -217,17 +192,14 @@ void pc_pci_device_init(PCIBus *pci_bus);
typedef void (*cpu_set_smm_t)(int smm, void *arg);
void pc_i8259_create(ISABus *isa_bus, qemu_irq *i8259_irqs);
void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name);
ISADevice *pc_find_fdc0(void);
int cmos_get_fd_drive_type(FloppyDriveType fd0);
#define FW_CFG_IO_BASE 0x510
/* port92.c */
#define PORT92_A20_LINE "a20"
/* hpet.c */
extern int no_hpet;
#define TYPE_PORT92 "port92"
/* pc_sysfw.c */
void pc_system_flash_create(PCMachineState *pcms);

View File

@ -23,6 +23,8 @@
#include "hw/boards.h"
#include "hw/nmi.h"
#include "hw/isa/isa.h"
#include "hw/i386/ioapic.h"
typedef struct {
/*< private >*/
@ -60,6 +62,8 @@ typedef struct {
uint16_t boot_cpus;
unsigned smp_dies;
OnOffAuto smm;
/*
* Address space used by IOAPIC device. All IOAPIC interrupts
* will be translated to MSI messages in the address space.
@ -68,6 +72,7 @@ typedef struct {
} X86MachineState;
#define X86_MACHINE_MAX_RAM_BELOW_4G "max-ram-below-4g"
#define X86_MACHINE_SMM "smm"
#define TYPE_X86_MACHINE MACHINE_TYPE_NAME("x86")
#define X86_MACHINE(obj) \
@ -95,4 +100,22 @@ void x86_load_linux(X86MachineState *x86ms,
bool pvh_enabled,
bool linuxboot_dma_enabled);
bool x86_machine_is_smm_enabled(X86MachineState *x86ms);
/* Global System Interrupts */
#define GSI_NUM_PINS IOAPIC_NUM_PINS
typedef struct GSIState {
qemu_irq i8259_irq[ISA_NUM_IRQS];
qemu_irq ioapic_irq[IOAPIC_NUM_PINS];
} GSIState;
qemu_irq x86_allocate_cpu_irq(void);
void gsi_handler(void *opaque, int n, int level);
void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name);
/* hpet.c */
extern int no_hpet;
#endif

12
include/hw/intc/i8259.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef HW_I8259_H
#define HW_I8259_H
/* i8259.c */
extern DeviceState *isa_pic;
qemu_irq *i8259_init(ISABus *bus, qemu_irq parent_irq);
qemu_irq *kvm_i8259_init(ISABus *bus);
int pic_get_output(DeviceState *d);
int pic_read_irq(DeviceState *d);
#endif

View File

@ -25,9 +25,9 @@
#ifndef QEMU_I8259_INTERNAL_H
#define QEMU_I8259_INTERNAL_H
#include "hw/i386/pc.h"
#include "hw/isa/isa.h"
#include "hw/intc/intc.h"
#include "hw/intc/i8259.h"
typedef struct PICCommonState PICCommonState;

View File

@ -88,7 +88,7 @@ struct ISADevice {
DeviceState parent_obj;
/*< public >*/
uint32_t isairq[2];
int8_t isairq[2]; /* -1 = unassigned */
int nirqs;
int ioport_id;
};
@ -96,9 +96,9 @@ struct ISADevice {
ISABus *isa_bus_new(DeviceState *dev, MemoryRegion *address_space,
MemoryRegion *address_space_io, Error **errp);
void isa_bus_irqs(ISABus *bus, qemu_irq *irqs);
qemu_irq isa_get_irq(ISADevice *dev, int isairq);
void isa_init_irq(ISADevice *dev, qemu_irq *p, int isairq);
void isa_connect_gpio_out(ISADevice *isadev, int gpioirq, int isairq);
qemu_irq isa_get_irq(ISADevice *dev, unsigned isairq);
void isa_init_irq(ISADevice *dev, qemu_irq *p, unsigned isairq);
void isa_connect_gpio_out(ISADevice *isadev, int gpioirq, unsigned isairq);
void isa_bus_dma(ISABus *bus, IsaDma *dma8, IsaDma *dma16);
IsaDma *isa_get_dma(ISABus *bus, int nchan);
MemoryRegion *isa_address_space(ISADevice *dev);

View File

@ -13,12 +13,27 @@
#include "hw/hw.h"
#include "hw/pci/pci_bus.h"
typedef struct PCII440FXState PCII440FXState;
#include "hw/pci-host/pam.h"
#define TYPE_I440FX_PCI_HOST_BRIDGE "i440FX-pcihost"
#define TYPE_I440FX_PCI_DEVICE "i440FX"
#define I440FX_PCI_DEVICE(obj) \
OBJECT_CHECK(PCII440FXState, (obj), TYPE_I440FX_PCI_DEVICE)
typedef struct PCII440FXState {
/*< private >*/
PCIDevice parent_obj;
/*< public >*/
MemoryRegion *system_memory;
MemoryRegion *pci_address_space;
MemoryRegion *ram_memory;
PAMMemoryRegion pam_regions[13];
MemoryRegion smram_region;
MemoryRegion smram, low_smram;
} PCII440FXState;
#define TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE "igd-passthrough-i440FX"
PCIBus *i440fx_init(const char *host_type, const char *pci_type,

View File

@ -174,7 +174,7 @@ enum {
#define QEMU_PCI_CAP_MULTIFUNCTION_BITNR 3
QEMU_PCI_CAP_MULTIFUNCTION = (1 << QEMU_PCI_CAP_MULTIFUNCTION_BITNR),
/* command register SERR bit enabled */
/* command register SERR bit enabled - unused since QEMU v5.0 */
#define QEMU_PCI_CAP_SERR_BITNR 4
QEMU_PCI_CAP_SERR = (1 << QEMU_PCI_CAP_SERR_BITNR),
/* Standard hot plug controller. */

View File

@ -424,13 +424,16 @@ static inline uint64_t deposit64(uint64_t value, int start, int length,
/**
* half_shuffle32:
* @value: 32-bit value (of which only the bottom 16 bits are of interest)
* @x: 32-bit value (of which only the bottom 16 bits are of interest)
*
* Given an input value::
*
* xxxx xxxx xxxx xxxx ABCD EFGH IJKL MNOP
*
* Given an input value:
* xxxx xxxx xxxx xxxx ABCD EFGH IJKL MNOP
* return the value where the bottom 16 bits are spread out into
* the odd bits in the word, and the even bits are zeroed:
* 0A0B 0C0D 0E0F 0G0H 0I0J 0K0L 0M0N 0O0P
* the odd bits in the word, and the even bits are zeroed::
*
* 0A0B 0C0D 0E0F 0G0H 0I0J 0K0L 0M0N 0O0P
*
* Any bits set in the top half of the input are ignored.
*
@ -450,13 +453,16 @@ static inline uint32_t half_shuffle32(uint32_t x)
/**
* half_shuffle64:
* @value: 64-bit value (of which only the bottom 32 bits are of interest)
* @x: 64-bit value (of which only the bottom 32 bits are of interest)
*
* Given an input value::
*
* xxxx xxxx xxxx .... xxxx xxxx ABCD EFGH IJKL MNOP QRST UVWX YZab cdef
*
* Given an input value:
* xxxx xxxx xxxx .... xxxx xxxx ABCD EFGH IJKL MNOP QRST UVWX YZab cdef
* return the value where the bottom 32 bits are spread out into
* the odd bits in the word, and the even bits are zeroed:
* 0A0B 0C0D 0E0F 0G0H 0I0J 0K0L 0M0N .... 0U0V 0W0X 0Y0Z 0a0b 0c0d 0e0f
* the odd bits in the word, and the even bits are zeroed::
*
* 0A0B 0C0D 0E0F 0G0H 0I0J 0K0L 0M0N .... 0U0V 0W0X 0Y0Z 0a0b 0c0d 0e0f
*
* Any bits set in the top half of the input are ignored.
*
@ -477,13 +483,16 @@ static inline uint64_t half_shuffle64(uint64_t x)
/**
* half_unshuffle32:
* @value: 32-bit value (of which only the odd bits are of interest)
* @x: 32-bit value (of which only the odd bits are of interest)
*
* Given an input value::
*
* xAxB xCxD xExF xGxH xIxJ xKxL xMxN xOxP
*
* Given an input value:
* xAxB xCxD xExF xGxH xIxJ xKxL xMxN xOxP
* return the value where all the odd bits are compressed down
* into the low half of the word, and the high half is zeroed:
* 0000 0000 0000 0000 ABCD EFGH IJKL MNOP
* into the low half of the word, and the high half is zeroed::
*
* 0000 0000 0000 0000 ABCD EFGH IJKL MNOP
*
* Any even bits set in the input are ignored.
*
@ -504,13 +513,16 @@ static inline uint32_t half_unshuffle32(uint32_t x)
/**
* half_unshuffle64:
* @value: 64-bit value (of which only the odd bits are of interest)
* @x: 64-bit value (of which only the odd bits are of interest)
*
* Given an input value::
*
* xAxB xCxD xExF xGxH xIxJ xKxL xMxN .... xUxV xWxX xYxZ xaxb xcxd xexf
*
* Given an input value:
* xAxB xCxD xExF xGxH xIxJ xKxL xMxN .... xUxV xWxX xYxZ xaxb xcxd xexf
* return the value where all the odd bits are compressed down
* into the low half of the word, and the high half is zeroed:
* 0000 0000 0000 .... 0000 0000 ABCD EFGH IJKL MNOP QRST UVWX YZab cdef
* into the low half of the word, and the high half is zeroed::
*
* 0000 0000 0000 .... 0000 0000 ABCD EFGH IJKL MNOP QRST UVWX YZab cdef
*
* Any even bits set in the input are ignored.
*

View File

@ -200,8 +200,14 @@ typedef struct InterfaceInfo InterfaceInfo;
*
* Interfaces allow a limited form of multiple inheritance. Instances are
* similar to normal types except for the fact that are only defined by
* their classes and never carry any state. You can dynamically cast an object
* to one of its #Interface types and vice versa.
* their classes and never carry any state. As a consequence, a pointer to
* an interface instance should always be of incomplete type in order to be
* sure it cannot be dereferenced. That is, you should define the
* 'typedef struct SomethingIf SomethingIf' so that you can pass around
* 'SomethingIf *si' arguments, but not define a 'struct SomethingIf { ... }'.
* The only things you can validly do with a 'SomethingIf *' are to pass it as
* an argument to a method on its corresponding SomethingIfClass, or to
* dynamically cast it to an object that implements the interface.
*
* # Methods #
*
@ -592,6 +598,18 @@ struct InterfaceClass
((interface *)object_dynamic_cast_assert(OBJECT((obj)), (name), \
__FILE__, __LINE__, __func__))
/**
* object_new_with_class:
* @klass: The class to instantiate.
*
* This function will initialize a new object using heap allocated memory.
* The returned object has a reference count of 1, and will be freed when
* the last reference is dropped.
*
* Returns: The newly allocated and instantiated object.
*/
Object *object_new_with_class(ObjectClass *klass);
/**
* object_new:
* @typename: The name of the type of the object to instantiate.
@ -679,6 +697,7 @@ void object_apply_global_props(Object *obj, const GPtrArray *props,
Error **errp);
void object_set_machine_compat_props(GPtrArray *compat_props);
void object_set_accelerator_compat_props(GPtrArray *compat_props);
void object_register_sugar_prop(const char *driver, const char *prop, const char *value);
void object_apply_compat_props(Object *obj);
/**

View File

@ -64,9 +64,9 @@ typedef struct AccelClass {
#define ACCEL_GET_CLASS(obj) \
OBJECT_GET_CLASS(AccelClass, (obj), TYPE_ACCEL)
extern unsigned long tcg_tb_size;
AccelClass *accel_find(const char *opt_name);
int accel_init_machine(AccelState *accel, MachineState *ms);
void configure_accelerator(MachineState *ms, const char *progname);
/* Called just before os_setup_post (ie just before drop OS privs) */
void accel_setup_post(MachineState *ms);

View File

@ -40,6 +40,4 @@ extern int smp_threads;
void list_cpus(const char *optarg);
void qemu_tcg_configure(QemuOpts *opts, Error **errp);
#endif

View File

@ -515,14 +515,16 @@ int kvm_irqchip_add_irqfd_notifier(KVMState *s, EventNotifier *n,
int kvm_irqchip_remove_irqfd_notifier(KVMState *s, EventNotifier *n,
qemu_irq irq);
void kvm_irqchip_set_qemuirq_gsi(KVMState *s, qemu_irq irq, int gsi);
void kvm_pc_gsi_handler(void *opaque, int n, int level);
void kvm_pc_setup_irq_routing(bool pci_enabled);
void kvm_init_irq_routing(KVMState *s);
bool kvm_kernel_irqchip_allowed(void);
bool kvm_kernel_irqchip_required(void);
bool kvm_kernel_irqchip_split(void);
/**
* kvm_arch_irqchip_create:
* @KVMState: The KVMState pointer
* @MachineState: The MachineState pointer
*
* Allow architectures to create an in-kernel irq chip themselves.
*
@ -530,7 +532,7 @@ void kvm_init_irq_routing(KVMState *s);
* 0: irq chip was not created
* > 0: irq chip was created
*/
int kvm_arch_irqchip_create(MachineState *ms, KVMState *s);
int kvm_arch_irqchip_create(KVMState *s);
/**
* kvm_set_one_reg - set a register value in KVM via KVM_SET_ONE_REG ioctl

View File

@ -2991,7 +2991,6 @@ struct FlatViewInfo {
bool dispatch_tree;
bool owner;
AccelClass *ac;
const char *ac_name;
};
static void mtree_print_flatview(gpointer key, gpointer value,
@ -3061,7 +3060,7 @@ static void mtree_print_flatview(gpointer key, gpointer value,
if (fvi->ac->has_memory(current_machine, as,
int128_get64(range->addr.start),
MR_SIZE(range->addr.size) + 1)) {
qemu_printf(" %s", fvi->ac_name);
qemu_printf(" %s", fvi->ac->name);
}
}
}
@ -3109,8 +3108,6 @@ void mtree_info(bool flatview, bool dispatch_tree, bool owner)
if (ac->has_memory) {
fvi.ac = ac;
fvi.ac_name = current_machine->accel ? current_machine->accel :
object_class_get_name(OBJECT_CLASS(ac));
}
/* Gather all FVs in one table */

View File

@ -863,15 +863,17 @@ static int multifd_recv_unfill_packet(MultiFDRecvParams *p, Error **errp)
p->next_packet_size = be32_to_cpu(packet->next_packet_size);
p->packet_num = be64_to_cpu(packet->packet_num);
if (p->pages->used) {
/* make sure that ramblock is 0 terminated */
packet->ramblock[255] = 0;
block = qemu_ram_block_by_name(packet->ramblock);
if (!block) {
error_setg(errp, "multifd: unknown ram block %s",
packet->ramblock);
return -1;
}
if (p->pages->used == 0) {
return 0;
}
/* make sure that ramblock is 0 terminated */
packet->ramblock[255] = 0;
block = qemu_ram_block_by_name(packet->ramblock);
if (!block) {
error_setg(errp, "multifd: unknown ram block %s",
packet->ramblock);
return -1;
}
for (i = 0; i < p->pages->used; i++) {
@ -3888,26 +3890,27 @@ int colo_init_ram_cache(void)
{
RAMBlock *block;
rcu_read_lock();
RAMBLOCK_FOREACH_NOT_IGNORED(block) {
block->colo_cache = qemu_anon_ram_alloc(block->used_length,
NULL,
false);
if (!block->colo_cache) {
error_report("%s: Can't alloc memory for COLO cache of block %s,"
"size 0x" RAM_ADDR_FMT, __func__, block->idstr,
block->used_length);
RAMBLOCK_FOREACH_NOT_IGNORED(block) {
if (block->colo_cache) {
qemu_anon_ram_free(block->colo_cache, block->used_length);
block->colo_cache = NULL;
WITH_RCU_READ_LOCK_GUARD() {
RAMBLOCK_FOREACH_NOT_IGNORED(block) {
block->colo_cache = qemu_anon_ram_alloc(block->used_length,
NULL,
false);
if (!block->colo_cache) {
error_report("%s: Can't alloc memory for COLO cache of block %s,"
"size 0x" RAM_ADDR_FMT, __func__, block->idstr,
block->used_length);
RAMBLOCK_FOREACH_NOT_IGNORED(block) {
if (block->colo_cache) {
qemu_anon_ram_free(block->colo_cache, block->used_length);
block->colo_cache = NULL;
}
}
return -errno;
}
return -errno;
memcpy(block->colo_cache, block->host, block->used_length);
}
memcpy(block->colo_cache, block->host, block->used_length);
}
rcu_read_unlock();
/*
* Record the dirty pages that sent by PVM, we use this dirty bitmap together
* with to decide which page in cache should be flushed into SVM's RAM. Here

View File

@ -394,7 +394,7 @@ int monitor_set_cpu(int cpu_index)
/* Callers must hold BQL. */
static CPUState *mon_get_cpu_sync(bool synchronize)
{
CPUState *cpu;
CPUState *cpu = NULL;
if (cur_mon->mon_cpu_path) {
cpu = (CPUState *) object_resolve_path_type(cur_mon->mon_cpu_path,
@ -411,6 +411,7 @@ static CPUState *mon_get_cpu_sync(bool synchronize)
monitor_set_cpu(first_cpu->cpu_index);
cpu = first_cpu;
}
assert(cpu != NULL);
if (synchronize) {
cpu_synchronize_state(cpu);
}

View File

@ -80,41 +80,26 @@ void os_setup_signal_handling(void)
sigaction(SIGTERM, &act, NULL);
}
/* Find a likely location for support files using the location of the binary.
For installed binaries this will be "$bindir/../share/qemu". When
running from the build tree this will be "$bindir/../pc-bios". */
#define SHARE_SUFFIX "/share/qemu"
#define BUILD_SUFFIX "/pc-bios"
/*
* Find a likely location for support files using the location of the binary.
* When running from the build tree this will be "$bindir/../pc-bios".
* Otherwise, this is CONFIG_QEMU_DATADIR.
*/
char *os_find_datadir(void)
{
char *dir, *exec_dir;
char *res;
size_t max_len;
g_autofree char *exec_dir = NULL;
g_autofree char *dir = NULL;
exec_dir = qemu_get_exec_dir();
if (exec_dir == NULL) {
return NULL;
}
dir = g_path_get_dirname(exec_dir);
g_return_val_if_fail(exec_dir != NULL, NULL);
max_len = strlen(dir) +
MAX(strlen(SHARE_SUFFIX), strlen(BUILD_SUFFIX)) + 1;
res = g_malloc0(max_len);
snprintf(res, max_len, "%s%s", dir, SHARE_SUFFIX);
if (access(res, R_OK)) {
snprintf(res, max_len, "%s%s", dir, BUILD_SUFFIX);
if (access(res, R_OK)) {
g_free(res);
res = NULL;
}
dir = g_build_filename(exec_dir, "..", "pc-bios", NULL);
if (g_file_test(dir, G_FILE_TEST_IS_DIR)) {
return g_steal_pointer(&dir);
}
g_free(dir);
g_free(exec_dir);
return res;
return g_strdup(CONFIG_QEMU_DATADIR);
}
#undef SHARE_SUFFIX
#undef BUILD_SUFFIX
void os_set_proc_name(const char *s)
{

View File

@ -43,7 +43,7 @@
#include "net/tap-linux.h"
#ifdef CONFIG_LIBCAP
#ifdef CONFIG_LIBCAP_NG
#include <cap-ng.h>
#endif
@ -207,7 +207,7 @@ static int send_fd(int c, int fd)
return sendmsg(c, &msg, 0);
}
#ifdef CONFIG_LIBCAP
#ifdef CONFIG_LIBCAP_NG
static int drop_privileges(void)
{
/* clear all capabilities */
@ -246,7 +246,7 @@ int main(int argc, char **argv)
int access_allowed, access_denied;
int ret = EXIT_SUCCESS;
#ifdef CONFIG_LIBCAP
#ifdef CONFIG_LIBCAP_NG
/* if we're run from an suid binary, immediately drop privileges preserving
* cap_net_admin */
if (geteuid() == 0 && getuid() != geteuid()) {

View File

@ -142,6 +142,12 @@ QEMU 4.1 has three options, please migrate to one of these three:
to do is specify the kernel they want to boot with the -kernel option
3. ``-bios <file>`` - Tells QEMU to load the specified file as the firmwrae.
@subsection -tb-size option (since 5.0)
QEMU 5.0 introduced an alternative syntax to specify the size of the translation
block cache, @option{-accel tcg,tb-size=}. The new syntax deprecates the
previously available @option{-tb-size} option.
@section QEMU Machine Protocol (QMP) commands
@subsection change (since 2.5.0)
@ -259,7 +265,7 @@ The 'scsi-disk' device is deprecated. Users should use 'scsi-hd' or
This machine type is very old and unmaintained. Users should use the 'malta'
machine type instead.
@subsection pc-0.12, pc-0.13, pc-0.14 and pc-0.15 (since 4.0)
@subsection pc-1.0, pc-1.1, pc-1.2 and pc-1.3 (since 5.0)
These machine types are very old and likely can not be used for live migration
from old QEMU versions anymore. A newer machine type should be used instead.

Some files were not shown because too many files have changed in this diff Show More