aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/9pfs/9p-local.c58
-rw-r--r--hw/9pfs/xen-9p-backend.c4
-rw-r--r--hw/acpi/aml-build.c26
-rw-r--r--hw/acpi/cpu.c7
-rw-r--r--hw/acpi/piix4.c2
-rw-r--r--hw/arm/spitz.c2
-rw-r--r--hw/arm/virt-acpi-build.c19
-rw-r--r--hw/arm/virt.c123
-rw-r--r--hw/audio/marvell_88w8618.c2
-rw-r--r--hw/audio/pcspk.c2
-rw-r--r--hw/block/nvme.c26
-rw-r--r--hw/block/nvme.h1
-rw-r--r--hw/block/virtio-blk.c4
-rw-r--r--hw/core/generic-loader.c9
-rw-r--r--hw/core/machine.c162
-rw-r--r--hw/core/or-irq.c2
-rw-r--r--hw/core/qdev.c1
-rw-r--r--hw/core/register.c2
-rw-r--r--hw/core/sysbus.c11
-rw-r--r--hw/display/cg3.c41
-rw-r--r--hw/display/jazz_led.c4
-rw-r--r--hw/display/sm501.c27
-rw-r--r--hw/display/tcx.c68
-rw-r--r--hw/display/vga.c2
-rw-r--r--hw/display/virtio-gpu-3d.c16
-rw-r--r--hw/display/virtio-gpu.c18
-rw-r--r--hw/dma/i8257.c2
-rw-r--r--hw/dma/sparc32_dma.c2
-rw-r--r--hw/gpio/omap_gpio.c4
-rw-r--r--hw/i2c/omap_i2c.c2
-rw-r--r--hw/i2c/smbus_eeprom.c2
-rw-r--r--hw/i2c/smbus_ich9.c2
-rw-r--r--hw/i386/acpi-build.c15
-rw-r--r--hw/i386/amd_iommu.c2
-rw-r--r--hw/i386/intel_iommu.c2
-rw-r--r--hw/i386/pc.c56
-rw-r--r--hw/i386/pc_piix.c2
-rw-r--r--hw/i386/pc_q35.c2
-rw-r--r--hw/i386/xen/xen-mapcache.c15
-rw-r--r--hw/input/virtio-input-hid.c6
-rw-r--r--hw/input/vmmouse.c2
-rw-r--r--hw/intc/apic_common.c2
-rw-r--r--hw/intc/etraxfs_pic.c2
-rw-r--r--hw/intc/grlib_irqmp.c2
-rw-r--r--hw/intc/i8259_common.c2
-rw-r--r--hw/intc/nios2_iic.c2
-rw-r--r--hw/intc/omap_intc.c4
-rw-r--r--hw/intc/xics_kvm.c13
-rw-r--r--hw/isa/lpc_ich9.c2
-rw-r--r--hw/isa/piix4.c2
-rw-r--r--hw/isa/vt82c686.c2
-rw-r--r--hw/microblaze/boot.c2
-rw-r--r--hw/mips/gt64xxx_pci.c2
-rw-r--r--hw/misc/vmport.c2
-rw-r--r--hw/net/dp8393x.c2
-rw-r--r--hw/net/etraxfs_eth.c2
-rw-r--r--hw/net/fsl_etsec/etsec.c2
-rw-r--r--hw/net/lance.c2
-rw-r--r--hw/nios2/boot.c2
-rw-r--r--hw/pci-bridge/dec.c2
-rw-r--r--hw/pci-bridge/pci_expander_bridge.c2
-rw-r--r--hw/pci-host/apb.c2
-rw-r--r--hw/pci-host/bonito.c2
-rw-r--r--hw/pci-host/gpex.c2
-rw-r--r--hw/pci-host/grackle.c2
-rw-r--r--hw/pci-host/piix.c6
-rw-r--r--hw/pci-host/ppce500.c2
-rw-r--r--hw/pci-host/prep.c2
-rw-r--r--hw/pci-host/q35.c4
-rw-r--r--hw/pci-host/uninorth.c8
-rw-r--r--hw/pci-host/versatile.c2
-rw-r--r--hw/pci-host/xilinx-pcie.c2
-rw-r--r--hw/ppc/mac_newworld.c18
-rw-r--r--hw/ppc/mac_oldworld.c18
-rw-r--r--hw/ppc/pnv.c4
-rw-r--r--hw/ppc/ppc4xx_pci.c2
-rw-r--r--hw/ppc/ppc_booke.c1
-rw-r--r--hw/ppc/spapr.c63
-rw-r--r--hw/ppc/spapr_cpu_core.c21
-rw-r--r--hw/ppc/spapr_drc.c2
-rw-r--r--hw/ppc/spapr_hcall.c18
-rw-r--r--hw/ppc/spapr_pci.c2
-rw-r--r--hw/s390x/s390-pci-bus.c1
-rw-r--r--hw/s390x/sclp.c4
-rw-r--r--hw/sd/milkymist-memcard.c2
-rw-r--r--hw/sd/pl181.c2
-rw-r--r--hw/sh4/sh_pci.c2
-rw-r--r--hw/timer/i8254_common.c2
-rw-r--r--hw/timer/mc146818rtc.c2
-rw-r--r--hw/tricore/tricore_testboard.c2
-rw-r--r--hw/usb/dev-hub.c1
-rw-r--r--hw/usb/dev-serial.c24
-rw-r--r--hw/usb/dev-smartcard-reader.c5
-rw-r--r--hw/usb/hcd-xhci.c9
-rw-r--r--hw/usb/redirect.c13
-rw-r--r--hw/vfio/amd-xgbe.c2
-rw-r--r--hw/vfio/calxeda-xgmac.c2
-rw-r--r--hw/xen/xen_backend.c4
98 files changed, 750 insertions, 318 deletions
diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
index f3ebca4f7a..a2486566af 100644
--- a/hw/9pfs/9p-local.c
+++ b/hw/9pfs/9p-local.c
@@ -452,6 +452,11 @@ static off_t local_telldir(FsContext *ctx, V9fsFidOpenState *fs)
return telldir(fs->dir.stream);
}
+static bool local_is_mapped_file_metadata(FsContext *fs_ctx, const char *name)
+{
+ return !strcmp(name, VIRTFS_META_DIR);
+}
+
static struct dirent *local_readdir(FsContext *ctx, V9fsFidOpenState *fs)
{
struct dirent *entry;
@@ -465,8 +470,8 @@ again:
if (ctx->export_flags & V9FS_SM_MAPPED) {
entry->d_type = DT_UNKNOWN;
} else if (ctx->export_flags & V9FS_SM_MAPPED_FILE) {
- if (!strcmp(entry->d_name, VIRTFS_META_DIR)) {
- /* skp the meta data directory */
+ if (local_is_mapped_file_metadata(ctx, entry->d_name)) {
+ /* skip the meta data directory */
goto again;
}
entry->d_type = DT_UNKNOWN;
@@ -559,6 +564,12 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath *dir_path,
int err = -1;
int dirfd;
+ if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE &&
+ local_is_mapped_file_metadata(fs_ctx, name)) {
+ errno = EINVAL;
+ return -1;
+ }
+
dirfd = local_opendir_nofollow(fs_ctx, dir_path->data);
if (dirfd == -1) {
return -1;
@@ -605,6 +616,12 @@ static int local_mkdir(FsContext *fs_ctx, V9fsPath *dir_path,
int err = -1;
int dirfd;
+ if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE &&
+ local_is_mapped_file_metadata(fs_ctx, name)) {
+ errno = EINVAL;
+ return -1;
+ }
+
dirfd = local_opendir_nofollow(fs_ctx, dir_path->data);
if (dirfd == -1) {
return -1;
@@ -694,6 +711,12 @@ static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name,
int err = -1;
int dirfd;
+ if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE &&
+ local_is_mapped_file_metadata(fs_ctx, name)) {
+ errno = EINVAL;
+ return -1;
+ }
+
/*
* Mark all the open to not follow symlinks
*/
@@ -752,6 +775,12 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
int err = -1;
int dirfd;
+ if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE &&
+ local_is_mapped_file_metadata(fs_ctx, name)) {
+ errno = EINVAL;
+ return -1;
+ }
+
dirfd = local_opendir_nofollow(fs_ctx, dir_path->data);
if (dirfd == -1) {
return -1;
@@ -826,6 +855,12 @@ static int local_link(FsContext *ctx, V9fsPath *oldpath,
int ret = -1;
int odirfd, ndirfd;
+ if (ctx->export_flags & V9FS_SM_MAPPED_FILE &&
+ local_is_mapped_file_metadata(ctx, name)) {
+ errno = EINVAL;
+ return -1;
+ }
+
odirfd = local_opendir_nofollow(ctx, odirpath);
if (odirfd == -1) {
goto out;
@@ -1096,6 +1131,12 @@ static int local_lremovexattr(FsContext *ctx, V9fsPath *fs_path,
static int local_name_to_path(FsContext *ctx, V9fsPath *dir_path,
const char *name, V9fsPath *target)
{
+ if (ctx->export_flags & V9FS_SM_MAPPED_FILE &&
+ local_is_mapped_file_metadata(ctx, name)) {
+ errno = EINVAL;
+ return -1;
+ }
+
if (dir_path) {
v9fs_path_sprintf(target, "%s/%s", dir_path->data, name);
} else if (strcmp(name, "/")) {
@@ -1116,6 +1157,13 @@ static int local_renameat(FsContext *ctx, V9fsPath *olddir,
int ret;
int odirfd, ndirfd;
+ if (ctx->export_flags & V9FS_SM_MAPPED_FILE &&
+ (local_is_mapped_file_metadata(ctx, old_name) ||
+ local_is_mapped_file_metadata(ctx, new_name))) {
+ errno = EINVAL;
+ return -1;
+ }
+
odirfd = local_opendir_nofollow(ctx, olddir->data);
if (odirfd == -1) {
return -1;
@@ -1206,6 +1254,12 @@ static int local_unlinkat(FsContext *ctx, V9fsPath *dir,
int ret;
int dirfd;
+ if (ctx->export_flags & V9FS_SM_MAPPED_FILE &&
+ local_is_mapped_file_metadata(ctx, name)) {
+ errno = EINVAL;
+ return -1;
+ }
+
dirfd = local_opendir_nofollow(ctx, dir->data);
if (dirfd == -1) {
return -1;
diff --git a/hw/9pfs/xen-9p-backend.c b/hw/9pfs/xen-9p-backend.c
index 9c7f41af99..5df97c90fa 100644
--- a/hw/9pfs/xen-9p-backend.c
+++ b/hw/9pfs/xen-9p-backend.c
@@ -332,12 +332,14 @@ static int xen_9pfs_connect(struct XenDevice *xendev)
str = g_strdup_printf("ring-ref%u", i);
if (xenstore_read_fe_int(&xen_9pdev->xendev, str,
&xen_9pdev->rings[i].ref) == -1) {
+ g_free(str);
goto out;
}
g_free(str);
str = g_strdup_printf("event-channel-%u", i);
if (xenstore_read_fe_int(&xen_9pdev->xendev, str,
&xen_9pdev->rings[i].evtchn) == -1) {
+ g_free(str);
goto out;
}
g_free(str);
@@ -378,7 +380,7 @@ static int xen_9pfs_connect(struct XenDevice *xendev)
if (xen_9pdev->rings[i].evtchndev == NULL) {
goto out;
}
- fcntl(xenevtchn_fd(xen_9pdev->rings[i].evtchndev), F_SETFD, FD_CLOEXEC);
+ qemu_set_cloexec(xenevtchn_fd(xen_9pdev->rings[i].evtchndev));
xen_9pdev->rings[i].local_port = xenevtchn_bind_interdomain
(xen_9pdev->rings[i].evtchndev,
xendev->dom,
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index 4ddfb68b24..36a6cc450e 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -24,6 +24,7 @@
#include "hw/acpi/aml-build.h"
#include "qemu/bswap.h"
#include "qemu/bitops.h"
+#include "sysemu/numa.h"
static GArray *build_alloc_array(void)
{
@@ -1636,3 +1637,28 @@ void build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base,
numamem->base_addr = cpu_to_le64(base);
numamem->range_length = cpu_to_le64(len);
}
+
+/*
+ * ACPI spec 5.2.17 System Locality Distance Information Table
+ * (Revision 2.0 or later)
+ */
+void build_slit(GArray *table_data, BIOSLinker *linker)
+{
+ int slit_start, i, j;
+ slit_start = table_data->len;
+
+ acpi_data_push(table_data, sizeof(AcpiTableHeader));
+
+ build_append_int_noprefix(table_data, nb_numa_nodes, 8);
+ for (i = 0; i < nb_numa_nodes; i++) {
+ for (j = 0; j < nb_numa_nodes; j++) {
+ assert(numa_info[i].distance[j]);
+ build_append_int_noprefix(table_data, numa_info[i].distance[j], 1);
+ }
+ }
+
+ build_header(linker, table_data,
+ (void *)(table_data->data + slit_start),
+ "SLIT",
+ table_data->len - slit_start, 1, NULL, NULL);
+}
diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index 8c719d3f9d..a233fe17cf 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -503,7 +503,6 @@ void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
/* build Processor object for each processor */
for (i = 0; i < arch_ids->len; i++) {
- int j;
Aml *dev;
Aml *uid = aml_int(i);
GArray *madt_buf = g_array_new(0, 1, 1);
@@ -557,9 +556,9 @@ void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
* as a result _PXM is required for all CPUs which might
* be hot-plugged. For simplicity, add it for all CPUs.
*/
- j = numa_get_node_for_cpu(i);
- if (j < nb_numa_nodes) {
- aml_append(dev, aml_name_decl("_PXM", aml_int(j)));
+ if (arch_ids->cpus[i].props.has_node_id) {
+ aml_append(dev, aml_name_decl("_PXM",
+ aml_int(arch_ids->cpus[i].props.node_id)));
}
aml_append(cpus_dev, dev);
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index c409374ab8..f276967365 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -705,7 +705,7 @@ static void piix4_pm_class_init(ObjectClass *klass, void *data)
* Reason: part of PIIX4 southbridge, needs to be wired up,
* e.g. by mips_malta_init()
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
dc->hotpluggable = false;
hc->plug = piix4_device_plug_cb;
hc->unplug_request = piix4_device_unplug_request_cb;
diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c
index fe2d5a764c..324626847c 100644
--- a/hw/arm/spitz.c
+++ b/hw/arm/spitz.c
@@ -1076,7 +1076,7 @@ static void sl_nand_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_sl_nand_info;
dc->props = sl_nand_properties;
/* Reason: init() method uses drive_get() */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo sl_nand_info = {
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 6e5f3399f2..e5852067f5 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -486,30 +486,25 @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
AcpiSystemResourceAffinityTable *srat;
AcpiSratProcessorGiccAffinity *core;
AcpiSratMemoryAffinity *numamem;
- int i, j, srat_start;
+ int i, srat_start;
uint64_t mem_base;
- uint32_t *cpu_node = g_malloc0(vms->smp_cpus * sizeof(uint32_t));
-
- for (i = 0; i < vms->smp_cpus; i++) {
- j = numa_get_node_for_cpu(i);
- if (j < nb_numa_nodes) {
- cpu_node[i] = j;
- }
- }
+ MachineClass *mc = MACHINE_GET_CLASS(vms);
+ const CPUArchIdList *cpu_list = mc->possible_cpu_arch_ids(MACHINE(vms));
srat_start = table_data->len;
srat = acpi_data_push(table_data, sizeof(*srat));
srat->reserved1 = cpu_to_le32(1);
- for (i = 0; i < vms->smp_cpus; ++i) {
+ for (i = 0; i < cpu_list->len; ++i) {
+ int node_id = cpu_list->cpus[i].props.has_node_id ?
+ cpu_list->cpus[i].props.node_id : 0;
core = acpi_data_push(table_data, sizeof(*core));
core->type = ACPI_SRAT_PROCESSOR_GICC;
core->length = sizeof(*core);
- core->proximity = cpu_to_le32(cpu_node[i]);
+ core->proximity = cpu_to_le32(node_id);
core->acpi_processor_uid = cpu_to_le32(i);
core->flags = cpu_to_le32(1);
}
- g_free(cpu_node);
mem_base = vms->memmap[VIRT_MEM].base;
for (i = 0; i < nb_numa_nodes; ++i) {
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 5f62a0321e..c7c8159dfd 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -338,7 +338,7 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
{
int cpu;
int addr_cells = 1;
- unsigned int i;
+ const MachineState *ms = MACHINE(vms);
/*
* From Documentation/devicetree/bindings/arm/cpus.txt
@@ -369,6 +369,7 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
for (cpu = vms->smp_cpus - 1; cpu >= 0; cpu--) {
char *nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu));
+ CPUState *cs = CPU(armcpu);
qemu_fdt_add_subnode(vms->fdt, nodename);
qemu_fdt_setprop_string(vms->fdt, nodename, "device_type", "cpu");
@@ -389,9 +390,9 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
armcpu->mp_affinity);
}
- i = numa_get_node_for_cpu(cpu);
- if (i < nb_numa_nodes) {
- qemu_fdt_setprop_cell(vms->fdt, nodename, "numa-node-id", i);
+ if (ms->possible_cpus->cpus[cs->cpu_index].props.has_node_id) {
+ qemu_fdt_setprop_cell(vms->fdt, nodename, "numa-node-id",
+ ms->possible_cpus->cpus[cs->cpu_index].props.node_id);
}
g_free(nodename);
@@ -1194,10 +1195,35 @@ void virt_machine_done(Notifier *notifier, void *data)
virt_build_smbios(vms);
}
+static uint64_t virt_cpu_mp_affinity(VirtMachineState *vms, int idx)
+{
+ uint8_t clustersz = ARM_DEFAULT_CPUS_PER_CLUSTER;
+ VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
+
+ if (!vmc->disallow_affinity_adjustment) {
+ /* Adjust MPIDR like 64-bit KVM hosts, which incorporate the
+ * GIC's target-list limitations. 32-bit KVM hosts currently
+ * always create clusters of 4 CPUs, but that is expected to
+ * change when they gain support for gicv3. When KVM is enabled
+ * it will override the changes we make here, therefore our
+ * purposes are to make TCG consistent (with 64-bit KVM hosts)
+ * and to improve SGI efficiency.
+ */
+ if (vms->gic_version == 3) {
+ clustersz = GICV3_TARGETLIST_BITS;
+ } else {
+ clustersz = GIC_TARGETLIST_BITS;
+ }
+ }
+ return arm_cpu_mp_affinity(idx, clustersz);
+}
+
static void machvirt_init(MachineState *machine)
{
VirtMachineState *vms = VIRT_MACHINE(machine);
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(machine);
+ MachineClass *mc = MACHINE_GET_CLASS(machine);
+ const CPUArchIdList *possible_cpus;
qemu_irq pic[NUM_IRQS];
MemoryRegion *sysmem = get_system_memory();
MemoryRegion *secure_sysmem = NULL;
@@ -1210,7 +1236,6 @@ static void machvirt_init(MachineState *machine)
CPUClass *cc;
Error *err = NULL;
bool firmware_loaded = bios_name || drive_get(IF_PFLASH, 0, 0);
- uint8_t clustersz;
if (!cpu_model) {
cpu_model = "cortex-a15";
@@ -1263,10 +1288,8 @@ static void machvirt_init(MachineState *machine)
*/
if (vms->gic_version == 3) {
virt_max_cpus = vms->memmap[VIRT_GIC_REDIST].size / 0x20000;
- clustersz = GICV3_TARGETLIST_BITS;
} else {
virt_max_cpus = GIC_NCPU;
- clustersz = GIC_TARGETLIST_BITS;
}
if (max_cpus > virt_max_cpus) {
@@ -1324,21 +1347,35 @@ static void machvirt_init(MachineState *machine)
exit(1);
}
- for (n = 0; n < smp_cpus; n++) {
- Object *cpuobj = object_new(typename);
- if (!vmc->disallow_affinity_adjustment) {
- /* Adjust MPIDR like 64-bit KVM hosts, which incorporate the
- * GIC's target-list limitations. 32-bit KVM hosts currently
- * always create clusters of 4 CPUs, but that is expected to
- * change when they gain support for gicv3. When KVM is enabled
- * it will override the changes we make here, therefore our
- * purposes are to make TCG consistent (with 64-bit KVM hosts)
- * and to improve SGI efficiency.
- */
- uint8_t aff1 = n / clustersz;
- uint8_t aff0 = n % clustersz;
- object_property_set_int(cpuobj, (aff1 << ARM_AFF1_SHIFT) | aff0,
- "mp-affinity", NULL);
+ possible_cpus = mc->possible_cpu_arch_ids(machine);
+ for (n = 0; n < possible_cpus->len; n++) {
+ Object *cpuobj;
+ CPUState *cs;
+ int node_id;
+
+ if (n >= smp_cpus) {
+ break;
+ }
+
+ cpuobj = object_new(typename);
+ object_property_set_int(cpuobj, possible_cpus->cpus[n].arch_id,
+ "mp-affinity", NULL);
+
+ cs = CPU(cpuobj);
+ cs->cpu_index = n;
+
+ node_id = possible_cpus->cpus[cs->cpu_index].props.node_id;
+ if (!possible_cpus->cpus[cs->cpu_index].props.has_node_id) {
+ /* by default CPUState::numa_node was 0 if it's not set via CLI
+ * keep it this way for now but in future we probably should
+ * refuse to start up with incomplete numa mapping */
+ node_id = 0;
+ }
+ if (cs->numa_node == CPU_UNSET_NUMA_NODE_ID) {
+ cs->numa_node = node_id;
+ } else {
+ /* CPU isn't device_add compatible yet, this shouldn't happen */
+ error_setg(&error_abort, "user set node-id not implemented");
}
if (!vms->secure) {
@@ -1518,6 +1555,46 @@ static void virt_set_gic_version(Object *obj, const char *value, Error **errp)
}
}
+static CpuInstanceProperties
+virt_cpu_index_to_props(MachineState *ms, unsigned cpu_index)
+{
+ MachineClass *mc = MACHINE_GET_CLASS(ms);
+ const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms);
+
+ assert(cpu_index < possible_cpus->len);
+ return possible_cpus->cpus[cpu_index].props;
+}
+
+static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
+{
+ int n;
+ VirtMachineState *vms = VIRT_MACHINE(ms);
+
+ if (ms->possible_cpus) {
+ assert(ms->possible_cpus->len == max_cpus);
+ return ms->possible_cpus;
+ }
+
+ ms->possible_cpus = g_malloc0(sizeof(CPUArchIdList) +
+ sizeof(CPUArchId) * max_cpus);
+ ms->possible_cpus->len = max_cpus;
+ for (n = 0; n < ms->possible_cpus->len; n++) {
+ ms->possible_cpus->cpus[n].arch_id =
+ virt_cpu_mp_affinity(vms, n);
+ ms->possible_cpus->cpus[n].props.has_thread_id = true;
+ ms->possible_cpus->cpus[n].props.thread_id = n;
+
+ /* default distribution of CPUs over NUMA nodes */
+ if (nb_numa_nodes) {
+ /* preset values but do not enable them i.e. 'has_node_id = false',
+ * numa init code will enable them later if manual mapping wasn't
+ * present on CLI */
+ ms->possible_cpus->cpus[n].props.node_id = n % nb_numa_nodes;
+ }
+ }
+ return ms->possible_cpus;
+}
+
static void virt_machine_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
@@ -1534,6 +1611,8 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
mc->pci_allow_0_address = true;
/* We know we will never create a pre-ARMv7 CPU which needs 1K pages */
mc->minimum_page_bits = 12;
+ mc->possible_cpu_arch_ids = virt_possible_cpu_arch_ids;
+ mc->cpu_index_to_instance_props = virt_cpu_index_to_props;
}
static const TypeInfo virt_machine_info = {
diff --git a/hw/audio/marvell_88w8618.c b/hw/audio/marvell_88w8618.c
index 511b004287..4f65f8c199 100644
--- a/hw/audio/marvell_88w8618.c
+++ b/hw/audio/marvell_88w8618.c
@@ -292,7 +292,7 @@ static void mv88w8618_audio_class_init(ObjectClass *klass, void *data)
dc->vmsd = &mv88w8618_audio_vmsd;
dc->props = mv88w8618_audio_properties;
/* Reason: pointer property "wm8750" */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo mv88w8618_audio_info = {
diff --git a/hw/audio/pcspk.c b/hw/audio/pcspk.c
index 798002277b..9b99358d87 100644
--- a/hw/audio/pcspk.c
+++ b/hw/audio/pcspk.c
@@ -223,7 +223,7 @@ static void pcspk_class_initfn(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_spk;
dc->props = pcspk_properties;
/* Reason: realize sets global pcspk_state */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo pcspk_info = {
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index ae303d44e5..7428db9f0c 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -227,6 +227,29 @@ static uint16_t nvme_flush(NvmeCtrl *n, NvmeNamespace *ns, NvmeCmd *cmd,
return NVME_NO_COMPLETE;
}
+static uint16_t nvme_write_zeros(NvmeCtrl *n, NvmeNamespace *ns, NvmeCmd *cmd,
+ NvmeRequest *req)
+{
+ NvmeRwCmd *rw = (NvmeRwCmd *)cmd;
+ const uint8_t lba_index = NVME_ID_NS_FLBAS_INDEX(ns->id_ns.flbas);
+ const uint8_t data_shift = ns->id_ns.lbaf[lba_index].ds;
+ uint64_t slba = le64_to_cpu(rw->slba);
+ uint32_t nlb = le16_to_cpu(rw->nlb) + 1;
+ uint64_t aio_slba = slba << (data_shift - BDRV_SECTOR_BITS);
+ uint32_t aio_nlb = nlb << (data_shift - BDRV_SECTOR_BITS);
+
+ if (slba + nlb > ns->id_ns.nsze) {
+ return NVME_LBA_RANGE | NVME_DNR;
+ }
+
+ req->has_sg = false;
+ block_acct_start(blk_get_stats(n->conf.blk), &req->acct, 0,
+ BLOCK_ACCT_WRITE);
+ req->aiocb = blk_aio_pwrite_zeroes(n->conf.blk, aio_slba, aio_nlb,
+ BDRV_REQ_MAY_UNMAP, nvme_rw_cb, req);
+ return NVME_NO_COMPLETE;
+}
+
static uint16_t nvme_rw(NvmeCtrl *n, NvmeNamespace *ns, NvmeCmd *cmd,
NvmeRequest *req)
{
@@ -279,6 +302,8 @@ static uint16_t nvme_io_cmd(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req)
switch (cmd->opcode) {
case NVME_CMD_FLUSH:
return nvme_flush(n, ns, cmd, req);
+ case NVME_CMD_WRITE_ZEROS:
+ return nvme_write_zeros(n, ns, cmd, req);
case NVME_CMD_WRITE:
case NVME_CMD_READ:
return nvme_rw(n, ns, cmd, req);
@@ -895,6 +920,7 @@ static int nvme_init(PCIDevice *pci_dev)
id->sqes = (0x6 << 4) | 0x6;
id->cqes = (0x4 << 4) | 0x4;
id->nn = cpu_to_le32(n->num_namespaces);
+ id->oncs = cpu_to_le16(NVME_ONCS_WRITE_ZEROS);
id->psd[0].mp = cpu_to_le16(0x9c4);
id->psd[0].enlat = cpu_to_le32(0x10);
id->psd[0].exlat = cpu_to_le32(0x4);
diff --git a/hw/block/nvme.h b/hw/block/nvme.h
index 8fb0c10756..a0d15649f9 100644
--- a/hw/block/nvme.h
+++ b/hw/block/nvme.h
@@ -179,6 +179,7 @@ enum NvmeIoCommands {
NVME_CMD_READ = 0x02,
NVME_CMD_WRITE_UNCOR = 0x04,
NVME_CMD_COMPARE = 0x05,
+ NVME_CMD_WRITE_ZEROS = 0x08,
NVME_CMD_DSM = 0x09,
};
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 98c16a7a9a..604d37dfc8 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -42,9 +42,7 @@ static void virtio_blk_init_request(VirtIOBlock *s, VirtQueue *vq,
static void virtio_blk_free_request(VirtIOBlockReq *req)
{
- if (req) {
- g_free(req);
- }
+ g_free(req);
}
static void virtio_blk_req_complete(VirtIOBlockReq *req, unsigned char status)
diff --git a/hw/core/generic-loader.c b/hw/core/generic-loader.c
index 58f1f02902..46012673c3 100644
--- a/hw/core/generic-loader.c
+++ b/hw/core/generic-loader.c
@@ -137,20 +137,21 @@ static void generic_loader_realize(DeviceState *dev, Error **errp)
#endif
if (s->file) {
+ AddressSpace *as = s->cpu ? s->cpu->as : NULL;
+
if (!s->force_raw) {
size = load_elf_as(s->file, NULL, NULL, &entry, NULL, NULL,
- big_endian, 0, 0, 0, s->cpu->as);
+ big_endian, 0, 0, 0, as);
if (size < 0) {
size = load_uimage_as(s->file, &entry, NULL, NULL, NULL, NULL,
- s->cpu->as);
+ as);
}
}
if (size < 0 || s->force_raw) {
/* Default to the maximum size being the machine's ram size */
- size = load_image_targphys_as(s->file, s->addr, ram_size,
- s->cpu->as);
+ size = load_image_targphys_as(s->file, s->addr, ram_size, as);
} else {
s->addr = entry;
}
diff --git a/hw/core/machine.c b/hw/core/machine.c
index ada9eea483..fd6a436064 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -17,8 +17,10 @@
#include "qapi/visitor.h"
#include "hw/sysbus.h"
#include "sysemu/sysemu.h"
+#include "sysemu/numa.h"
#include "qemu/error-report.h"
#include "qemu/cutils.h"
+#include "sysemu/numa.h"
static char *machine_get_accel(Object *obj, Error **errp)
{
@@ -388,6 +390,102 @@ HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine)
return head;
}
+/**
+ * machine_set_cpu_numa_node:
+ * @machine: machine object to modify
+ * @props: specifies which cpu objects to assign to
+ * numa node specified by @props.node_id
+ * @errp: if an error occurs, a pointer to an area to store the error
+ *
+ * Associate NUMA node specified by @props.node_id with cpu slots that
+ * match socket/core/thread-ids specified by @props. It's recommended to use
+ * query-hotpluggable-cpus.props values to specify affected cpu slots,
+ * which would lead to exact 1:1 mapping of cpu slots to NUMA node.
+ *
+ * However for CLI convenience it's possible to pass in subset of properties,
+ * which would affect all cpu slots that match it.
+ * Ex for pc machine:
+ * -smp 4,cores=2,sockets=2 -numa node,nodeid=0 -numa node,nodeid=1 \
+ * -numa cpu,node-id=0,socket_id=0 \
+ * -numa cpu,node-id=1,socket_id=1
+ * will assign all child cores of socket 0 to node 0 and
+ * of socket 1 to node 1.
+ *
+ * On attempt of reassigning (already assigned) cpu slot to another NUMA node,
+ * return error.
+ * Empty subset is disallowed and function will return with error in this case.
+ */
+void machine_set_cpu_numa_node(MachineState *machine,
+ const CpuInstanceProperties *props, Error **errp)
+{
+ MachineClass *mc = MACHINE_GET_CLASS(machine);
+ bool match = false;
+ int i;
+
+ if (!mc->possible_cpu_arch_ids) {
+ error_setg(errp, "mapping of CPUs to NUMA node is not supported");
+ return;
+ }
+
+ /* disabling node mapping is not supported, forbid it */
+ assert(props->has_node_id);
+
+ /* force board to initialize possible_cpus if it hasn't been done yet */
+ mc->possible_cpu_arch_ids(machine);
+
+ for (i = 0; i < machine->possible_cpus->len; i++) {
+ CPUArchId *slot = &machine->possible_cpus->cpus[i];
+
+ /* reject unsupported by board properties */
+ if (props->has_thread_id && !slot->props.has_thread_id) {
+ error_setg(errp, "thread-id is not supported");
+ return;
+ }
+
+ if (props->has_core_id && !slot->props.has_core_id) {
+ error_setg(errp, "core-id is not supported");
+ return;
+ }
+
+ if (props->has_socket_id && !slot->props.has_socket_id) {
+ error_setg(errp, "socket-id is not supported");
+ return;
+ }
+
+ /* skip slots with explicit mismatch */
+ if (props->has_thread_id && props->thread_id != slot->props.thread_id) {
+ continue;
+ }
+
+ if (props->has_core_id && props->core_id != slot->props.core_id) {
+ continue;
+ }
+
+ if (props->has_socket_id && props->socket_id != slot->props.socket_id) {
+ continue;
+ }
+
+ /* reject assignment if slot is already assigned, for compatibility
+ * of legacy cpu_index mapping with SPAPR core based mapping do not
+ * error out if cpu thread and matched core have the same node-id */
+ if (slot->props.has_node_id &&
+ slot->props.node_id != props->node_id) {
+ error_setg(errp, "CPU is already assigned to node-id: %" PRId64,
+ slot->props.node_id);
+ return;
+ }
+
+ /* assign slot to node as it's matched '-numa cpu' key */
+ match = true;
+ slot->props.node_id = props->node_id;
+ slot->props.has_node_id = props->has_node_id;
+ }
+
+ if (!match) {
+ error_setg(errp, "no match found");
+ }
+}
+
static void machine_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
@@ -400,6 +498,7 @@ static void machine_class_init(ObjectClass *oc, void *data)
* On Linux, each node's border has to be 8MB aligned
*/
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);
@@ -580,6 +679,69 @@ bool machine_mem_merge(MachineState *machine)
return machine->mem_merge;
}
+static char *cpu_slot_to_string(const CPUArchId *cpu)
+{
+ GString *s = g_string_new(NULL);
+ if (cpu->props.has_socket_id) {
+ g_string_append_printf(s, "socket-id: %"PRId64, cpu->props.socket_id);
+ }
+ if (cpu->props.has_core_id) {
+ if (s->len) {
+ g_string_append_printf(s, ", ");
+ }
+ g_string_append_printf(s, "core-id: %"PRId64, cpu->props.core_id);
+ }
+ if (cpu->props.has_thread_id) {
+ if (s->len) {
+ g_string_append_printf(s, ", ");
+ }
+ g_string_append_printf(s, "thread-id: %"PRId64, cpu->props.thread_id);
+ }
+ return g_string_free(s, false);
+}
+
+static void machine_numa_validate(MachineState *machine)
+{
+ int i;
+ GString *s = g_string_new(NULL);
+ MachineClass *mc = MACHINE_GET_CLASS(machine);
+ const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(machine);
+
+ assert(nb_numa_nodes);
+ for (i = 0; i < possible_cpus->len; i++) {
+ const CPUArchId *cpu_slot = &possible_cpus->cpus[i];
+
+ /* at this point numa mappings are initilized by CLI options
+ * or with default mappings so it's sufficient to list
+ * all not yet mapped CPUs here */
+ /* TODO: make it hard error in future */
+ if (!cpu_slot->props.has_node_id) {
+ char *cpu_str = cpu_slot_to_string(cpu_slot);
+ g_string_append_printf(s, "%sCPU %d [%s]", s->len ? ", " : "", i,
+ cpu_str);
+ g_free(cpu_str);
+ }
+ }
+ if (s->len) {
+ error_report("warning: CPU(s) not present in any NUMA nodes: %s",
+ s->str);
+ error_report("warning: All CPU(s) up to maxcpus should be described "
+ "in NUMA config, ability to start up with partial NUMA "
+ "mappings is obsoleted and will be removed in future");
+ }
+ g_string_free(s, true);
+}
+
+void machine_run_board_init(MachineState *machine)
+{
+ MachineClass *machine_class = MACHINE_GET_CLASS(machine);
+
+ if (nb_numa_nodes) {
+ machine_numa_validate(machine);
+ }
+ machine_class->init(machine);
+}
+
static void machine_class_finalize(ObjectClass *klass, void *data)
{
MachineClass *mc = MACHINE_CLASS(klass);
diff --git a/hw/core/or-irq.c b/hw/core/or-irq.c
index 1485d5b285..f9d76c4641 100644
--- a/hw/core/or-irq.c
+++ b/hw/core/or-irq.c
@@ -91,7 +91,7 @@ static void or_irq_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_or_irq;
/* Reason: Needs to be wired up to work, e.g. see stm32f205_soc.c */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo or_irq_type_info = {
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 02b632f6b3..1863db9d0a 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -1118,6 +1118,7 @@ static void device_class_init(ObjectClass *class, void *data)
* should override it in their class_init()
*/
dc->hotpluggable = true;
+ dc->user_creatable = true;
}
void device_reset(DeviceState *dev)
diff --git a/hw/core/register.c b/hw/core/register.c
index dc335a79a9..da38ef3a54 100644
--- a/hw/core/register.c
+++ b/hw/core/register.c
@@ -288,7 +288,7 @@ static void register_class_init(ObjectClass *oc, void *data)
DeviceClass *dc = DEVICE_CLASS(oc);
/* Reason: needs to be wired up to work */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo register_info = {
diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c
index c0f560b289..5d0887f499 100644
--- a/hw/core/sysbus.c
+++ b/hw/core/sysbus.c
@@ -326,6 +326,17 @@ static void sysbus_device_class_init(ObjectClass *klass, void *data)
DeviceClass *k = DEVICE_CLASS(klass);
k->init = sysbus_device_init;
k->bus_type = TYPE_SYSTEM_BUS;
+ /*
+ * device_add plugs devices into a suitable bus. For "real" buses,
+ * that actually connects the device. For sysbus, the connections
+ * need to be made separately, and device_add can't do that. The
+ * device would be left unconnected, and will probably not work
+ *
+ * However, a few machines can handle device_add/-device with
+ * a few specific sysbus devices. In those cases, the device
+ * subclass needs to override it and set user_creatable=true.
+ */
+ k->user_creatable = false;
}
static const TypeInfo sysbus_device_type_info = {
diff --git a/hw/display/cg3.c b/hw/display/cg3.c
index 7ef8a96496..1de15a1d34 100644
--- a/hw/display/cg3.c
+++ b/hw/display/cg3.c
@@ -94,7 +94,8 @@ static void cg3_update_display(void *opaque)
uint32_t dval;
int x, y, y_start;
unsigned int width, height;
- ram_addr_t page, page_min, page_max;
+ ram_addr_t page;
+ DirtyBitmapSnapshot *snap = NULL;
if (surface_bits_per_pixel(surface) != 32) {
return;
@@ -103,29 +104,32 @@ static void cg3_update_display(void *opaque)
height = s->height;
y_start = -1;
- page_min = -1;
- page_max = 0;
- page = 0;
pix = memory_region_get_ram_ptr(&s->vram_mem);
data = (uint32_t *)surface_data(surface);
- memory_region_sync_dirty_bitmap(&s->vram_mem);
+ if (!s->full_update) {
+ memory_region_sync_dirty_bitmap(&s->vram_mem);
+ snap = memory_region_snapshot_and_clear_dirty(&s->vram_mem, 0x0,
+ memory_region_size(&s->vram_mem),
+ DIRTY_MEMORY_VGA);
+ }
+
for (y = 0; y < height; y++) {
- int update = s->full_update;
+ int update;
page = (ram_addr_t)y * width;
- update |= memory_region_get_dirty(&s->vram_mem, page, width,
- DIRTY_MEMORY_VGA);
+
+ if (s->full_update) {
+ update = 1;
+ } else {
+ update = memory_region_snapshot_get_dirty(&s->vram_mem, snap, page,
+ width);
+ }
+
if (update) {
if (y_start < 0) {
y_start = y;
}
- if (page < page_min) {
- page_min = page;
- }
- if (page > page_max) {
- page_max = page;
- }
for (x = 0; x < width; x++) {
dval = *pix++;
@@ -134,7 +138,7 @@ static void cg3_update_display(void *opaque)
}
} else {
if (y_start >= 0) {
- dpy_gfx_update(s->con, 0, y_start, s->width, y - y_start);
+ dpy_gfx_update(s->con, 0, y_start, width, y - y_start);
y_start = -1;
}
pix += width;
@@ -143,17 +147,14 @@ static void cg3_update_display(void *opaque)
}
s->full_update = 0;
if (y_start >= 0) {
- dpy_gfx_update(s->con, 0, y_start, s->width, y - y_start);
- }
- if (page_max >= page_min) {
- memory_region_reset_dirty(&s->vram_mem,
- page_min, page_max - page_min, DIRTY_MEMORY_VGA);
+ dpy_gfx_update(s->con, 0, y_start, width, y - y_start);
}
/* vsync interrupt? */
if (s->regs[0] & CG3_CR_ENABLE_INTS) {
s->regs[1] |= CG3_SR_PENDING_INT;
qemu_irq_raise(s->irq);
}
+ g_free(snap);
}
static void cg3_invalidate_display(void *opaque)
diff --git a/hw/display/jazz_led.c b/hw/display/jazz_led.c
index b72fdb1717..3c97d56434 100644
--- a/hw/display/jazz_led.c
+++ b/hw/display/jazz_led.c
@@ -227,13 +227,13 @@ static void jazz_led_invalidate_display(void *opaque)
static void jazz_led_text_update(void *opaque, console_ch_t *chardata)
{
LedState *s = opaque;
- char buf[2];
+ char buf[3];
dpy_text_cursor(s->con, -1, -1);
qemu_console_resize(s->con, 2, 1);
/* TODO: draw the segments */
- snprintf(buf, 2, "%02hhx\n", s->segments);
+ snprintf(buf, 3, "%02hhx", s->segments);
console_write_ch(chardata++, ATTR2CHTYPE(buf[0], QEMU_COLOR_BLUE,
QEMU_COLOR_BLACK, 1));
console_write_ch(chardata++, ATTR2CHTYPE(buf[1], QEMU_COLOR_BLUE,
diff --git a/hw/display/sm501.c b/hw/display/sm501.c
index 2094adbc9c..9d254ef2e1 100644
--- a/hw/display/sm501.c
+++ b/hw/display/sm501.c
@@ -1414,6 +1414,7 @@ static void sm501_update_display(void *opaque)
{
SM501State *s = (SM501State *)opaque;
DisplaySurface *surface = qemu_console_surface(s->con);
+ DirtyBitmapSnapshot *snap;
int y, c_x = 0, c_y = 0;
int crt = (s->dc_crt_control & SM501_DC_CRT_CONTROL_SEL) ? 1 : 0;
int width = get_width(s, crt);
@@ -1425,9 +1426,7 @@ static void sm501_update_display(void *opaque)
draw_hwc_line_func *draw_hwc_line = NULL;
int full_update = 0;
int y_start = -1;
- ram_addr_t page_min = ~0l;
- ram_addr_t page_max = 0l;
- ram_addr_t offset;
+ ram_addr_t offset = 0;
uint32_t *palette;
uint8_t hwc_palette[3 * 3];
uint8_t *hwc_src = NULL;
@@ -1479,17 +1478,17 @@ static void sm501_update_display(void *opaque)
/* draw each line according to conditions */
memory_region_sync_dirty_bitmap(&s->local_mem_region);
+ snap = memory_region_snapshot_and_clear_dirty(&s->local_mem_region,
+ offset, width * height * src_bpp, DIRTY_MEMORY_VGA);
for (y = 0, offset = 0; y < height; y++, offset += width * src_bpp) {
int update, update_hwc;
- ram_addr_t page0 = offset;
- ram_addr_t page1 = offset + width * src_bpp - 1;
/* check if hardware cursor is enabled and we're within its range */
update_hwc = draw_hwc_line && c_y <= y && y < c_y + SM501_HWC_HEIGHT;
update = full_update || update_hwc;
/* check dirty flags for each line */
- update |= memory_region_get_dirty(&s->local_mem_region, page0,
- page1 - page0, DIRTY_MEMORY_VGA);
+ update |= memory_region_snapshot_get_dirty(&s->local_mem_region, snap,
+ offset, width * src_bpp);
/* draw line and change status */
if (update) {
@@ -1507,12 +1506,6 @@ static void sm501_update_display(void *opaque)
if (y_start < 0) {
y_start = y;
}
- if (page0 < page_min) {
- page_min = page0;
- }
- if (page1 > page_max) {
- page_max = page1;
- }
} else {
if (y_start >= 0) {
/* flush to display */
@@ -1521,18 +1514,12 @@ static void sm501_update_display(void *opaque)
}
}
}
+ g_free(snap);
/* complete flush to display */
if (y_start >= 0) {
dpy_gfx_update(s->con, 0, y_start, width, y - y_start);
}
-
- /* clear dirty flags */
- if (page_min != ~0l) {
- memory_region_reset_dirty(&s->local_mem_region,
- page_min, page_max + TARGET_PAGE_SIZE,
- DIRTY_MEMORY_VGA);
- }
}
static const GraphicHwOps sm501_ops = {
diff --git a/hw/display/tcx.c b/hw/display/tcx.c
index 0e66dcd055..6593c1d6af 100644
--- a/hw/display/tcx.c
+++ b/hw/display/tcx.c
@@ -104,36 +104,23 @@ static void tcx_set_dirty(TCXState *s, ram_addr_t addr, int len)
}
}
-static int tcx_check_dirty(TCXState *s, ram_addr_t addr, int len)
+static int tcx_check_dirty(TCXState *s, DirtyBitmapSnapshot *snap,
+ ram_addr_t addr, int len)
{
int ret;
- ret = memory_region_get_dirty(&s->vram_mem, addr, len, DIRTY_MEMORY_VGA);
+ ret = memory_region_snapshot_get_dirty(&s->vram_mem, snap, addr, len);
if (s->depth == 24) {
- ret |= memory_region_get_dirty(&s->vram_mem,
- s->vram24_offset + addr * 4, len * 4,
- DIRTY_MEMORY_VGA);
- ret |= memory_region_get_dirty(&s->vram_mem,
- s->cplane_offset + addr * 4, len * 4,
- DIRTY_MEMORY_VGA);
+ ret |= memory_region_snapshot_get_dirty(&s->vram_mem, snap,
+ s->vram24_offset + addr * 4, len * 4);
+ ret |= memory_region_snapshot_get_dirty(&s->vram_mem, snap,
+ s->cplane_offset + addr * 4, len * 4);
}
return ret;
}
-static void tcx_reset_dirty(TCXState *s, ram_addr_t addr, int len)
-{
- memory_region_reset_dirty(&s->vram_mem, addr, len, DIRTY_MEMORY_VGA);
-
- if (s->depth == 24) {
- memory_region_reset_dirty(&s->vram_mem, s->vram24_offset + addr * 4,
- len * 4, DIRTY_MEMORY_VGA);
- memory_region_reset_dirty(&s->vram_mem, s->cplane_offset + addr * 4,
- len * 4, DIRTY_MEMORY_VGA);
- }
-}
-
static void update_palette_entries(TCXState *s, int start, int end)
{
DisplaySurface *surface = qemu_console_surface(s->con);
@@ -233,7 +220,8 @@ static void tcx_update_display(void *opaque)
{
TCXState *ts = opaque;
DisplaySurface *surface = qemu_console_surface(ts->con);
- ram_addr_t page, page_min, page_max;
+ ram_addr_t page;
+ DirtyBitmapSnapshot *snap = NULL;
int y, y_start, dd, ds;
uint8_t *d, *s;
@@ -243,22 +231,20 @@ static void tcx_update_display(void *opaque)
page = 0;
y_start = -1;
- page_min = -1;
- page_max = 0;
d = surface_data(surface);
s = ts->vram;
dd = surface_stride(surface);
ds = 1024;
memory_region_sync_dirty_bitmap(&ts->vram_mem);
+ snap = memory_region_snapshot_and_clear_dirty(&ts->vram_mem, 0x0,
+ memory_region_size(&ts->vram_mem),
+ DIRTY_MEMORY_VGA);
+
for (y = 0; y < ts->height; y++, page += ds) {
- if (tcx_check_dirty(ts, page, ds)) {
+ if (tcx_check_dirty(ts, snap, page, ds)) {
if (y_start < 0)
y_start = y;
- if (page < page_min)
- page_min = page;
- if (page > page_max)
- page_max = page;
tcx_draw_line32(ts, d, s, ts->width);
if (y >= ts->cursy && y < ts->cursy + 32 && ts->cursx < ts->width) {
@@ -280,17 +266,15 @@ static void tcx_update_display(void *opaque)
dpy_gfx_update(ts->con, 0, y_start,
ts->width, y - y_start);
}
- /* reset modified pages */
- if (page_max >= page_min) {
- tcx_reset_dirty(ts, page_min, page_max - page_min);
- }
+ g_free(snap);
}
static void tcx24_update_display(void *opaque)
{
TCXState *ts = opaque;
DisplaySurface *surface = qemu_console_surface(ts->con);
- ram_addr_t page, page_min, page_max;
+ ram_addr_t page;
+ DirtyBitmapSnapshot *snap = NULL;
int y, y_start, dd, ds;
uint8_t *d, *s;
uint32_t *cptr, *s24;
@@ -301,8 +285,6 @@ static void tcx24_update_display(void *opaque)
page = 0;
y_start = -1;
- page_min = -1;
- page_max = 0;
d = surface_data(surface);
s = ts->vram;
s24 = ts->vram24;
@@ -311,14 +293,15 @@ static void tcx24_update_display(void *opaque)
ds = 1024;
memory_region_sync_dirty_bitmap(&ts->vram_mem);
+ snap = memory_region_snapshot_and_clear_dirty(&ts->vram_mem, 0x0,
+ memory_region_size(&ts->vram_mem),
+ DIRTY_MEMORY_VGA);
+
for (y = 0; y < ts->height; y++, page += ds) {
- if (tcx_check_dirty(ts, page, ds)) {
+ if (tcx_check_dirty(ts, snap, page, ds)) {
if (y_start < 0)
y_start = y;
- if (page < page_min)
- page_min = page;
- if (page > page_max)
- page_max = page;
+
tcx24_draw_line32(ts, d, s, ts->width, cptr, s24);
if (y >= ts->cursy && y < ts->cursy+32 && ts->cursx < ts->width) {
tcx_draw_cursor32(ts, d, y, ts->width);
@@ -341,10 +324,7 @@ static void tcx24_update_display(void *opaque)
dpy_gfx_update(ts->con, 0, y_start,
ts->width, y - y_start);
}
- /* reset modified pages */
- if (page_max >= page_min) {
- tcx_reset_dirty(ts, page_min, page_max - page_min);
- }
+ g_free(snap);
}
static void tcx_invalidate_display(void *opaque)
diff --git a/hw/display/vga.c b/hw/display/vga.c
index b2516c8d21..dcc95f88e2 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -1630,7 +1630,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
if (!full_update) {
vga_sync_dirty_bitmap(s);
snap = memory_region_snapshot_and_clear_dirty(&s->vram, addr1,
- bwidth * height,
+ line_offset * height,
DIRTY_MEMORY_VGA);
}
diff --git a/hw/display/virtio-gpu-3d.c b/hw/display/virtio-gpu-3d.c
index f49b7fe8cd..8c106a662d 100644
--- a/hw/display/virtio-gpu-3d.c
+++ b/hw/display/virtio-gpu-3d.c
@@ -600,6 +600,22 @@ void virtio_gpu_virgl_reset(VirtIOGPU *g)
}
}
+void virtio_gpu_gl_block(void *opaque, bool block)
+{
+ VirtIOGPU *g = opaque;
+
+ if (block) {
+ g->renderer_blocked++;
+ } else {
+ g->renderer_blocked--;
+ }
+ assert(g->renderer_blocked >= 0);
+
+ if (g->renderer_blocked == 0) {
+ virtio_gpu_process_cmdq(g);
+ }
+}
+
int virtio_gpu_virgl_init(VirtIOGPU *g)
{
int ret;
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index e1056f34df..cfb5dfa336 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -929,28 +929,14 @@ static int virtio_gpu_ui_info(void *opaque, uint32_t idx, QemuUIInfo *info)
return 0;
}
-static void virtio_gpu_gl_block(void *opaque, bool block)
-{
- VirtIOGPU *g = opaque;
-
- if (block) {
- g->renderer_blocked++;
- } else {
- g->renderer_blocked--;
- }
- assert(g->renderer_blocked >= 0);
-
- if (g->renderer_blocked == 0) {
- virtio_gpu_process_cmdq(g);
- }
-}
-
const GraphicHwOps virtio_gpu_ops = {
.invalidate = virtio_gpu_invalidate_display,
.gfx_update = virtio_gpu_update_display,
.text_update = virtio_gpu_text_update,
.ui_info = virtio_gpu_ui_info,
+#ifdef CONFIG_VIRGL
.gl_block = virtio_gpu_gl_block,
+#endif
};
static const VMStateDescription vmstate_virtio_gpu_scanout = {
diff --git a/hw/dma/i8257.c b/hw/dma/i8257.c
index 8bd82e8bc8..bd23e893bf 100644
--- a/hw/dma/i8257.c
+++ b/hw/dma/i8257.c
@@ -601,7 +601,7 @@ static void i8257_class_init(ObjectClass *klass, void *data)
idc->schedule = i8257_dma_schedule;
idc->register_channel = i8257_dma_register_channel;
/* Reason: needs to be wired up by isa_bus_dma() to work */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo i8257_info = {
diff --git a/hw/dma/sparc32_dma.c b/hw/dma/sparc32_dma.c
index 9d545e412e..9c6bdc6295 100644
--- a/hw/dma/sparc32_dma.c
+++ b/hw/dma/sparc32_dma.c
@@ -305,7 +305,7 @@ static void sparc32_dma_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_dma;
dc->props = sparc32_dma_properties;
/* Reason: pointer property "iommu_opaque" */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo sparc32_dma_info = {
diff --git a/hw/gpio/omap_gpio.c b/hw/gpio/omap_gpio.c
index dabef4a119..1df394eb12 100644
--- a/hw/gpio/omap_gpio.c
+++ b/hw/gpio/omap_gpio.c
@@ -773,7 +773,7 @@ static void omap_gpio_class_init(ObjectClass *klass, void *data)
dc->reset = omap_gpif_reset;
dc->props = omap_gpio_properties;
/* Reason: pointer property "clk" */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo omap_gpio_info = {
@@ -804,7 +804,7 @@ static void omap2_gpio_class_init(ObjectClass *klass, void *data)
dc->reset = omap2_gpif_reset;
dc->props = omap2_gpio_properties;
/* Reason: pointer properties "iclk", "fclk0", ..., "fclk5" */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo omap2_gpio_info = {
diff --git a/hw/i2c/omap_i2c.c b/hw/i2c/omap_i2c.c
index f7c92ea00c..f6e80bee25 100644
--- a/hw/i2c/omap_i2c.c
+++ b/hw/i2c/omap_i2c.c
@@ -491,7 +491,7 @@ static void omap_i2c_class_init(ObjectClass *klass, void *data)
dc->props = omap_i2c_properties;
dc->reset = omap_i2c_reset;
/* Reason: pointer properties "iclk", "fclk" */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
dc->realize = omap_i2c_realize;
}
diff --git a/hw/i2c/smbus_eeprom.c b/hw/i2c/smbus_eeprom.c
index 5b7bd891bc..b13ec0fe7a 100644
--- a/hw/i2c/smbus_eeprom.c
+++ b/hw/i2c/smbus_eeprom.c
@@ -123,7 +123,7 @@ static void smbus_eeprom_class_initfn(ObjectClass *klass, void *data)
sc->read_data = eeprom_read_data;
dc->props = smbus_eeprom_properties;
/* Reason: pointer property "data" */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo smbus_eeprom_info = {
diff --git a/hw/i2c/smbus_ich9.c b/hw/i2c/smbus_ich9.c
index 48fab22625..ea51e09186 100644
--- a/hw/i2c/smbus_ich9.c
+++ b/hw/i2c/smbus_ich9.c
@@ -103,7 +103,7 @@ static void ich9_smb_class_init(ObjectClass *klass, void *data)
* Reason: part of ICH9 southbridge, needs to be wired up by
* pc_q35_init()
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
I2CBus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base)
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index c75f73ebb1..afcadacd2e 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -2335,7 +2335,8 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
srat->reserved1 = cpu_to_le32(1);
for (i = 0; i < apic_ids->len; i++) {
- int j = numa_get_node_for_cpu(i);
+ int node_id = apic_ids->cpus[i].props.has_node_id ?
+ apic_ids->cpus[i].props.node_id : 0;
uint32_t apic_id = apic_ids->cpus[i].arch_id;
if (apic_id < 255) {
@@ -2345,9 +2346,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
core->type = ACPI_SRAT_PROCESSOR_APIC;
core->length = sizeof(*core);
core->local_apic_id = apic_id;
- if (j < nb_numa_nodes) {
- core->proximity_lo = j;
- }
+ core->proximity_lo = node_id;
memset(core->proximity_hi, 0, 3);
core->local_sapic_eid = 0;
core->flags = cpu_to_le32(1);
@@ -2358,9 +2357,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
core->type = ACPI_SRAT_PROCESSOR_x2APIC;
core->length = sizeof(*core);
core->x2apic_id = cpu_to_le32(apic_id);
- if (j < nb_numa_nodes) {
- core->proximity_domain = cpu_to_le32(j);
- }
+ core->proximity_domain = cpu_to_le32(node_id);
core->flags = cpu_to_le32(1);
}
}
@@ -2707,6 +2704,10 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine)
if (pcms->numa_nodes) {
acpi_add_table(table_offsets, tables_blob);
build_srat(tables_blob, tables->linker, machine);
+ if (have_numa_distance) {
+ acpi_add_table(table_offsets, tables_blob);
+ build_slit(tables_blob, tables->linker);
+ }
}
if (acpi_get_mcfg(&mcfg)) {
acpi_add_table(table_offsets, tables_blob);
diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c
index 516ebae952..329058dac8 100644
--- a/hw/i386/amd_iommu.c
+++ b/hw/i386/amd_iommu.c
@@ -1199,6 +1199,8 @@ static void amdvi_class_init(ObjectClass *klass, void* data)
dc->vmsd = &vmstate_amdvi;
dc->hotpluggable = false;
dc_class->realize = amdvi_realize;
+ /* Supported by the pc-q35-* machine types */
+ dc->user_creatable = true;
}
static const TypeInfo amdvi = {
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index a12b1761f5..9ba2162cd9 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -3019,6 +3019,8 @@ static void vtd_class_init(ObjectClass *klass, void *data)
dc->hotpluggable = false;
x86_class->realize = vtd_realize;
x86_class->int_remap = vtd_int_remap;
+ /* Supported by the pc-q35-* machine types */
+ dc->user_creatable = true;
}
static const TypeInfo vtd_info = {
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 8063241140..816bfa872c 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -597,7 +597,7 @@ static void port92_class_initfn(ObjectClass *klass, void *data)
* wiring: its A20 output line needs to be wired up by
* port92_init().
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo port92_info = {
@@ -747,7 +747,9 @@ static FWCfgState *bochs_bios_init(AddressSpace *as, PCMachineState *pcms)
{
FWCfgState *fw_cfg;
uint64_t *numa_fw_cfg;
- int i, j;
+ int i;
+ const CPUArchIdList *cpus;
+ MachineClass *mc = MACHINE_GET_CLASS(pcms);
fw_cfg = fw_cfg_init_io_dma(FW_CFG_IO_BASE, FW_CFG_IO_BASE + 4, as);
fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, pcms->boot_cpus);
@@ -782,12 +784,12 @@ static FWCfgState *bochs_bios_init(AddressSpace *as, PCMachineState *pcms)
*/
numa_fw_cfg = g_new0(uint64_t, 1 + pcms->apic_id_limit + nb_numa_nodes);
numa_fw_cfg[0] = cpu_to_le64(nb_numa_nodes);
- for (i = 0; i < max_cpus; i++) {
- unsigned int apic_id = x86_cpu_apic_id_from_index(i);
+ cpus = mc->possible_cpu_arch_ids(MACHINE(pcms));
+ for (i = 0; i < cpus->len; i++) {
+ unsigned int apic_id = cpus->cpus[i].arch_id;
assert(apic_id < pcms->apic_id_limit);
- j = numa_get_node_for_cpu(i);
- if (j < nb_numa_nodes) {
- numa_fw_cfg[apic_id + 1] = cpu_to_le64(j);
+ if (cpus->cpus[i].props.has_node_id) {
+ numa_fw_cfg[apic_id + 1] = cpu_to_le64(cpus->cpus[i].props.node_id);
}
}
for (i = 0; i < nb_numa_nodes; i++) {
@@ -1891,6 +1893,7 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
int idx;
+ int node_id;
CPUState *cs;
CPUArchId *cpu_slot;
X86CPUTopoInfo topo;
@@ -1980,6 +1983,22 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
cs = CPU(cpu);
cs->cpu_index = idx;
+
+ node_id = cpu_slot->props.node_id;
+ if (!cpu_slot->props.has_node_id) {
+ /* by default CPUState::numa_node was 0 if it's not set via CLI
+ * keep it this way for now but in future we probably should
+ * refuse to start up with incomplete numa mapping */
+ node_id = 0;
+ }
+ if (cs->numa_node == CPU_UNSET_NUMA_NODE_ID) {
+ cs->numa_node = node_id;
+ } else if (cs->numa_node != node_id) {
+ error_setg(errp, "node-id %d must match numa node specified"
+ "with -numa option for cpu-index %d",
+ cs->numa_node, cs->cpu_index);
+ return;
+ }
}
static void pc_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
@@ -2241,12 +2260,14 @@ static void pc_machine_reset(void)
}
}
-static unsigned pc_cpu_index_to_socket_id(unsigned cpu_index)
+static CpuInstanceProperties
+pc_cpu_index_to_props(MachineState *ms, unsigned cpu_index)
{
- X86CPUTopoInfo topo;
- x86_topo_ids_from_idx(smp_cores, smp_threads, cpu_index,
- &topo);
- return topo.pkg_id;
+ MachineClass *mc = MACHINE_GET_CLASS(ms);
+ const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms);
+
+ assert(cpu_index < possible_cpus->len);
+ return possible_cpus->cpus[cpu_index].props;
}
static const CPUArchIdList *pc_possible_cpu_arch_ids(MachineState *ms)
@@ -2278,6 +2299,15 @@ static const CPUArchIdList *pc_possible_cpu_arch_ids(MachineState *ms)
ms->possible_cpus->cpus[i].props.core_id = topo.core_id;
ms->possible_cpus->cpus[i].props.has_thread_id = true;
ms->possible_cpus->cpus[i].props.thread_id = topo.smt_id;
+
+ /* default distribution of CPUs over NUMA nodes */
+ if (nb_numa_nodes) {
+ /* preset values but do not enable them i.e. 'has_node_id = false',
+ * numa init code will enable them later if manual mapping wasn't
+ * present on CLI */
+ ms->possible_cpus->cpus[i].props.node_id =
+ topo.pkg_id % nb_numa_nodes;
+ }
}
return ms->possible_cpus;
}
@@ -2321,7 +2351,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
pcmc->save_tsc_khz = true;
pcmc->linuxboot_dma_enabled = true;
mc->get_hotplug_handler = pc_get_hotpug_handler;
- mc->cpu_index_to_socket_id = pc_cpu_index_to_socket_id;
+ mc->cpu_index_to_instance_props = pc_cpu_index_to_props;
mc->possible_cpu_arch_ids = pc_possible_cpu_arch_ids;
mc->has_hotpluggable_cpus = true;
mc->default_boot_order = "cad";
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 8f3d85ca58..2234bd0461 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -54,6 +54,7 @@
#endif
#include "migration/migration.h"
#include "kvm_i386.h"
+#include "sysemu/numa.h"
#define MAX_IDE_BUS 2
@@ -442,6 +443,7 @@ static void pc_i440fx_2_10_machine_options(MachineClass *m)
pc_i440fx_machine_options(m);
m->alias = "pc";
m->is_default = 1;
+ m->numa_auto_assign_ram = numa_legacy_auto_assign_ram;
}
DEFINE_I440FX_MACHINE(v2_10, "pc-i440fx-2.10", NULL,
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index cf9a788ec7..f243203844 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -47,6 +47,7 @@
#include "hw/usb.h"
#include "qemu/error-report.h"
#include "migration/migration.h"
+#include "sysemu/numa.h"
/* ICH9 AHCI has 6 ports */
#define MAX_SATA_PORTS 6
@@ -305,6 +306,7 @@ static void pc_q35_2_10_machine_options(MachineClass *m)
{
pc_q35_machine_options(m);
m->alias = "q35";
+ m->numa_auto_assign_ram = numa_legacy_auto_assign_ram;
}
DEFINE_Q35_MACHINE(v2_10, "pc-q35-2.10", NULL,
diff --git a/hw/i386/xen/xen-mapcache.c b/hw/i386/xen/xen-mapcache.c
index 31debdfb2c..e60156c04f 100644
--- a/hw/i386/xen/xen-mapcache.c
+++ b/hw/i386/xen/xen-mapcache.c
@@ -62,6 +62,7 @@ typedef struct MapCacheRev {
hwaddr paddr_index;
hwaddr size;
QTAILQ_ENTRY(MapCacheRev) next;
+ bool dma;
} MapCacheRev;
typedef struct MapCache {
@@ -202,7 +203,7 @@ static void xen_remap_bucket(MapCacheEntry *entry,
}
static uint8_t *xen_map_cache_unlocked(hwaddr phys_addr, hwaddr size,
- uint8_t lock)
+ uint8_t lock, bool dma)
{
MapCacheEntry *entry, *pentry = NULL;
hwaddr address_index;
@@ -289,6 +290,7 @@ tryagain:
if (lock) {
MapCacheRev *reventry = g_malloc0(sizeof(MapCacheRev));
entry->lock++;
+ reventry->dma = dma;
reventry->vaddr_req = mapcache->last_entry->vaddr_base + address_offset;
reventry->paddr_index = mapcache->last_entry->paddr_index;
reventry->size = entry->size;
@@ -300,12 +302,12 @@ tryagain:
}
uint8_t *xen_map_cache(hwaddr phys_addr, hwaddr size,
- uint8_t lock)
+ uint8_t lock, bool dma)
{
uint8_t *p;
mapcache_lock();
- p = xen_map_cache_unlocked(phys_addr, size, lock);
+ p = xen_map_cache_unlocked(phys_addr, size, lock, dma);
mapcache_unlock();
return p;
}
@@ -426,8 +428,11 @@ void xen_invalidate_map_cache(void)
mapcache_lock();
QTAILQ_FOREACH(reventry, &mapcache->locked_entries, next) {
- DPRINTF("There should be no locked mappings at this time, "
- "but "TARGET_FMT_plx" -> %p is present\n",
+ if (!reventry->dma) {
+ continue;
+ }
+ fprintf(stderr, "Locked DMA mapping while invalidating mapcache!"
+ " "TARGET_FMT_plx" -> %p is present\n",
reventry->paddr_index, reventry->vaddr_req);
}
diff --git a/hw/input/virtio-input-hid.c b/hw/input/virtio-input-hid.c
index 3ee0c1814a..46c038110c 100644
--- a/hw/input/virtio-input-hid.c
+++ b/hw/input/virtio-input-hid.c
@@ -484,12 +484,14 @@ static struct virtio_input_config virtio_tablet_config[] = {
.select = VIRTIO_INPUT_CFG_ABS_INFO,
.subsel = ABS_X,
.size = sizeof(virtio_input_absinfo),
- .u.abs.max = const_le32(INPUT_EVENT_ABS_SIZE - 1),
+ .u.abs.min = const_le32(INPUT_EVENT_ABS_MIN),
+ .u.abs.max = const_le32(INPUT_EVENT_ABS_MAX),
},{
.select = VIRTIO_INPUT_CFG_ABS_INFO,
.subsel = ABS_Y,
.size = sizeof(virtio_input_absinfo),
- .u.abs.max = const_le32(INPUT_EVENT_ABS_SIZE - 1),
+ .u.abs.min = const_le32(INPUT_EVENT_ABS_MIN),
+ .u.abs.max = const_le32(INPUT_EVENT_ABS_MAX),
},
{ /* end of list */ },
};
diff --git a/hw/input/vmmouse.c b/hw/input/vmmouse.c
index 6d15a887c6..4747da9a8d 100644
--- a/hw/input/vmmouse.c
+++ b/hw/input/vmmouse.c
@@ -286,7 +286,7 @@ static void vmmouse_class_initfn(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_vmmouse;
dc->props = vmmouse_properties;
/* Reason: pointer property "ps2_mouse" */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo vmmouse_info = {
diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
index c3829e31b5..1ef56f8d10 100644
--- a/hw/intc/apic_common.c
+++ b/hw/intc/apic_common.c
@@ -501,7 +501,7 @@ static void apic_common_class_init(ObjectClass *klass, void *data)
* Reason: APIC and CPU need to be wired up by
* x86_cpu_apic_create()
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo apic_common_type = {
diff --git a/hw/intc/etraxfs_pic.c b/hw/intc/etraxfs_pic.c
index 64a6f4b4ba..1bfde2f09e 100644
--- a/hw/intc/etraxfs_pic.c
+++ b/hw/intc/etraxfs_pic.c
@@ -173,7 +173,7 @@ static void etraxfs_pic_class_init(ObjectClass *klass, void *data)
dc->props = etraxfs_pic_properties;
/*
* Note: pointer property "interrupt_vector" may remain null, thus
- * no need for dc->cannot_instantiate_with_device_add_yet = true;
+ * no need for dc->user_creatable = false;
*/
}
diff --git a/hw/intc/grlib_irqmp.c b/hw/intc/grlib_irqmp.c
index ac7e63f38b..94659ee256 100644
--- a/hw/intc/grlib_irqmp.c
+++ b/hw/intc/grlib_irqmp.c
@@ -360,7 +360,7 @@ static void grlib_irqmp_class_init(ObjectClass *klass, void *data)
dc->reset = grlib_irqmp_reset;
dc->props = grlib_irqmp_properties;
/* Reason: pointer properties "set_pil_in", "set_pil_in_opaque" */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
dc->realize = grlib_irqmp_realize;
}
diff --git a/hw/intc/i8259_common.c b/hw/intc/i8259_common.c
index d9a5e8b217..c2fd563b5b 100644
--- a/hw/intc/i8259_common.c
+++ b/hw/intc/i8259_common.c
@@ -144,7 +144,7 @@ static void pic_common_class_init(ObjectClass *klass, void *data)
* wiring of the slave to the master is hard-coded in device model
* code.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo pic_common_type = {
diff --git a/hw/intc/nios2_iic.c b/hw/intc/nios2_iic.c
index 190b6fdbf3..016426f964 100644
--- a/hw/intc/nios2_iic.c
+++ b/hw/intc/nios2_iic.c
@@ -80,7 +80,7 @@ static void altera_iic_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
/* Reason: needs to be wired up, e.g. by nios2_10m50_ghrd_init() */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
dc->realize = altera_iic_realize;
}
diff --git a/hw/intc/omap_intc.c b/hw/intc/omap_intc.c
index 877be67971..ccdda89dab 100644
--- a/hw/intc/omap_intc.c
+++ b/hw/intc/omap_intc.c
@@ -401,7 +401,7 @@ static void omap_intc_class_init(ObjectClass *klass, void *data)
dc->reset = omap_inth_reset;
dc->props = omap_intc_properties;
/* Reason: pointer property "clk" */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
dc->realize = omap_intc_realize;
}
@@ -656,7 +656,7 @@ static void omap2_intc_class_init(ObjectClass *klass, void *data)
dc->reset = omap_inth_reset;
dc->props = omap2_intc_properties;
/* Reason: pointer property "iclk", "fclk" */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
dc->realize = omap2_intc_realize;
}
diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index 42e0e0ef84..dd93531ae3 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -213,6 +213,7 @@ static void ics_get_kvm_state(ICSState *ics)
irq->priority = irq->saved_priority;
}
+ irq->status = 0;
if (state & KVM_XICS_PENDING) {
if (state & KVM_XICS_LEVEL_SENSITIVE) {
irq->status |= XICS_STATUS_ASSERTED;
@@ -228,6 +229,12 @@ static void ics_get_kvm_state(ICSState *ics)
| XICS_STATUS_REJECTED;
}
}
+ if (state & KVM_XICS_PRESENTED) {
+ irq->status |= XICS_STATUS_PRESENTED;
+ }
+ if (state & KVM_XICS_QUEUED) {
+ irq->status |= XICS_STATUS_QUEUED;
+ }
}
}
@@ -265,6 +272,12 @@ static int ics_set_kvm_state(ICSState *ics, int version_id)
state |= KVM_XICS_PENDING;
}
}
+ if (irq->status & XICS_STATUS_PRESENTED) {
+ state |= KVM_XICS_PRESENTED;
+ }
+ if (irq->status & XICS_STATUS_QUEUED) {
+ state |= KVM_XICS_QUEUED;
+ }
ret = ioctl(kernel_xics_fd, KVM_SET_DEVICE_ATTR, &attr);
if (ret != 0) {
diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index a0866c3856..e2215dcf4d 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -805,7 +805,7 @@ static void ich9_lpc_class_init(ObjectClass *klass, void *data)
* Reason: part of ICH9 southbridge, needs to be wired up by
* pc_q35_init()
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
hc->plug = ich9_pm_device_plug_cb;
hc->unplug_request = ich9_pm_device_unplug_request_cb;
hc->unplug = ich9_pm_device_unplug_cb;
diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index 5500fcc4d6..f811eba59d 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -123,7 +123,7 @@ static void piix4_class_init(ObjectClass *klass, void *data)
* Reason: part of PIIX4 southbridge, needs to be wired up,
* e.g. by mips_malta_init()
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
dc->hotpluggable = false;
}
diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 41d5254f8e..50dc83df77 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -494,7 +494,7 @@ static void via_class_init(ObjectClass *klass, void *data)
* Reason: part of VIA VT82C686 southbridge, needs to be wired up,
* e.g. by mips_fulong2e_init()
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo via_info = {
diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c
index 1834d22a61..457a08a2fe 100644
--- a/hw/microblaze/boot.c
+++ b/hw/microblaze/boot.c
@@ -189,7 +189,7 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,
ram_size - initrd_offset);
}
if (initrd_size < 0) {
- error_report("qemu: could not load initrd '%s'",
+ error_report("could not load initrd '%s'",
initrd_filename);
exit(EXIT_FAILURE);
}
diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c
index 4811843ab6..e8b2eef688 100644
--- a/hw/mips/gt64xxx_pci.c
+++ b/hw/mips/gt64xxx_pci.c
@@ -1224,7 +1224,7 @@ static void gt64120_pci_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo gt64120_pci_info = {
diff --git a/hw/misc/vmport.c b/hw/misc/vmport.c
index be40930b8b..165500223f 100644
--- a/hw/misc/vmport.c
+++ b/hw/misc/vmport.c
@@ -163,7 +163,7 @@ static void vmport_class_initfn(ObjectClass *klass, void *data)
dc->realize = vmport_realizefn;
/* Reason: realize sets global port_state */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo vmport_info = {
diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
index efa33ad40a..b53fcaa8bc 100644
--- a/hw/net/dp8393x.c
+++ b/hw/net/dp8393x.c
@@ -934,7 +934,7 @@ static void dp8393x_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_dp8393x;
dc->props = dp8393x_properties;
/* Reason: dma_mr property can't be set */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo dp8393x_info = {
diff --git a/hw/net/etraxfs_eth.c b/hw/net/etraxfs_eth.c
index efaa49faae..013c8d0a41 100644
--- a/hw/net/etraxfs_eth.c
+++ b/hw/net/etraxfs_eth.c
@@ -630,7 +630,7 @@ static void etraxfs_eth_class_init(ObjectClass *klass, void *data)
k->init = fs_eth_init;
dc->props = etraxfs_eth_properties;
/* Reason: pointer properties "dma_out", "dma_in" */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo etraxfs_eth_info = {
diff --git a/hw/net/fsl_etsec/etsec.c b/hw/net/fsl_etsec/etsec.c
index aa2b0d5a85..9da1932970 100644
--- a/hw/net/fsl_etsec/etsec.c
+++ b/hw/net/fsl_etsec/etsec.c
@@ -416,6 +416,8 @@ static void etsec_class_init(ObjectClass *klass, void *data)
dc->realize = etsec_realize;
dc->reset = etsec_reset;
dc->props = etsec_properties;
+ /* Supported by ppce500 machine */
+ dc->user_creatable = true;
}
static TypeInfo etsec_info = {
diff --git a/hw/net/lance.c b/hw/net/lance.c
index 573d724bcf..92b0c68274 100644
--- a/hw/net/lance.c
+++ b/hw/net/lance.c
@@ -165,7 +165,7 @@ static void lance_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_lance;
dc->props = lance_properties;
/* Reason: pointer property "dma" */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo lance_info = {
diff --git a/hw/nios2/boot.c b/hw/nios2/boot.c
index e0a9aff2f4..2b31f5b844 100644
--- a/hw/nios2/boot.c
+++ b/hw/nios2/boot.c
@@ -197,7 +197,7 @@ void nios2_load_kernel(Nios2CPU *cpu, hwaddr ddr_base,
ram_size - initrd_offset);
}
if (initrd_size < 0) {
- error_report("qemu: could not load initrd '%s'",
+ error_report("could not load initrd '%s'",
initrd_filename);
exit(EXIT_FAILURE);
}
diff --git a/hw/pci-bridge/dec.c b/hw/pci-bridge/dec.c
index 840c96198a..cca93620ac 100644
--- a/hw/pci-bridge/dec.c
+++ b/hw/pci-bridge/dec.c
@@ -128,7 +128,7 @@ static void dec_21154_pci_host_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo dec_21154_pci_host_info = {
diff --git a/hw/pci-bridge/pci_expander_bridge.c b/hw/pci-bridge/pci_expander_bridge.c
index 6ac187fa32..ff59abf208 100644
--- a/hw/pci-bridge/pci_expander_bridge.c
+++ b/hw/pci-bridge/pci_expander_bridge.c
@@ -150,7 +150,7 @@ static void pxb_host_class_init(ObjectClass *class, void *data)
dc->fw_name = "pci";
/* Reason: Internal part of the pxb/pxb-pcie device, not usable by itself */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
sbc->explicit_ofw_unit_address = pxb_host_ofw_unit_address;
hc->root_bus_path = pxb_host_root_bus_path;
}
diff --git a/hw/pci-host/apb.c b/hw/pci-host/apb.c
index 653e711121..edc88f4c65 100644
--- a/hw/pci-host/apb.c
+++ b/hw/pci-host/apb.c
@@ -810,7 +810,7 @@ static void pbm_pci_host_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo pbm_pci_host_info = {
diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
index 1999ece590..85a3bb0dd2 100644
--- a/hw/pci-host/bonito.c
+++ b/hw/pci-host/bonito.c
@@ -825,7 +825,7 @@ static void bonito_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo bonito_info = {
diff --git a/hw/pci-host/gpex.c b/hw/pci-host/gpex.c
index 66055ee5cc..e2629ce70d 100644
--- a/hw/pci-host/gpex.c
+++ b/hw/pci-host/gpex.c
@@ -136,7 +136,7 @@ static void gpex_root_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo gpex_root_info = {
diff --git a/hw/pci-host/grackle.c b/hw/pci-host/grackle.c
index 2c8acdaaca..2e281f6155 100644
--- a/hw/pci-host/grackle.c
+++ b/hw/pci-host/grackle.c
@@ -134,7 +134,7 @@ static void grackle_pci_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo grackle_pci_info = {
diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index bf4221d4bf..2d02de12d9 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -685,7 +685,7 @@ static void pci_piix3_class_init(ObjectClass *klass, void *data)
* Reason: part of PIIX3 southbridge, needs to be wired up by
* pc_piix.c's pc_init1()
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo piix3_pci_type_info = {
@@ -739,7 +739,7 @@ static void i440fx_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
dc->hotpluggable = false;
}
@@ -868,7 +868,7 @@ static void i440fx_pcihost_class_init(ObjectClass *klass, void *data)
dc->fw_name = "pci";
dc->props = i440fx_props;
/* Reason: needs to be wired up by pc_init1 */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo i440fx_pcihost_info = {
diff --git a/hw/pci-host/ppce500.c b/hw/pci-host/ppce500.c
index e502bc0505..becc0eeb76 100644
--- a/hw/pci-host/ppce500.c
+++ b/hw/pci-host/ppce500.c
@@ -508,7 +508,7 @@ static void e500_host_bridge_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo e500_host_bridge_info = {
diff --git a/hw/pci-host/prep.c b/hw/pci-host/prep.c
index 260a119a9e..900a6edfcf 100644
--- a/hw/pci-host/prep.c
+++ b/hw/pci-host/prep.c
@@ -364,7 +364,7 @@ static void raven_class_init(ObjectClass *klass, void *data)
* Reason: PCI-facing part of the host bridge, not usable without
* the host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo raven_info = {
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index 344f77b10c..cd5c49616e 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -156,7 +156,7 @@ static void q35_host_class_init(ObjectClass *klass, void *data)
dc->realize = q35_host_realize;
dc->props = mch_props;
/* Reason: needs to be wired up by pc_q35_init */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
dc->fw_name = "pci";
}
@@ -549,7 +549,7 @@ static void mch_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo mch_info = {
diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c
index df342ac3cb..6cf5e59f86 100644
--- a/hw/pci-host/uninorth.c
+++ b/hw/pci-host/uninorth.c
@@ -366,7 +366,7 @@ static void unin_main_pci_host_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo unin_main_pci_host_info = {
@@ -390,7 +390,7 @@ static void u3_agp_pci_host_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo u3_agp_pci_host_info = {
@@ -414,7 +414,7 @@ static void unin_agp_pci_host_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo unin_agp_pci_host_info = {
@@ -438,7 +438,7 @@ static void unin_internal_pci_host_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo unin_internal_pci_host_info = {
diff --git a/hw/pci-host/versatile.c b/hw/pci-host/versatile.c
index 27fde46126..aa1fdf75fd 100644
--- a/hw/pci-host/versatile.c
+++ b/hw/pci-host/versatile.c
@@ -479,7 +479,7 @@ static void versatile_pci_host_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo versatile_pci_host_info = {
diff --git a/hw/pci-host/xilinx-pcie.c b/hw/pci-host/xilinx-pcie.c
index 8b71e2d950..a968cea2af 100644
--- a/hw/pci-host/xilinx-pcie.c
+++ b/hw/pci-host/xilinx-pcie.c
@@ -309,7 +309,7 @@ static void xilinx_pcie_root_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo xilinx_pcie_root_info = {
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index 68aaedc06d..bae1c0ac99 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -80,6 +80,8 @@
#define CLOCKFREQ (266UL * 1000UL * 1000UL)
#define BUSFREQ (100UL * 1000UL * 1000UL)
+#define NDRV_VGA_FILENAME "qemu_vga.ndrv"
+
/* UniN device */
static void unin_write(void *opaque, hwaddr addr, uint64_t value,
unsigned size)
@@ -160,7 +162,8 @@ static void ppc_core99_init(MachineState *machine)
MACIOIDEState *macio_ide;
BusState *adb_bus;
MacIONVRAMState *nvr;
- int bios_size;
+ int bios_size, ndrv_size;
+ uint8_t *ndrv_file;
MemoryRegion *pic_mem, *escc_mem;
MemoryRegion *escc_bar = g_new(MemoryRegion, 1);
int ppc_boot_device;
@@ -494,6 +497,19 @@ static void ppc_core99_init(MachineState *machine)
fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_BUSFREQ, BUSFREQ);
fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_NVRAM_ADDR, nvram_addr);
+ /* MacOS NDRV VGA driver */
+ filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, NDRV_VGA_FILENAME);
+ if (filename) {
+ ndrv_size = get_image_size(filename);
+ if (ndrv_size != -1) {
+ ndrv_file = g_malloc(ndrv_size);
+ ndrv_size = load_image(filename, ndrv_file);
+
+ fw_cfg_add_file(fw_cfg, "ndrv/qemu_vga.ndrv", ndrv_file, ndrv_size);
+ }
+ g_free(filename);
+ }
+
qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
}
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index 5df94e239b..97bb8541d7 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -53,6 +53,8 @@
#define CLOCKFREQ 266000000UL
#define BUSFREQ 66000000UL
+#define NDRV_VGA_FILENAME "qemu_vga.ndrv"
+
static void fw_cfg_boot_set(void *opaque, const char *boot_device,
Error **errp)
{
@@ -99,7 +101,8 @@ static void ppc_heathrow_init(MachineState *machine)
MACIOIDEState *macio_ide;
DeviceState *dev;
BusState *adb_bus;
- int bios_size;
+ int bios_size, ndrv_size;
+ uint8_t *ndrv_file;
MemoryRegion *pic_mem;
MemoryRegion *escc_mem, *escc_bar = g_new(MemoryRegion, 1);
uint16_t ppc_boot_device;
@@ -355,6 +358,19 @@ static void ppc_heathrow_init(MachineState *machine)
fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_CLOCKFREQ, CLOCKFREQ);
fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_BUSFREQ, BUSFREQ);
+ /* MacOS NDRV VGA driver */
+ filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, NDRV_VGA_FILENAME);
+ if (filename) {
+ ndrv_size = get_image_size(filename);
+ if (ndrv_size != -1) {
+ ndrv_file = g_malloc(ndrv_size);
+ ndrv_size = load_image(filename, ndrv_file);
+
+ fw_cfg_add_file(fw_cfg, "ndrv/qemu_vga.ndrv", ndrv_file, ndrv_size);
+ }
+ g_free(filename);
+ }
+
qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
}
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index d4bcdb027f..231ed9735b 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -511,7 +511,7 @@ static void ppc_powernv_reset(void)
* This is the internal simulator but it could also be an external
* BMC.
*/
- obj = object_resolve_path_type("", TYPE_IPMI_BMC, NULL);
+ obj = object_resolve_path_type("", "ipmi-bmc-sim", NULL);
if (obj) {
pnv->bmc = IPMI_BMC(obj);
}
@@ -610,7 +610,7 @@ static void ppc_powernv_init(MachineState *machine)
/* Create the processor chips */
chip_typename = g_strdup_printf(TYPE_PNV_CHIP "-%s", machine->cpu_model);
if (!object_class_by_name(chip_typename)) {
- error_report("qemu: invalid CPU model '%s' for %s machine",
+ error_report("invalid CPU model '%s' for %s machine",
machine->cpu_model, MACHINE_GET_CLASS(machine)->name);
exit(1);
}
diff --git a/hw/ppc/ppc4xx_pci.c b/hw/ppc/ppc4xx_pci.c
index dc19682970..6953f8b9ac 100644
--- a/hw/ppc/ppc4xx_pci.c
+++ b/hw/ppc/ppc4xx_pci.c
@@ -351,7 +351,7 @@ static void ppc4xx_host_bridge_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo ppc4xx_host_bridge_info = {
diff --git a/hw/ppc/ppc_booke.c b/hw/ppc/ppc_booke.c
index 60baffaf1d..23bcf1b138 100644
--- a/hw/ppc/ppc_booke.c
+++ b/hw/ppc/ppc_booke.c
@@ -282,7 +282,6 @@ void store_booke_tcr(CPUPPCState *env, target_ulong val)
ppc_tb_t *tb_env = env->tb_env;
booke_timer_t *booke_timer = tb_env->opaque;
- tb_env = env->tb_env;
env->spr[SPR_BOOKE_TCR] = val;
kvmppc_set_tcr(cpu);
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 80d12d005c..0980d733cd 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -219,7 +219,7 @@ static void spapr_populate_pa_features(CPUPPCState *env, void *fdt, int offset,
/* 16: Vector */
0x00, 0x00, 0x00, 0x00, 0x80, 0x00, /* 12 - 17 */
/* 18: Vec. Scalar, 20: Vec. XOR, 22: HTM */
- 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 18 - 23 */
+ 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 18 - 23 */
/* 24: Ext. Dec, 26: 64 bit ftrs, 28: PM ftrs */
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 24 - 29 */
/* 30: MMR, 32: LE atomic, 34: EBB + ext EBB */
@@ -855,6 +855,8 @@ static void spapr_dt_rtas(sPAPRMachineState *spapr, void *fdt)
* option vector 5: */
static void spapr_dt_ov5_platform_support(void *fdt, int chosen)
{
+ PowerPCCPU *first_ppc_cpu = POWERPC_CPU(first_cpu);
+
char val[2 * 3] = {
24, 0x00, /* Hash/Radix, filled in below. */
25, 0x00, /* Hash options: Segment Tables == no, GTSE == no. */
@@ -870,8 +872,13 @@ static void spapr_dt_ov5_platform_support(void *fdt, int chosen)
val[1] = 0x00; /* Hash */
}
} else {
- /* TODO: TCG case, hash */
- val[1] = 0x00;
+ if (first_ppc_cpu->env.mmu_model & POWERPC_MMU_V3) {
+ /* V3 MMU supports both hash and radix (with dynamic switching) */
+ val[1] = 0xC0;
+ } else {
+ /* Otherwise we can only do hash */
+ val[1] = 0x00;
+ }
}
_FDT(fdt_setprop(fdt, chosen, "ibm,arch-vec-5-platform-support",
val, sizeof(val)));
@@ -2101,8 +2108,8 @@ static void ppc_spapr_init(MachineState *machine)
}
spapr_ovec_set(spapr->ov5, OV5_FORM1_AFFINITY);
- if (kvmppc_has_cap_mmu_radix()) {
- /* KVM always allows GTSE with radix... */
+ if (!kvm_enabled() || kvmppc_has_cap_mmu_radix()) {
+ /* KVM and TCG always allow GTSE with radix... */
spapr_ovec_set(spapr->ov5, OV5_MMU_RADIX_GTSE);
}
/* ... but not with hash (currently). */
@@ -2824,9 +2831,11 @@ static void spapr_core_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
MachineClass *mc = MACHINE_GET_CLASS(hotplug_dev);
Error *local_err = NULL;
CPUCore *cc = CPU_CORE(dev);
+ sPAPRCPUCore *sc = SPAPR_CPU_CORE(dev);
char *base_core_type = spapr_get_cpu_core_type(machine->cpu_model);
const char *type = object_get_typename(OBJECT(dev));
CPUArchId *core_slot;
+ int node_id;
int index;
if (dev->hotplugged && !mc->has_hotpluggable_cpus) {
@@ -2861,6 +2870,21 @@ static void spapr_core_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
goto out;
}
+ node_id = core_slot->props.node_id;
+ if (!core_slot->props.has_node_id) {
+ /* by default CPUState::numa_node was 0 if it's not set via CLI
+ * keep it this way for now but in future we probably should
+ * refuse to start up with incomplete numa mapping */
+ node_id = 0;
+ }
+ if (sc->node_id == CPU_UNSET_NUMA_NODE_ID) {
+ sc->node_id = node_id;
+ } else if (sc->node_id != node_id) {
+ error_setg(&local_err, "node-id %d must match numa node specified"
+ "with -numa option for cpu-index %d", sc->node_id, cc->core_id);
+ goto out;
+ }
+
out:
g_free(base_core_type);
error_propagate(errp, local_err);
@@ -2981,11 +3005,18 @@ static HotplugHandler *spapr_get_hotplug_handler(MachineState *machine,
return NULL;
}
-static unsigned spapr_cpu_index_to_socket_id(unsigned cpu_index)
+static CpuInstanceProperties
+spapr_cpu_index_to_props(MachineState *machine, unsigned cpu_index)
{
- /* Allocate to NUMA nodes on a "socket" basis (not that concept of
- * socket means much for the paravirtualized PAPR platform) */
- return cpu_index / smp_threads / smp_cores;
+ CPUArchId *core_slot;
+ MachineClass *mc = MACHINE_GET_CLASS(machine);
+
+ /* make sure possible_cpu are intialized */
+ mc->possible_cpu_arch_ids(machine);
+ /* get CPU core slot containing thread that matches cpu_index */
+ core_slot = spapr_find_cpu_slot(machine, cpu_index, NULL);
+ assert(core_slot);
+ return core_slot->props;
}
static const CPUArchIdList *spapr_possible_cpu_arch_ids(MachineState *machine)
@@ -3012,8 +3043,15 @@ static const CPUArchIdList *spapr_possible_cpu_arch_ids(MachineState *machine)
machine->possible_cpus->cpus[i].arch_id = core_id;
machine->possible_cpus->cpus[i].props.has_core_id = true;
machine->possible_cpus->cpus[i].props.core_id = core_id;
- /* TODO: add 'has_node/node' here to describe
- to which node core belongs */
+
+ /* default distribution of CPUs over NUMA nodes */
+ if (nb_numa_nodes) {
+ /* preset values but do not enable them i.e. 'has_node_id = false',
+ * numa init code will enable them later if manual mapping wasn't
+ * present on CLI */
+ machine->possible_cpus->cpus[i].props.node_id =
+ core_id / smp_threads / smp_cores % nb_numa_nodes;
+ }
}
return machine->possible_cpus;
}
@@ -3138,7 +3176,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
hc->pre_plug = spapr_machine_device_pre_plug;
hc->plug = spapr_machine_device_plug;
hc->unplug = spapr_machine_device_unplug;
- mc->cpu_index_to_socket_id = spapr_cpu_index_to_socket_id;
+ mc->cpu_index_to_instance_props = spapr_cpu_index_to_props;
mc->possible_cpu_arch_ids = spapr_possible_cpu_arch_ids;
hc->unplug_request = spapr_machine_device_unplug_request;
@@ -3242,6 +3280,7 @@ static void spapr_machine_2_9_class_options(MachineClass *mc)
{
spapr_machine_2_10_class_options(mc);
SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_9);
+ mc->numa_auto_assign_ram = numa_legacy_auto_assign_ram;
}
DEFINE_SPAPR_MACHINE(2_9, "2.9", false);
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index 4389ef4c2a..a17ea07ef1 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -176,13 +176,11 @@ static void spapr_cpu_core_realize(DeviceState *dev, Error **errp)
const char *typename = object_class_get_name(scc->cpu_class);
size_t size = object_type_get_instance_size(typename);
Error *local_err = NULL;
- int core_node_id = numa_get_node_for_cpu(cc->core_id);;
void *obj;
int i, j;
sc->threads = g_malloc0(size * cc->nr_threads);
for (i = 0; i < cc->nr_threads; i++) {
- int node_id;
char id[32];
CPUState *cs;
@@ -192,17 +190,8 @@ static void spapr_cpu_core_realize(DeviceState *dev, Error **errp)
cs = CPU(obj);
cs->cpu_index = cc->core_id + i;
- /* Set NUMA node for the added CPUs */
- node_id = numa_get_node_for_cpu(cs->cpu_index);
- if (node_id != core_node_id) {
- error_setg(&local_err, "Invalid node-id=%d of thread[cpu-index: %d]"
- " on CPU[core-id: %d, node-id: %d], node-id must be the same",
- node_id, cs->cpu_index, cc->core_id, core_node_id);
- goto err;
- }
- if (node_id < nb_numa_nodes) {
- cs->numa_node = node_id;
- }
+ /* Set NUMA node for the threads belonged to core */
+ cs->numa_node = sc->node_id;
snprintf(id, sizeof(id), "thread[%d]", i);
object_property_add_child(OBJECT(sc), id, obj, &local_err);
@@ -263,6 +252,11 @@ static const char *spapr_core_models[] = {
"POWER9_v1.0",
};
+static Property spapr_cpu_core_properties[] = {
+ DEFINE_PROP_INT32("node-id", sPAPRCPUCore, node_id, CPU_UNSET_NUMA_NODE_ID),
+ DEFINE_PROP_END_OF_LIST()
+};
+
void spapr_cpu_core_class_init(ObjectClass *oc, void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);
@@ -270,6 +264,7 @@ void spapr_cpu_core_class_init(ObjectClass *oc, void *data)
dc->realize = spapr_cpu_core_realize;
dc->unrealize = spapr_cpu_core_unrealizefn;
+ dc->props = spapr_cpu_core_properties;
scc->cpu_class = cpu_class_by_name(TYPE_POWERPC_CPU, data);
g_assert(scc->cpu_class);
}
diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
index a1cdc875b1..9fa5545991 100644
--- a/hw/ppc/spapr_drc.c
+++ b/hw/ppc/spapr_drc.c
@@ -675,7 +675,7 @@ static void spapr_dr_connector_class_init(ObjectClass *k, void *data)
/*
* Reason: it crashes FIXME find and document the real reason
*/
- dk->cannot_instantiate_with_device_add_yet = true;
+ dk->user_creatable = false;
}
static const TypeInfo spapr_dr_connector_info = {
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 9f18f75b88..0d608d6e28 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -936,7 +936,7 @@ static target_ulong h_register_process_table(PowerPCCPU *cpu,
target_ulong opcode,
target_ulong *args)
{
- CPUPPCState *env = &cpu->env;
+ CPUState *cs;
target_ulong flags = args[0];
target_ulong proc_tbl = args[1];
target_ulong page_size = args[2];
@@ -992,16 +992,12 @@ static target_ulong h_register_process_table(PowerPCCPU *cpu,
spapr_check_setup_free_hpt(spapr, spapr->patb_entry, cproc);
spapr->patb_entry = cproc; /* Save new process table */
- if ((flags & FLAG_RADIX) || (flags & FLAG_HASH_PROC_TBL)) {
- /* Use Process TBL */
- env->spr[SPR_LPCR] |= LPCR_UPRT;
- } else {
- env->spr[SPR_LPCR] &= ~LPCR_UPRT;
- }
- if (flags & FLAG_GTSE) { /* Partition Uses Guest Translation Shootdwn */
- env->spr[SPR_LPCR] |= LPCR_GTSE;
- } else {
- env->spr[SPR_LPCR] &= ~LPCR_GTSE;
+
+ /* Update the UPRT and GTSE bits in the LPCR for all cpus */
+ CPU_FOREACH(cs) {
+ set_spr(cs, SPR_LPCR, LPCR_UPRT | LPCR_GTSE,
+ ((flags & (FLAG_RADIX | FLAG_HASH_PROC_TBL)) ? LPCR_UPRT : 0) |
+ ((flags & FLAG_GTSE) ? LPCR_GTSE : 0));
}
if (kvm_enabled()) {
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index e7567e2e8f..a7cff32bbf 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1994,6 +1994,8 @@ static void spapr_phb_class_init(ObjectClass *klass, void *data)
dc->props = spapr_phb_properties;
dc->reset = spapr_phb_reset;
dc->vmsd = &vmstate_spapr_pci;
+ /* Supported by TYPE_SPAPR_MACHINE */
+ dc->user_creatable = true;
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
hp->plug = spapr_phb_hot_plug_child;
hp->unplug = spapr_phb_hot_unplug_child;
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index a8a1bab50a..66a6fbeb8c 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -872,7 +872,6 @@ static void s390_pcihost_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
- dc->cannot_instantiate_with_device_add_yet = true;
dc->reset = s390_pcihost_reset;
k->init = s390_pcihost_init;
hc->plug = s390_pcihost_hot_plug;
diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index b4f6dd58dd..83d6023894 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -505,10 +505,10 @@ static void sclp_realize(DeviceState *dev, Error **errp)
ret = s390_set_memory_limit(machine->maxram_size, &hw_limit);
if (ret == -E2BIG) {
- error_setg(&err, "qemu: host supports a maximum of %" PRIu64 " GB",
+ error_setg(&err, "host supports a maximum of %" PRIu64 " GB",
hw_limit >> 30);
} else if (ret) {
- error_setg(&err, "qemu: setting the guest size failed");
+ error_setg(&err, "setting the guest size failed");
}
out:
diff --git a/hw/sd/milkymist-memcard.c b/hw/sd/milkymist-memcard.c
index 1f2f0ed44a..4008c81002 100644
--- a/hw/sd/milkymist-memcard.c
+++ b/hw/sd/milkymist-memcard.c
@@ -299,7 +299,7 @@ static void milkymist_memcard_class_init(ObjectClass *klass, void *data)
dc->reset = milkymist_memcard_reset;
dc->vmsd = &vmstate_milkymist_memcard;
/* Reason: init() method uses drive_get_next() */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo milkymist_memcard_info = {
diff --git a/hw/sd/pl181.c b/hw/sd/pl181.c
index 82c63a4fb5..55c8098ecd 100644
--- a/hw/sd/pl181.c
+++ b/hw/sd/pl181.c
@@ -515,7 +515,7 @@ static void pl181_class_init(ObjectClass *klass, void *data)
k->vmsd = &vmstate_pl181;
k->reset = pl181_reset;
/* Reason: init() method uses drive_get_next() */
- k->cannot_instantiate_with_device_add_yet = true;
+ k->user_creatable = false;
k->realize = pl181_realize;
}
diff --git a/hw/sh4/sh_pci.c b/hw/sh4/sh_pci.c
index 1747628f3d..38395c082b 100644
--- a/hw/sh4/sh_pci.c
+++ b/hw/sh4/sh_pci.c
@@ -171,7 +171,7 @@ static void sh_pci_host_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo sh_pci_host_info = {
diff --git a/hw/timer/i8254_common.c b/hw/timer/i8254_common.c
index e18299a482..976d5200f1 100644
--- a/hw/timer/i8254_common.c
+++ b/hw/timer/i8254_common.c
@@ -287,7 +287,7 @@ static void pit_common_class_init(ObjectClass *klass, void *data)
* wired to the HPET, and because of that, some wiring is always
* done by board code.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo pit_common_type = {
diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c
index 4165450250..93de3e1cc5 100644
--- a/hw/timer/mc146818rtc.c
+++ b/hw/timer/mc146818rtc.c
@@ -973,7 +973,7 @@ static void rtc_class_initfn(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_rtc;
dc->props = mc146818rtc_properties;
/* Reason: needs to be wired up by rtc_init() */
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static void rtc_finalize(Object *obj)
diff --git a/hw/tricore/tricore_testboard.c b/hw/tricore/tricore_testboard.c
index 19dd587207..8910bf0f27 100644
--- a/hw/tricore/tricore_testboard.c
+++ b/hw/tricore/tricore_testboard.c
@@ -50,7 +50,7 @@ static void tricore_load_kernel(CPUTriCoreState *env)
NULL, 0,
EM_TRICORE, 1, 0);
if (kernel_size <= 0) {
- error_report("qemu: no kernel file '%s'",
+ error_report("no kernel file '%s'",
tricoretb_binfo.kernel_filename);
exit(1);
}
diff --git a/hw/usb/dev-hub.c b/hw/usb/dev-hub.c
index 9fe7333946..47b7519910 100644
--- a/hw/usb/dev-hub.c
+++ b/hw/usb/dev-hub.c
@@ -208,6 +208,7 @@ static void usb_hub_wakeup(USBPort *port1)
USBHubPort *port = &s->ports[port1->index];
if (port->wPortStatus & PORT_STAT_SUSPEND) {
+ port->wPortStatus &= ~PORT_STAT_SUSPEND;
port->wPortChange |= PORT_STAT_C_SUSPEND;
usb_wakeup(s->intr, 0);
}
diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c
index 6d5137383b..83a4f0e6fb 100644
--- a/hw/usb/dev-serial.c
+++ b/hw/usb/dev-serial.c
@@ -513,27 +513,18 @@ static USBDevice *usb_serial_init(USBBus *bus, const char *filename)
{
USBDevice *dev;
Chardev *cdrv;
- uint32_t vendorid = 0, productid = 0;
char label[32];
static int index;
while (*filename && *filename != ':') {
const char *p;
- char *e;
+
if (strstart(filename, "vendorid=", &p)) {
- vendorid = strtol(p, &e, 16);
- if (e == p || (*e && *e != ',' && *e != ':')) {
- error_report("bogus vendor ID %s", p);
- return NULL;
- }
- filename = e;
+ error_report("vendorid is not supported anymore");
+ return NULL;
} else if (strstart(filename, "productid=", &p)) {
- productid = strtol(p, &e, 16);
- if (e == p || (*e && *e != ',' && *e != ':')) {
- error_report("bogus product ID %s", p);
- return NULL;
- }
- filename = e;
+ error_report("productid is not supported anymore");
+ return NULL;
} else {
error_report("unrecognized serial USB option %s", filename);
return NULL;
@@ -554,10 +545,7 @@ static USBDevice *usb_serial_init(USBBus *bus, const char *filename)
dev = usb_create(bus, "usb-serial");
qdev_prop_set_chr(&dev->qdev, "chardev", cdrv);
- if (vendorid)
- qdev_prop_set_uint16(&dev->qdev, "vendorid", vendorid);
- if (productid)
- qdev_prop_set_uint16(&dev->qdev, "productid", productid);
+
return dev;
}
diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c
index 757b8b3f5a..49cb1829b5 100644
--- a/hw/usb/dev-smartcard-reader.c
+++ b/hw/usb/dev-smartcard-reader.c
@@ -813,7 +813,10 @@ static void ccid_write_data_block(USBCCIDState *s, uint8_t slot, uint8_t seq,
if (p->b.bError) {
DPRINTF(s, D_VERBOSE, "error %d\n", p->b.bError);
}
- memcpy(p->abData, data, len);
+ if (len) {
+ g_assert_nonnull(data);
+ memcpy(p->abData, data, len);
+ }
ccid_reset_error_status(s);
usb_wakeup(s->bulk, 0);
}
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index a2d3143bf4..77d8e1137a 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -50,7 +50,7 @@
/* Very pessimistic, let's hope it's enough for all cases */
#define EV_QUEUE (((3 * 24) + 16) * MAXSLOTS)
-#define TRB_LINK_LIMIT 4
+#define TRB_LINK_LIMIT 32
#define COMMAND_LIMIT 256
#define TRANSFER_LIMIT 256
@@ -1790,9 +1790,6 @@ static void xhci_stall_ep(XHCITransfer *xfer)
}
}
-static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer,
- XHCIEPContext *epctx);
-
static int xhci_setup_packet(XHCITransfer *xfer)
{
USBEndpoint *ep;
@@ -1806,7 +1803,7 @@ static int xhci_setup_packet(XHCITransfer *xfer)
ep = xhci_epid_to_usbep(xfer->epctx);
if (!ep) {
DPRINTF("xhci: slot %d has no device\n",
- xfer->slotid);
+ xfer->epctx->slotid);
return -1;
}
}
@@ -1980,7 +1977,7 @@ static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx
{
uint64_t mfindex;
- DPRINTF("xhci_submit(slotid=%d,epid=%d)\n", xfer->slotid, xfer->epid);
+ DPRINTF("xhci_submit(slotid=%d,epid=%d)\n", epctx->slotid, epctx->epid);
xfer->in_xfer = epctx->type>>2;
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index b001a27f05..ad5ef783a6 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -229,21 +229,10 @@ static void usbredir_log(void *priv, int level, const char *msg)
static void usbredir_log_data(USBRedirDevice *dev, const char *desc,
const uint8_t *data, int len)
{
- int i, j, n;
-
if (dev->debug < usbredirparser_debug_data) {
return;
}
-
- for (i = 0; i < len; i += j) {
- char buf[128];
-
- n = sprintf(buf, "%s", desc);
- for (j = 0; j < 8 && i + j < len; j++) {
- n += sprintf(buf + n, " %02X", data[i + j]);
- }
- error_report("%s", buf);
- }
+ qemu_hexdump((char *)data, stderr, desc, len);
}
/*
diff --git a/hw/vfio/amd-xgbe.c b/hw/vfio/amd-xgbe.c
index 2c60310cf9..fab196cebf 100644
--- a/hw/vfio/amd-xgbe.c
+++ b/hw/vfio/amd-xgbe.c
@@ -38,6 +38,8 @@ static void vfio_amd_xgbe_class_init(ObjectClass *klass, void *data)
dc->realize = amd_xgbe_realize;
dc->desc = "VFIO AMD XGBE";
dc->vmsd = &vfio_platform_amd_xgbe_vmstate;
+ /* Supported by TYPE_VIRT_MACHINE */
+ dc->user_creatable = true;
}
static const TypeInfo vfio_amd_xgbe_dev_info = {
diff --git a/hw/vfio/calxeda-xgmac.c b/hw/vfio/calxeda-xgmac.c
index bb15d588e5..7bb17af7ad 100644
--- a/hw/vfio/calxeda-xgmac.c
+++ b/hw/vfio/calxeda-xgmac.c
@@ -38,6 +38,8 @@ static void vfio_calxeda_xgmac_class_init(ObjectClass *klass, void *data)
dc->realize = calxeda_xgmac_realize;
dc->desc = "VFIO Calxeda XGMAC";
dc->vmsd = &vfio_platform_calxeda_xgmac_vmstate;
+ /* Supported by TYPE_VIRT_MACHINE */
+ dc->user_creatable = true;
}
static const TypeInfo vfio_calxeda_xgmac_dev_info = {
diff --git a/hw/xen/xen_backend.c b/hw/xen/xen_backend.c
index c85f1637e4..3570f37e56 100644
--- a/hw/xen/xen_backend.c
+++ b/hw/xen/xen_backend.c
@@ -147,7 +147,7 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
qdev_unplug(DEVICE(xendev), NULL);
return NULL;
}
- fcntl(xenevtchn_fd(xendev->evtchndev), F_SETFD, FD_CLOEXEC);
+ qemu_set_cloexec(xenevtchn_fd(xendev->evtchndev));
if (ops->flags & DEVOPS_FLAG_NEED_GNTDEV) {
xendev->gnttabdev = xengnttab_open(NULL, 0);
@@ -619,6 +619,8 @@ static void xendev_class_init(ObjectClass *klass, void *data)
dc->props = xendev_properties;
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+ /* xen-backend devices can be plugged/unplugged dynamically */
+ dc->user_creatable = true;
}
static const TypeInfo xendev_type_info = {