aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS17
-rw-r--r--accel/tcg/translate-all.c52
-rw-r--r--block/block-backend.c36
-rw-r--r--block/throttle-groups.c6
-rw-r--r--exec.c5
-rw-r--r--hw/arm/exynos4_boards.c12
-rw-r--r--hw/arm/highbank.c17
-rw-r--r--hw/arm/raspi.c2
-rw-r--r--hw/arm/xlnx-zcu102.c9
-rw-r--r--hw/arm/xlnx-zynqmp.c26
-rw-r--r--hw/intc/xics.c11
-rw-r--r--hw/intc/xics_kvm.c19
-rw-r--r--hw/net/eepro100.c31
-rw-r--r--hw/ppc/spapr_hcall.c13
-rw-r--r--include/exec/exec-all.h11
-rw-r--r--include/hw/boards.h5
-rw-r--r--include/hw/compat.h4
-rw-r--r--include/hw/pci/pci.h1
-rw-r--r--include/hw/ppc/xics.h2
-rw-r--r--include/qom/cpu.h1
-rw-r--r--net/colo-compare.c61
-rw-r--r--net/colo.c18
-rw-r--r--net/colo.h1
-rw-r--r--net/socket.c6
-rw-r--r--qemu-doc.texi7
-rw-r--r--qemu-options.hx2
-rw-r--r--target/arm/translate-a64.c2
-rwxr-xr-xtests/qemu-iotests/09362
-rw-r--r--tests/qemu-iotests/093.out4
-rw-r--r--vl.c21
30 files changed, 340 insertions, 124 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 0cd4d02..ffd77b4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -564,6 +564,23 @@ M: Alistair Francis <alistair@alistair23.me>
S: Maintained
F: hw/arm/netduino2.c
+SmartFusion2
+M: Subbaraya Sundeep <sundeep.lkml@gmail.com>
+S: Maintained
+F: hw/arm/msf2-soc.c
+F: hw/misc/msf2-sysreg.c
+F: hw/timer/mss-timer.c
+F: hw/ssi/mss-spi.c
+F: include/hw/arm/msf2-soc.h
+F: include/hw/misc/msf2-sysreg.h
+F: include/hw/timer/mss-timer.h
+F: include/hw/ssi/mss-spi.h
+
+Emcraft M2S-FG484
+M: Subbaraya Sundeep <sundeep.lkml@gmail.com>
+S: Maintained
+F: hw/arm/msf2-som.c
+
CRIS Machines
-------------
Axis Dev88
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index 34c5e28..e7f0329 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -352,36 +352,42 @@ static int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
return 0;
}
-bool cpu_restore_state(CPUState *cpu, uintptr_t retaddr)
+bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc)
{
TranslationBlock *tb;
bool r = false;
+ uintptr_t check_offset;
- /* A retaddr of zero is invalid so we really shouldn't have ended
- * up here. The target code has likely forgotten to check retaddr
- * != 0 before attempting to restore state. We return early to
- * avoid blowing up on a recursive tb_lock(). The target must have
- * previously survived a failed cpu_restore_state because
- * tb_find_pc(0) would have failed anyway. It still should be
- * fixed though.
+ /* The host_pc has to be in the region of current code buffer. If
+ * it is not we will not be able to resolve it here. The two cases
+ * where host_pc will not be correct are:
+ *
+ * - fault during translation (instruction fetch)
+ * - fault from helper (not using GETPC() macro)
+ *
+ * Either way we need return early to avoid blowing up on a
+ * recursive tb_lock() as we can't resolve it here.
+ *
+ * We are using unsigned arithmetic so if host_pc <
+ * tcg_init_ctx.code_gen_buffer check_offset will wrap to way
+ * above the code_gen_buffer_size
*/
-
- if (!retaddr) {
- return r;
- }
-
- tb_lock();
- tb = tb_find_pc(retaddr);
- if (tb) {
- cpu_restore_state_from_tb(cpu, tb, retaddr);
- if (tb->cflags & CF_NOCACHE) {
- /* one-shot translation, invalidate it immediately */
- tb_phys_invalidate(tb, -1);
- tb_remove(tb);
+ check_offset = host_pc - (uintptr_t) tcg_init_ctx.code_gen_buffer;
+
+ if (check_offset < tcg_init_ctx.code_gen_buffer_size) {
+ tb_lock();
+ tb = tb_find_pc(host_pc);
+ if (tb) {
+ cpu_restore_state_from_tb(cpu, tb, host_pc);
+ if (tb->cflags & CF_NOCACHE) {
+ /* one-shot translation, invalidate it immediately */
+ tb_phys_invalidate(tb, -1);
+ tb_remove(tb);
+ }
+ r = true;
}
- r = true;
+ tb_unlock();
}
- tb_unlock();
return r;
}
diff --git a/block/block-backend.c b/block/block-backend.c
index 45d9101..f10b1db 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -655,12 +655,16 @@ BlockBackend *blk_by_public(BlockBackendPublic *public)
*/
void blk_remove_bs(BlockBackend *blk)
{
- ThrottleTimers *tt;
+ ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
+ BlockDriverState *bs;
notifier_list_notify(&blk->remove_bs_notifiers, blk);
- if (blk->public.throttle_group_member.throttle_state) {
- tt = &blk->public.throttle_group_member.throttle_timers;
- throttle_timers_detach_aio_context(tt);
+ if (tgm->throttle_state) {
+ bs = blk_bs(blk);
+ bdrv_drained_begin(bs);
+ throttle_group_detach_aio_context(tgm);
+ throttle_group_attach_aio_context(tgm, qemu_get_aio_context());
+ bdrv_drained_end(bs);
}
blk_update_root_state(blk);
@@ -674,6 +678,7 @@ void blk_remove_bs(BlockBackend *blk)
*/
int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp)
{
+ ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
blk->root = bdrv_root_attach_child(bs, "root", &child_root,
blk->perm, blk->shared_perm, blk, errp);
if (blk->root == NULL) {
@@ -682,10 +687,9 @@ int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp)
bdrv_ref(bs);
notifier_list_notify(&blk->insert_bs_notifiers, blk);
- if (blk->public.throttle_group_member.throttle_state) {
- throttle_timers_attach_aio_context(
- &blk->public.throttle_group_member.throttle_timers,
- bdrv_get_aio_context(bs));
+ if (tgm->throttle_state) {
+ throttle_group_detach_aio_context(tgm);
+ throttle_group_attach_aio_context(tgm, bdrv_get_aio_context(bs));
}
return 0;
@@ -1748,8 +1752,10 @@ void blk_set_aio_context(BlockBackend *blk, AioContext *new_context)
if (bs) {
if (tgm->throttle_state) {
+ bdrv_drained_begin(bs);
throttle_group_detach_aio_context(tgm);
throttle_group_attach_aio_context(tgm, new_context);
+ bdrv_drained_end(bs);
}
bdrv_set_aio_context(bs, new_context);
}
@@ -1974,10 +1980,16 @@ void blk_set_io_limits(BlockBackend *blk, ThrottleConfig *cfg)
void blk_io_limits_disable(BlockBackend *blk)
{
- assert(blk->public.throttle_group_member.throttle_state);
- bdrv_drained_begin(blk_bs(blk));
- throttle_group_unregister_tgm(&blk->public.throttle_group_member);
- bdrv_drained_end(blk_bs(blk));
+ BlockDriverState *bs = blk_bs(blk);
+ ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
+ assert(tgm->throttle_state);
+ if (bs) {
+ bdrv_drained_begin(bs);
+ }
+ throttle_group_unregister_tgm(tgm);
+ if (bs) {
+ bdrv_drained_end(bs);
+ }
}
/* should be called before blk_set_io_limits if a limit is set */
diff --git a/block/throttle-groups.c b/block/throttle-groups.c
index b291a88..2587f19 100644
--- a/block/throttle-groups.c
+++ b/block/throttle-groups.c
@@ -594,6 +594,12 @@ void throttle_group_attach_aio_context(ThrottleGroupMember *tgm,
void throttle_group_detach_aio_context(ThrottleGroupMember *tgm)
{
ThrottleTimers *tt = &tgm->throttle_timers;
+
+ /* Requests must have been drained */
+ assert(tgm->pending_reqs[0] == 0 && tgm->pending_reqs[1] == 0);
+ assert(qemu_co_queue_empty(&tgm->throttled_reqs[0]));
+ assert(qemu_co_queue_empty(&tgm->throttled_reqs[1]));
+
throttle_timers_detach_aio_context(tt);
tgm->aio_context = NULL;
}
diff --git a/exec.c b/exec.c
index 97a24a8..8b579c0 100644
--- a/exec.c
+++ b/exec.c
@@ -792,11 +792,12 @@ void cpu_exec_initfn(CPUState *cpu)
void cpu_exec_realizefn(CPUState *cpu, Error **errp)
{
CPUClass *cc = CPU_GET_CLASS(cpu);
+ static bool tcg_target_initialized;
cpu_list_add(cpu);
- if (tcg_enabled() && !cc->tcg_initialized) {
- cc->tcg_initialized = true;
+ if (tcg_enabled() && !tcg_target_initialized) {
+ tcg_target_initialized = true;
cc->tcg_initialize();
}
diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
index f1441ec..750162c 100644
--- a/hw/arm/exynos4_boards.c
+++ b/hw/arm/exynos4_boards.c
@@ -27,7 +27,6 @@
#include "qemu-common.h"
#include "cpu.h"
#include "sysemu/sysemu.h"
-#include "sysemu/qtest.h"
#include "hw/sysbus.h"
#include "net/net.h"
#include "hw/arm/arm.h"
@@ -129,13 +128,6 @@ exynos4_boards_init_common(MachineState *machine,
Exynos4BoardType board_type)
{
Exynos4BoardState *s = g_new(Exynos4BoardState, 1);
- MachineClass *mc = MACHINE_GET_CLASS(machine);
-
- if (smp_cpus != EXYNOS4210_NCPUS && !qtest_enabled()) {
- error_report("%s board supports only %d CPU cores, ignoring smp_cpus"
- " value",
- mc->name, EXYNOS4210_NCPUS);
- }
exynos4_board_binfo.ram_size = exynos4_board_ram_size[board_type];
exynos4_board_binfo.board_id = exynos4_board_id[board_type];
@@ -189,6 +181,8 @@ static void nuri_class_init(ObjectClass *oc, void *data)
mc->desc = "Samsung NURI board (Exynos4210)";
mc->init = nuri_init;
mc->max_cpus = EXYNOS4210_NCPUS;
+ mc->min_cpus = EXYNOS4210_NCPUS;
+ mc->default_cpus = EXYNOS4210_NCPUS;
mc->ignore_memory_transaction_failures = true;
}
@@ -205,6 +199,8 @@ static void smdkc210_class_init(ObjectClass *oc, void *data)
mc->desc = "Samsung SMDKC210 board (Exynos4210)";
mc->init = smdkc210_init;
mc->max_cpus = EXYNOS4210_NCPUS;
+ mc->min_cpus = EXYNOS4210_NCPUS;
+ mc->default_cpus = EXYNOS4210_NCPUS;
mc->ignore_memory_transaction_failures = true;
}
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
index 354c6b2..287392b 100644
--- a/hw/arm/highbank.c
+++ b/hw/arm/highbank.c
@@ -34,6 +34,7 @@
#include "hw/ide/ahci.h"
#include "hw/cpu/a9mpcore.h"
#include "hw/cpu/a15mpcore.h"
+#include "qemu/log.h"
#define SMP_BOOT_ADDR 0x100
#define SMP_BOOT_REG 0x40
@@ -117,14 +118,26 @@ static void hb_regs_write(void *opaque, hwaddr offset,
}
}
- regs[offset/4] = value;
+ if (offset / 4 >= NUM_REGS) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "highbank: bad write offset 0x%" HWADDR_PRIx "\n", offset);
+ return;
+ }
+ regs[offset / 4] = value;
}
static uint64_t hb_regs_read(void *opaque, hwaddr offset,
unsigned size)
{
+ uint32_t value;
uint32_t *regs = opaque;
- uint32_t value = regs[offset/4];
+
+ if (offset / 4 >= NUM_REGS) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "highbank: bad read offset 0x%" HWADDR_PRIx "\n", offset);
+ return 0;
+ }
+ value = regs[offset / 4];
if ((offset == 0x100) || (offset == 0x108) || (offset == 0x10C)) {
value |= 0x30000000;
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
index 5941c9f..cd5fa8c 100644
--- a/hw/arm/raspi.c
+++ b/hw/arm/raspi.c
@@ -167,6 +167,8 @@ static void raspi2_machine_init(MachineClass *mc)
mc->no_floppy = 1;
mc->no_cdrom = 1;
mc->max_cpus = BCM2836_NCPUS;
+ mc->min_cpus = BCM2836_NCPUS;
+ mc->default_cpus = BCM2836_NCPUS;
mc->default_ram_size = 1024 * 1024 * 1024;
mc->ignore_memory_transaction_failures = true;
};
diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c
index e2d15a1..9631a53 100644
--- a/hw/arm/xlnx-zcu102.c
+++ b/hw/arm/xlnx-zcu102.c
@@ -164,6 +164,9 @@ static void xlnx_ep108_init(MachineState *machine)
{
XlnxZCU102 *s = EP108_MACHINE(machine);
+ info_report("The Xilinx EP108 machine is deprecated, please use the "
+ "ZCU102 machine instead. It has the same features supported.");
+
xlnx_zynqmp_init(s, machine);
}
@@ -185,6 +188,8 @@ static void xlnx_ep108_machine_class_init(ObjectClass *oc, void *data)
mc->block_default_type = IF_IDE;
mc->units_per_default_bus = 1;
mc->ignore_memory_transaction_failures = true;
+ mc->max_cpus = XLNX_ZYNQMP_NUM_APU_CPUS + XLNX_ZYNQMP_NUM_RPU_CPUS;
+ mc->default_cpus = XLNX_ZYNQMP_NUM_APU_CPUS;
}
static const TypeInfo xlnx_ep108_machine_init_typeinfo = {
@@ -235,12 +240,14 @@ static void xlnx_zcu102_machine_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
- mc->desc = "Xilinx ZynqMP ZCU102 board";
+ mc->desc = "Xilinx ZynqMP ZCU102 board with 4xA53s and 2xR5s based on " \
+ "the value of smp";
mc->init = xlnx_zcu102_init;
mc->block_default_type = IF_IDE;
mc->units_per_default_bus = 1;
mc->ignore_memory_transaction_failures = true;
mc->max_cpus = XLNX_ZYNQMP_NUM_APU_CPUS + XLNX_ZYNQMP_NUM_RPU_CPUS;
+ mc->default_cpus = XLNX_ZYNQMP_NUM_APU_CPUS;
}
static const TypeInfo xlnx_zcu102_machine_init_typeinfo = {
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
index d4b6560..c707c66 100644
--- a/hw/arm/xlnx-zynqmp.c
+++ b/hw/arm/xlnx-zynqmp.c
@@ -98,8 +98,9 @@ static void xlnx_zynqmp_create_rpu(XlnxZynqMPState *s, const char *boot_cpu,
{
Error *err = NULL;
int i;
+ int num_rpus = MIN(smp_cpus - XLNX_ZYNQMP_NUM_APU_CPUS, XLNX_ZYNQMP_NUM_RPU_CPUS);
- for (i = 0; i < XLNX_ZYNQMP_NUM_RPU_CPUS; i++) {
+ for (i = 0; i < num_rpus; i++) {
char *name;
object_initialize(&s->rpu_cpu[i], sizeof(s->rpu_cpu[i]),
@@ -132,8 +133,9 @@ static void xlnx_zynqmp_init(Object *obj)
{
XlnxZynqMPState *s = XLNX_ZYNQMP(obj);
int i;
+ int num_apus = MIN(smp_cpus, XLNX_ZYNQMP_NUM_APU_CPUS);
- for (i = 0; i < XLNX_ZYNQMP_NUM_APU_CPUS; i++) {
+ for (i = 0; i < num_apus; i++) {
object_initialize(&s->apu_cpu[i], sizeof(s->apu_cpu[i]),
"cortex-a53-" TYPE_ARM_CPU);
object_property_add_child(obj, "apu-cpu[*]", OBJECT(&s->apu_cpu[i]),
@@ -182,6 +184,7 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
MemoryRegion *system_memory = get_system_memory();
uint8_t i;
uint64_t ram_size;
+ int num_apus = MIN(smp_cpus, XLNX_ZYNQMP_NUM_APU_CPUS);
const char *boot_cpu = s->boot_cpu ? s->boot_cpu : "apu-cpu[0]";
ram_addr_t ddr_low_size, ddr_high_size;
qemu_irq gic_spi[GIC_NUM_SPI_INTR];
@@ -233,10 +236,10 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
qdev_prop_set_uint32(DEVICE(&s->gic), "num-irq", GIC_NUM_SPI_INTR + 32);
qdev_prop_set_uint32(DEVICE(&s->gic), "revision", 2);
- qdev_prop_set_uint32(DEVICE(&s->gic), "num-cpu", XLNX_ZYNQMP_NUM_APU_CPUS);
+ qdev_prop_set_uint32(DEVICE(&s->gic), "num-cpu", num_apus);
/* Realize APUs before realizing the GIC. KVM requires this. */
- for (i = 0; i < XLNX_ZYNQMP_NUM_APU_CPUS; i++) {
+ for (i = 0; i < num_apus; i++) {
char *name;
object_property_set_int(OBJECT(&s->apu_cpu[i]), QEMU_PSCI_CONDUIT_SMC,
@@ -292,7 +295,7 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
}
}
- for (i = 0; i < XLNX_ZYNQMP_NUM_APU_CPUS; i++) {
+ for (i = 0; i < num_apus; i++) {
qemu_irq irq;
sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), i,
@@ -307,11 +310,14 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
}
if (s->has_rpu) {
- xlnx_zynqmp_create_rpu(s, boot_cpu, &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
+ info_report("The 'has_rpu' property is no longer required, to use the "
+ "RPUs just use -smp 6.");
+ }
+
+ xlnx_zynqmp_create_rpu(s, boot_cpu, &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
}
if (!s->boot_cpu_ptr) {
diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index cc9816e..a1cc0e4 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -40,11 +40,17 @@
void icp_pic_print_info(ICPState *icp, Monitor *mon)
{
+ ICPStateClass *icpc = ICP_GET_CLASS(icp);
int cpu_index = icp->cs ? icp->cs->cpu_index : -1;
if (!icp->output) {
return;
}
+
+ if (icpc->synchronize_state) {
+ icpc->synchronize_state(icp);
+ }
+
monitor_printf(mon, "CPU %d XIRR=%08x (%p) PP=%02x MFRR=%02x\n",
cpu_index, icp->xirr, icp->xirr_owner,
icp->pending_priority, icp->mfrr);
@@ -52,6 +58,7 @@ void icp_pic_print_info(ICPState *icp, Monitor *mon)
void ics_pic_print_info(ICSState *ics, Monitor *mon)
{
+ ICSStateClass *icsc = ICS_BASE_GET_CLASS(ics);
uint32_t i;
monitor_printf(mon, "ICS %4x..%4x %p\n",
@@ -61,6 +68,10 @@ void ics_pic_print_info(ICSState *ics, Monitor *mon)
return;
}
+ if (icsc->synchronize_state) {
+ icsc->synchronize_state(ics);
+ }
+
for (i = 0; i < ics->nr_irqs; i++) {
ICSIRQState *irq = ics->irqs + i;
diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index 3091ad3..89fb20e 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -81,6 +81,18 @@ static void icp_get_kvm_state(ICPState *icp)
& KVM_REG_PPC_ICP_PPRI_MASK;
}
+static void do_icp_synchronize_state(CPUState *cpu, run_on_cpu_data arg)
+{
+ icp_get_kvm_state(arg.host_ptr);
+}
+
+static void icp_synchronize_state(ICPState *icp)
+{
+ if (icp->cs) {
+ run_on_cpu(icp->cs, do_icp_synchronize_state, RUN_ON_CPU_HOST_PTR(icp));
+ }
+}
+
static int icp_set_kvm_state(ICPState *icp, int version_id)
{
uint64_t state;
@@ -156,6 +168,7 @@ static void icp_kvm_class_init(ObjectClass *klass, void *data)
icpc->post_load = icp_set_kvm_state;
icpc->realize = icp_kvm_realize;
icpc->reset = icp_kvm_reset;
+ icpc->synchronize_state = icp_synchronize_state;
}
static const TypeInfo icp_kvm_info = {
@@ -234,6 +247,11 @@ static void ics_get_kvm_state(ICSState *ics)
}
}
+static void ics_synchronize_state(ICSState *ics)
+{
+ ics_get_kvm_state(ics);
+}
+
static int ics_set_kvm_state(ICSState *ics, int version_id)
{
uint64_t state;
@@ -347,6 +365,7 @@ static void ics_kvm_class_init(ObjectClass *klass, void *data)
icsc->realize = ics_kvm_realize;
icsc->pre_save = ics_get_kvm_state;
icsc->post_load = ics_set_kvm_state;
+ icsc->synchronize_state = ics_synchronize_state;
}
static const TypeInfo ics_kvm_info = {
diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c
index 80b8f47..a63ed2c 100644
--- a/hw/net/eepro100.c
+++ b/hw/net/eepro100.c
@@ -132,6 +132,7 @@ typedef struct {
const char *name;
const char *desc;
uint16_t device_id;
+ uint16_t alt_device_id;
uint8_t revision;
uint16_t subsystem_vendor_id;
uint16_t subsystem_id;
@@ -276,6 +277,7 @@ typedef struct {
/* Quasi static device properties (no need to save them). */
uint16_t stats_size;
bool has_extended_tcb_support;
+ bool use_alt_device_id;
} EEPRO100State;
/* Word indices in EEPROM. */
@@ -774,23 +776,11 @@ static void tx_command(EEPRO100State *s)
}
assert(tcb_bytes <= sizeof(buf));
while (size < tcb_bytes) {
- uint32_t tx_buffer_address = ldl_le_pci_dma(&s->dev, tbd_address);
- uint16_t tx_buffer_size = lduw_le_pci_dma(&s->dev, tbd_address + 4);
-#if 0
- uint16_t tx_buffer_el = lduw_le_pci_dma(&s->dev, tbd_address + 6);
-#endif
- if (tx_buffer_size == 0) {
- /* Prevent an endless loop. */
- logout("loop in %s:%u\n", __FILE__, __LINE__);
- break;
- }
- tbd_address += 8;
TRACE(RXTX, logout
("TBD (simplified mode): buffer address 0x%08x, size 0x%04x\n",
- tx_buffer_address, tx_buffer_size));
- tx_buffer_size = MIN(tx_buffer_size, sizeof(buf) - size);
- pci_dma_read(&s->dev, tx_buffer_address, &buf[size], tx_buffer_size);
- size += tx_buffer_size;
+ tbd_address, tcb_bytes));
+ pci_dma_read(&s->dev, tbd_address, &buf[size], tcb_bytes);
+ size += tcb_bytes;
}
if (tbd_array == 0xffffffff) {
/* Simplified mode. Was already handled by code above. */
@@ -1867,6 +1857,14 @@ static void e100_nic_realize(PCIDevice *pci_dev, Error **errp)
TRACE(OTHER, logout("\n"));
+ /* By default, the i82559a adapter uses the legacy PCI ID (for the
+ * i82557). This allows the PCI ID to be changed to the alternate
+ * i82559 ID if needed.
+ */
+ if (s->use_alt_device_id && strcmp(info->name, "i82559a") == 0) {
+ pci_config_set_device_id(s->dev.config, info->alt_device_id);
+ }
+
s->device = info->device;
e100_pci_reset(s, &local_err);
@@ -1986,6 +1984,7 @@ static E100PCIDeviceInfo e100_devices[] = {
.desc = "Intel i82559A Ethernet",
.device = i82559A,
.device_id = PCI_DEVICE_ID_INTEL_82557,
+ .alt_device_id = PCI_DEVICE_ID_INTEL_82559,
.revision = 0x06,
.stats_size = 80,
.has_extended_tcb_support = true,
@@ -2079,6 +2078,8 @@ static E100PCIDeviceInfo *eepro100_get_class(EEPRO100State *s)
static Property e100_properties[] = {
DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
+ DEFINE_PROP_BOOL("x-use-alt-device-id", EEPRO100State, use_alt_device_id,
+ true),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 0d59d15..be22a6b 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -1636,6 +1636,12 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
spapr->cas_legacy_guest_workaround = !spapr_ovec_test(ov1_guest,
OV1_PPC_3_00);
if (!spapr->cas_reboot) {
+ /* If ppc_spapr_reset() did not set up a HPT but one is necessary
+ * (because the guest isn't going to use radix) then set it up here. */
+ if ((spapr->patb_entry & PATBE1_GR) && !guest_radix) {
+ /* legacy hash or new hash: */
+ spapr_setup_hpt_and_vrma(spapr);
+ }
spapr->cas_reboot =
(spapr_h_cas_compose_response(spapr, args[1], args[2],
ov5_updates) != 0);
@@ -1644,13 +1650,6 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
if (spapr->cas_reboot) {
qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
- } else {
- /* If ppc_spapr_reset() did not set up a HPT but one is necessary
- * (because the guest isn't going to use radix) then set it up here. */
- if ((spapr->patb_entry & PATBE1_GR) && !guest_radix) {
- /* legacy hash or new hash: */
- spapr_setup_hpt_and_vrma(spapr);
- }
}
return H_SUCCESS;
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 923ece3..0f51c92 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -45,6 +45,17 @@ void restore_state_to_opc(CPUArchState *env, struct TranslationBlock *tb,
target_ulong *data);
void cpu_gen_init(void);
+
+/**
+ * cpu_restore_state:
+ * @cpu: the vCPU state is to be restore to
+ * @searched_pc: the host PC the fault occurred at
+ * @return: true if state was restored, false otherwise
+ *
+ * Attempt to restore the state for a fault occurring in translated
+ * code. If the searched_pc is not in translated code no state is
+ * restored and the function returns false.
+ */
bool cpu_restore_state(CPUState *cpu, uintptr_t searched_pc);
void QEMU_NORETURN cpu_loop_exit_noexc(CPUState *cpu);
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 191a5b3..62f160e 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -102,6 +102,9 @@ typedef struct {
/**
* MachineClass:
+ * @max_cpus: maximum number of CPUs supported. Default: 1
+ * @min_cpus: minimum number of CPUs supported. Default: 1
+ * @default_cpus: number of CPUs instantiated if none are specified. Default: 1
* @get_hotplug_handler: this function is called during bus-less
* device hotplug. If defined it returns pointer to an instance
* of HotplugHandler object, which handles hotplug operation
@@ -167,6 +170,8 @@ struct MachineClass {
BlockInterfaceType block_default_type;
int units_per_default_bus;
int max_cpus;
+ int min_cpus;
+ int default_cpus;
unsigned int no_serial:1,
no_parallel:1,
use_virtcon:1,
diff --git a/include/hw/compat.h b/include/hw/compat.h
index cf389b4..f96212c 100644
--- a/include/hw/compat.h
+++ b/include/hw/compat.h
@@ -10,6 +10,10 @@
.driver = "virtio-tablet-device",\
.property = "wheel-axis",\
.value = "false",\
+ },{\
+ .driver = "i82559a",\
+ .property = "x-use-alt-device-id",\
+ .value = "false",\
},
#define HW_COMPAT_2_9 \
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 8d02a0a..f30e2cf 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -70,6 +70,7 @@ extern bool pci_available;
/* Intel (0x8086) */
#define PCI_DEVICE_ID_INTEL_82551IT 0x1209
#define PCI_DEVICE_ID_INTEL_82557 0x1229
+#define PCI_DEVICE_ID_INTEL_82559 0x1030
#define PCI_DEVICE_ID_INTEL_82801IR 0x2922
/* Red Hat / Qumranet (for QEMU) -- see pci-ids.txt */
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index 28d248a..2df99be 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -69,6 +69,7 @@ struct ICPStateClass {
void (*pre_save)(ICPState *icp);
int (*post_load)(ICPState *icp, int version_id);
void (*reset)(ICPState *icp);
+ void (*synchronize_state)(ICPState *icp);
};
struct ICPState {
@@ -119,6 +120,7 @@ struct ICSStateClass {
void (*reject)(ICSState *s, uint32_t irq);
void (*resend)(ICSState *s);
void (*eoi)(ICSState *s, uint32_t irq);
+ void (*synchronize_state)(ICSState *s);
};
struct ICSState {
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index fa4b0c9..c2fa151 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -209,7 +209,6 @@ typedef struct CPUClass {
/* Keep non-pointer data at the end to minimize holes. */
int gdb_num_core_regs;
bool gdb_stop_before_watchpoint;
- bool tcg_initialized;
} CPUClass;
#ifdef HOST_WORDS_BIGENDIAN
diff --git a/net/colo-compare.c b/net/colo-compare.c
index b3f35d7..ccdcba2 100644
--- a/net/colo-compare.c
+++ b/net/colo-compare.c
@@ -113,10 +113,30 @@ static gint seq_sorter(Packet *a, Packet *b, gpointer data)
}
/*
+ * Return 1 on success, if return 0 means the
+ * packet will be dropped
+ */
+static int colo_insert_packet(GQueue *queue, Packet *pkt)
+{
+ if (g_queue_get_length(queue) <= MAX_QUEUE_SIZE) {
+ if (pkt->ip->ip_p == IPPROTO_TCP) {
+ g_queue_insert_sorted(queue,
+ pkt,
+ (GCompareDataFunc)seq_sorter,
+ NULL);
+ } else {
+ g_queue_push_tail(queue, pkt);
+ }
+ return 1;
+ }
+ return 0;
+}
+
+/*
* Return 0 on success, if return -1 means the pkt
* is unsupported(arp and ipv6) and will be sent later
*/
-static int packet_enqueue(CompareState *s, int mode)
+static int packet_enqueue(CompareState *s, int mode, Connection **con)
{
ConnectionKey key;
Packet *pkt = NULL;
@@ -149,32 +169,17 @@ static int packet_enqueue(CompareState *s, int mode)
}
if (mode == PRIMARY_IN) {
- if (g_queue_get_length(&conn->primary_list) <=
- MAX_QUEUE_SIZE) {
- g_queue_push_tail(&conn->primary_list, pkt);
- if (conn->ip_proto == IPPROTO_TCP) {
- g_queue_sort(&conn->primary_list,
- (GCompareDataFunc)seq_sorter,
- NULL);
- }
- } else {
+ if (!colo_insert_packet(&conn->primary_list, pkt)) {
error_report("colo compare primary queue size too big,"
"drop packet");
}
} else {
- if (g_queue_get_length(&conn->secondary_list) <=
- MAX_QUEUE_SIZE) {
- g_queue_push_tail(&conn->secondary_list, pkt);
- if (conn->ip_proto == IPPROTO_TCP) {
- g_queue_sort(&conn->secondary_list,
- (GCompareDataFunc)seq_sorter,
- NULL);
- }
- } else {
+ if (!colo_insert_packet(&conn->secondary_list, pkt)) {
error_report("colo compare secondary queue size too big,"
"drop packet");
}
}
+ con = &conn;
return 0;
}
@@ -475,7 +480,9 @@ static void colo_old_packet_check(void *opaque)
/*
* Called from the compare thread on the primary
- * for compare connection
+ * for compare packet with secondary list of the
+ * specified connection when a new packet was
+ * queued to it.
*/
static void colo_compare_connection(void *opaque, void *user_data)
{
@@ -724,28 +731,30 @@ static void compare_set_vnet_hdr(Object *obj,
static void compare_pri_rs_finalize(SocketReadState *pri_rs)
{
CompareState *s = container_of(pri_rs, CompareState, pri_rs);
+ Connection *conn = NULL;
- if (packet_enqueue(s, PRIMARY_IN)) {
+ if (packet_enqueue(s, PRIMARY_IN, &conn)) {
trace_colo_compare_main("primary: unsupported packet in");
compare_chr_send(s,
pri_rs->buf,
pri_rs->packet_len,
pri_rs->vnet_hdr_len);
} else {
- /* compare connection */
- g_queue_foreach(&s->conn_list, colo_compare_connection, s);
+ /* compare packet in the specified connection */
+ colo_compare_connection(conn, s);
}
}
static void compare_sec_rs_finalize(SocketReadState *sec_rs)
{
CompareState *s = container_of(sec_rs, CompareState, sec_rs);
+ Connection *conn = NULL;
- if (packet_enqueue(s, SECONDARY_IN)) {
+ if (packet_enqueue(s, SECONDARY_IN, &conn)) {
trace_colo_compare_main("secondary: unsupported packet in");
} else {
- /* compare connection */
- g_queue_foreach(&s->conn_list, colo_compare_connection, s);
+ /* compare packet in the specified connection */
+ colo_compare_connection(conn, s);
}
}
diff --git a/net/colo.c b/net/colo.c
index 28ce7c8..a39d600 100644
--- a/net/colo.c
+++ b/net/colo.c
@@ -82,6 +82,14 @@ int parse_packet_early(Packet *pkt)
return 0;
}
+void extract_ip_and_port(uint32_t tmp_ports, ConnectionKey *key, Packet *pkt)
+{
+ key->src = pkt->ip->ip_src;
+ key->dst = pkt->ip->ip_dst;
+ key->src_port = ntohs(tmp_ports >> 16);
+ key->dst_port = ntohs(tmp_ports & 0xffff);
+}
+
void fill_connection_key(Packet *pkt, ConnectionKey *key)
{
uint32_t tmp_ports;
@@ -97,17 +105,11 @@ void fill_connection_key(Packet *pkt, ConnectionKey *key)
case IPPROTO_SCTP:
case IPPROTO_UDPLITE:
tmp_ports = *(uint32_t *)(pkt->transport_header);
- key->src = pkt->ip->ip_src;
- key->dst = pkt->ip->ip_dst;
- key->src_port = ntohs(tmp_ports & 0xffff);
- key->dst_port = ntohs(tmp_ports >> 16);
+ extract_ip_and_port(tmp_ports, key, pkt);
break;
case IPPROTO_AH:
tmp_ports = *(uint32_t *)(pkt->transport_header + 4);
- key->src = pkt->ip->ip_src;
- key->dst = pkt->ip->ip_dst;
- key->src_port = ntohs(tmp_ports & 0xffff);
- key->dst_port = ntohs(tmp_ports >> 16);
+ extract_ip_and_port(tmp_ports, key, pkt);
break;
default:
break;
diff --git a/net/colo.h b/net/colo.h
index caedb0d..0658e86 100644
--- a/net/colo.h
+++ b/net/colo.h
@@ -76,6 +76,7 @@ typedef struct Connection {
uint32_t connection_key_hash(const void *opaque);
int connection_key_equal(const void *opaque1, const void *opaque2);
int parse_packet_early(Packet *pkt);
+void extract_ip_and_port(uint32_t tmp_ports, ConnectionKey *key, Packet *pkt);
void fill_connection_key(Packet *pkt, ConnectionKey *key);
void reverse_connection_key(ConnectionKey *key);
Connection *connection_new(ConnectionKey *key);
diff --git a/net/socket.c b/net/socket.c
index e6b471c..6917fbc 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -373,7 +373,7 @@ static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer,
net_socket_read_poll(s, true);
/* mcast: save bound address as dst */
- if (is_connected) {
+ if (is_connected && mcast != NULL) {
s->dgram_dst = saddr;
snprintf(nc->info_str, sizeof(nc->info_str),
"socket: fd=%d (cloned mcast=%s:%d)",
@@ -695,8 +695,8 @@ int net_init_socket(const Netdev *netdev, const char *name,
assert(netdev->type == NET_CLIENT_DRIVER_SOCKET);
sock = &netdev->u.socket;
- if (sock->has_listen + sock->has_connect + sock->has_mcast +
- sock->has_udp > 1) {
+ if (sock->has_fd + sock->has_listen + sock->has_connect + sock->has_mcast +
+ sock->has_udp != 1) {
error_setg(errp, "exactly one of listen=, connect=, mcast= or udp="
" is required");
return -1;
diff --git a/qemu-doc.texi b/qemu-doc.texi
index 8c10956..d383ac4 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -2537,6 +2537,13 @@ or ``ivshmem-doorbell`` device types.
The ``spapr-pci-vfio-host-bridge'' device type is replaced by
the ``spapr-pci-host-bridge'' device type.
+@section System emulator machines
+
+@subsection Xilinx EP108 (since 2.11.0)
+
+The ``xlnx-ep108'' machine has been replaced by the ``xlnx-zcu102'' machine.
+The ``xlnx-zcu102'' machine has the same features and capabilites in QEMU.
+
@node License
@appendix License
diff --git a/qemu-options.hx b/qemu-options.hx
index 3728e9b..a39c7e4 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2047,7 +2047,7 @@ that the card should have; this option currently only affects virtio cards; set
@var{v} = 0 to disable MSI-X. If no @option{-net} option is specified, a single
NIC is created. QEMU can emulate several different models of network card.
Valid values for @var{type} are
-@code{virtio}, @code{i82551}, @code{i82557b}, @code{i82559er},
+@code{virtio}, @code{i82551}, @code{i82557b}, @code{i82559a}, @code{i82559er},
@code{ne2k_pci}, @code{ne2k_isa}, @code{pcnet}, @code{rtl8139},
@code{e1000}, @code{smc91c111}, @code{lance} and @code{mcf_fec}.
Not all devices are supported on all targets. Use @code{-net nic,model=help}
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index caca05a..625ef2d 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -2351,6 +2351,8 @@ static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn,
post_index = false;
writeback = true;
break;
+ default:
+ g_assert_not_reached();
}
if (rn == 31) {
diff --git a/tests/qemu-iotests/093 b/tests/qemu-iotests/093
index ef39972..5c36a5f 100755
--- a/tests/qemu-iotests/093
+++ b/tests/qemu-iotests/093
@@ -308,6 +308,68 @@ class ThrottleTestGroupNames(iotests.QMPTestCase):
groupname = "group%d" % i
self.verify_name(devname, groupname)
+class ThrottleTestRemovableMedia(iotests.QMPTestCase):
+ def setUp(self):
+ self.vm = iotests.VM()
+ if iotests.qemu_default_machine == 's390-ccw-virtio':
+ self.vm.add_device("virtio-scsi-ccw,id=virtio-scsi")
+ else:
+ self.vm.add_device("virtio-scsi-pci,id=virtio-scsi")
+ self.vm.launch()
+
+ def tearDown(self):
+ self.vm.shutdown()
+
+ def test_removable_media(self):
+ # Add a couple of dummy nodes named cd0 and cd1
+ result = self.vm.qmp("blockdev-add", driver="null-aio",
+ node_name="cd0")
+ self.assert_qmp(result, 'return', {})
+ result = self.vm.qmp("blockdev-add", driver="null-aio",
+ node_name="cd1")
+ self.assert_qmp(result, 'return', {})
+
+ # Attach a CD drive with cd0 inserted
+ result = self.vm.qmp("device_add", driver="scsi-cd",
+ id="dev0", drive="cd0")
+ self.assert_qmp(result, 'return', {})
+
+ # Set I/O limits
+ args = { "id": "dev0", "iops": 100, "iops_rd": 0, "iops_wr": 0,
+ "bps": 50, "bps_rd": 0, "bps_wr": 0 }
+ result = self.vm.qmp("block_set_io_throttle", conv_keys=False, **args)
+ self.assert_qmp(result, 'return', {})
+
+ # Check that the I/O limits have been set
+ result = self.vm.qmp("query-block")
+ self.assert_qmp(result, 'return[0]/inserted/iops', 100)
+ self.assert_qmp(result, 'return[0]/inserted/bps', 50)
+
+ # Now eject cd0 and insert cd1
+ result = self.vm.qmp("blockdev-open-tray", id='dev0')
+ self.assert_qmp(result, 'return', {})
+ result = self.vm.qmp("x-blockdev-remove-medium", id='dev0')
+ self.assert_qmp(result, 'return', {})
+ result = self.vm.qmp("x-blockdev-insert-medium", id='dev0', node_name='cd1')
+ self.assert_qmp(result, 'return', {})
+
+ # Check that the I/O limits are still the same
+ result = self.vm.qmp("query-block")
+ self.assert_qmp(result, 'return[0]/inserted/iops', 100)
+ self.assert_qmp(result, 'return[0]/inserted/bps', 50)
+
+ # Eject cd1
+ result = self.vm.qmp("x-blockdev-remove-medium", id='dev0')
+ self.assert_qmp(result, 'return', {})
+
+ # Check that we can't set limits if the device has no medium
+ result = self.vm.qmp("block_set_io_throttle", conv_keys=False, **args)
+ self.assert_qmp(result, 'error/class', 'GenericError')
+
+ # Remove the CD drive
+ result = self.vm.qmp("device_del", id='dev0')
+ self.assert_qmp(result, 'return', {})
+
if __name__ == '__main__':
iotests.main(supported_fmts=["raw"])
diff --git a/tests/qemu-iotests/093.out b/tests/qemu-iotests/093.out
index 2f7d390..594c16f 100644
--- a/tests/qemu-iotests/093.out
+++ b/tests/qemu-iotests/093.out
@@ -1,5 +1,5 @@
-.......
+........
----------------------------------------------------------------------
-Ran 7 tests
+Ran 8 tests
OK
diff --git a/vl.c b/vl.c
index ec29909..7372424 100644
--- a/vl.c
+++ b/vl.c
@@ -160,8 +160,8 @@ Chardev *virtcon_hds[MAX_VIRTIO_CONSOLES];
Chardev *sclp_hds[MAX_SCLP_CONSOLES];
int win2k_install_hack = 0;
int singlestep = 0;
-int smp_cpus = 1;
-unsigned int max_cpus = 1;
+int smp_cpus;
+unsigned int max_cpus;
int smp_cores = 1;
int smp_threads = 1;
int acpi_enabled = 1;
@@ -4327,9 +4327,24 @@ int main(int argc, char **argv, char **envp)
exit(0);
}
+ /* machine_class: default to UP */
+ machine_class->max_cpus = machine_class->max_cpus ?: 1;
+ machine_class->min_cpus = machine_class->min_cpus ?: 1;
+ machine_class->default_cpus = machine_class->default_cpus ?: 1;
+
+ /* default to machine_class->default_cpus */
+ smp_cpus = machine_class->default_cpus;
+ max_cpus = machine_class->default_cpus;
+
smp_parse(qemu_opts_find(qemu_find_opts("smp-opts"), NULL));
- machine_class->max_cpus = machine_class->max_cpus ?: 1; /* Default to UP */
+ /* sanity-check smp_cpus and max_cpus against machine_class */
+ if (smp_cpus < machine_class->min_cpus) {
+ error_report("Invalid SMP CPUs %d. The min CPUs "
+ "supported by machine '%s' is %d", smp_cpus,
+ machine_class->name, machine_class->min_cpus);
+ exit(1);
+ }
if (max_cpus > machine_class->max_cpus) {
error_report("Invalid SMP CPUs %d. The max CPUs "
"supported by machine '%s' is %d", max_cpus,