Merge remote-tracking branch 'remotes/kraxel/tags/seabios-20191118-pull-request' into staging
seabios: update to pre-1.13 snapshot again (lchs fixed)
# gpg: Signature made Mon 18 Nov 2019 14:23:50 GMT
# gpg: using RSA key 4CB6D8EED3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" [full]
# gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" [full]
# gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" [full]
# Primary key fingerprint: A032 8CFF B93A 17A7 9901 FE7D 4CB6 D8EE D3E8 7138
* remotes/kraxel/tags/seabios-20191118-pull-request:
seabios: update to pre-1.13 snapshot again
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
diff --git a/.travis.yml b/.travis.yml
index 678e33d..b9a026c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -77,7 +77,7 @@
- SRC_DIR="."
- BUILD_DIR="."
- BASE_CONFIG="--disable-docs --disable-tools"
- - TEST_CMD="make check -j3 V=1"
+ - TEST_CMD="make check V=1"
# This is broadly a list of "mainline" softmmu targets which have support across the major distros
- MAIN_SOFTMMU_TARGETS="aarch64-softmmu,arm-softmmu,i386-softmmu,mips-softmmu,mips64-softmmu,ppc64-softmmu,riscv64-softmmu,s390x-softmmu,x86_64-softmmu"
- CCACHE_SLOPPINESS="include_file_ctime,include_file_mtime"
diff --git a/MAINTAINERS b/MAINTAINERS
index 363e72a..ff8d0d2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2143,13 +2143,11 @@
SLIRP
M: Samuel Thibault <samuel.thibault@ens-lyon.org>
-M: Jan Kiszka <jan.kiszka@siemens.com>
S: Maintained
F: slirp/
F: net/slirp.c
F: include/net/slirp.h
T: git https://people.debian.org/~sthibault/qemu.git slirp
-T: git git://git.kiszka.org/qemu.git queues/slirp
Stubs
M: Paolo Bonzini <pbonzini@redhat.com>
diff --git a/Makefile b/Makefile
index aa9d1a4..b437a34 100644
--- a/Makefile
+++ b/Makefile
@@ -480,7 +480,9 @@
$(SOFTMMU_ALL_RULES): $(crypto-obj-y)
$(SOFTMMU_ALL_RULES): $(io-obj-y)
$(SOFTMMU_ALL_RULES): config-all-devices.mak
+ifdef DECOMPRESS_EDK2_BLOBS
$(SOFTMMU_ALL_RULES): $(edk2-decompressed)
+endif
.PHONY: $(TARGET_DIRS_RULES)
# The $(TARGET_DIRS_RULES) are of the form SUBDIR/GOAL, so that
@@ -771,7 +773,7 @@
bepo cz
ifdef INSTALL_BLOBS
-BLOBS=bios.bin bios-256k.bin sgabios.bin vgabios.bin vgabios-cirrus.bin \
+BLOBS=bios.bin bios-256k.bin bios-microvm.bin sgabios.bin vgabios.bin vgabios-cirrus.bin \
vgabios-stdvga.bin vgabios-vmware.bin vgabios-qxl.bin vgabios-virtio.bin \
vgabios-ramfb.bin vgabios-bochs-display.bin vgabios-ati.bin \
ppc_rom.bin openbios-sparc32 openbios-sparc64 openbios-ppc QEMU,tcx.bin QEMU,cgthree.bin \
diff --git a/VERSION b/VERSION
index b9d9a64..cfcbdd7 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-4.1.90
+4.1.91
diff --git a/configure b/configure
index efe165e..6099be1 100755
--- a/configure
+++ b/configure
@@ -427,6 +427,7 @@
linux_user="no"
bsd_user="no"
blobs="yes"
+edk2_blobs="no"
pkgversion=""
pie=""
qom_cast_debug="yes"
@@ -2146,6 +2147,18 @@
;;
esac
+for target in $target_list; do
+ case "$target" in
+ arm-softmmu | aarch64-softmmu | i386-softmmu | x86_64-softmmu)
+ edk2_blobs="yes"
+ ;;
+ esac
+done
+# The EDK2 binaries are compressed with bzip2
+if test "$edk2_blobs" = "yes" && ! has bzip2; then
+ error_exit "The bzip2 program is required for building QEMU"
+fi
+
feature_not_found() {
feature=$1
remedy=$2
@@ -7526,6 +7539,10 @@
echo "LIBUDEV_LIBS=$libudev_libs" >> $config_host_mak
fi
+if test "$edk2_blobs" = "yes" ; then
+ echo "DECOMPRESS_EDK2_BLOBS=y" >> $config_host_mak
+fi
+
# use included Linux headers
if test "$linux" = "yes" ; then
mkdir -p linux-headers
diff --git a/contrib/ivshmem-server/ivshmem-server.c b/contrib/ivshmem-server/ivshmem-server.c
index 77f97b2..88daee8 100644
--- a/contrib/ivshmem-server/ivshmem-server.c
+++ b/contrib/ivshmem-server/ivshmem-server.c
@@ -353,6 +353,9 @@
err_close_sock:
close(sock_fd);
err_close_shm:
+ if (server->use_shm_open) {
+ shm_unlink(server->shm_path);
+ }
close(shm_fd);
return -1;
}
@@ -370,6 +373,9 @@
}
unlink(server->unix_sock_path);
+ if (server->use_shm_open) {
+ shm_unlink(server->shm_path);
+ }
close(server->sock_fd);
close(server->shm_fd);
server->sock_fd = -1;
diff --git a/contrib/ivshmem-server/main.c b/contrib/ivshmem-server/main.c
index 197c79c..e4cd35f 100644
--- a/contrib/ivshmem-server/main.c
+++ b/contrib/ivshmem-server/main.c
@@ -223,8 +223,9 @@
sa_quit.sa_handler = ivshmem_server_quit_cb;
sa_quit.sa_flags = 0;
if (sigemptyset(&sa_quit.sa_mask) == -1 ||
- sigaction(SIGTERM, &sa_quit, 0) == -1) {
- perror("failed to add SIGTERM handler; sigaction");
+ sigaction(SIGTERM, &sa_quit, 0) == -1 ||
+ sigaction(SIGINT, &sa_quit, 0) == -1) {
+ perror("failed to add signal handler; sigaction");
goto err;
}
diff --git a/hw/core/numa.c b/hw/core/numa.c
index 038c96d..e3332a9 100644
--- a/hw/core/numa.c
+++ b/hw/core/numa.c
@@ -503,7 +503,7 @@
warn_report("falling back to regular RAM allocation");
error_printf("This is deprecated. Make sure that -mem-path "
" specified path has sufficient resources to allocate"
- " -m specified RAM amount");
+ " -m specified RAM amount\n");
/* Legacy behavior: if allocation failed, fall back to
* regular RAM allocation.
*/
diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index d8e1291..9cb8d38 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -555,6 +555,15 @@
xive_tctx_set_os_cam(tctx, xive_nvt_cam_line(nvt_blk, nvt_idx));
}
+static void spapr_xive_cpu_intc_destroy(SpaprInterruptController *intc,
+ PowerPCCPU *cpu)
+{
+ SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
+
+ xive_tctx_destroy(spapr_cpu->tctx);
+ spapr_cpu->tctx = NULL;
+}
+
static void spapr_xive_set_irq(SpaprInterruptController *intc, int irq, int val)
{
SpaprXive *xive = SPAPR_XIVE(intc);
@@ -692,6 +701,7 @@
sicc->deactivate = spapr_xive_deactivate;
sicc->cpu_intc_create = spapr_xive_cpu_intc_create;
sicc->cpu_intc_reset = spapr_xive_cpu_intc_reset;
+ sicc->cpu_intc_destroy = spapr_xive_cpu_intc_destroy;
sicc->claim_irq = spapr_xive_claim_irq;
sicc->free_irq = spapr_xive_free_irq;
sicc->set_irq = spapr_xive_set_irq;
diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 6da0576..e7ac9ba 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -44,7 +44,16 @@
void icp_pic_print_info(ICPState *icp, Monitor *mon)
{
- int cpu_index = icp->cs ? icp->cs->cpu_index : -1;
+ int cpu_index;
+
+ /* Skip partially initialized vCPUs. This can happen on sPAPR when vCPUs
+ * are hot plugged or unplugged.
+ */
+ if (!icp) {
+ return;
+ }
+
+ cpu_index = icp->cs ? icp->cs->cpu_index : -1;
if (!icp->output) {
return;
@@ -388,8 +397,10 @@
obj = object_new(type);
object_property_add_child(cpu, type, obj, &error_abort);
object_unref(obj);
+ object_ref(OBJECT(xi));
object_property_add_const_link(obj, ICP_PROP_XICS, OBJECT(xi),
&error_abort);
+ object_ref(cpu);
object_property_add_const_link(obj, ICP_PROP_CPU, cpu, &error_abort);
object_property_set_bool(obj, true, "realized", &local_err);
if (local_err) {
@@ -401,6 +412,15 @@
return obj;
}
+void icp_destroy(ICPState *icp)
+{
+ Object *obj = OBJECT(icp);
+
+ object_unref(object_property_get_link(obj, ICP_PROP_CPU, &error_abort));
+ object_unref(object_property_get_link(obj, ICP_PROP_XICS, &error_abort));
+ object_unparent(obj);
+}
+
/*
* ICS: Source layer
*/
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 7418fb9..b3705da 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -352,6 +352,15 @@
icp_reset(spapr_cpu_state(cpu)->icp);
}
+static void xics_spapr_cpu_intc_destroy(SpaprInterruptController *intc,
+ PowerPCCPU *cpu)
+{
+ SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
+
+ icp_destroy(spapr_cpu->icp);
+ spapr_cpu->icp = NULL;
+}
+
static int xics_spapr_claim_irq(SpaprInterruptController *intc, int irq,
bool lsi, Error **errp)
{
@@ -440,6 +449,7 @@
sicc->deactivate = xics_spapr_deactivate;
sicc->cpu_intc_create = xics_spapr_cpu_intc_create;
sicc->cpu_intc_reset = xics_spapr_cpu_intc_reset;
+ sicc->cpu_intc_destroy = xics_spapr_cpu_intc_destroy;
sicc->claim_irq = xics_spapr_claim_irq;
sicc->free_irq = xics_spapr_free_irq;
sicc->set_irq = xics_spapr_set_irq;
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index f066be5..75dce82 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -523,9 +523,18 @@
void xive_tctx_pic_print_info(XiveTCTX *tctx, Monitor *mon)
{
- int cpu_index = tctx->cs ? tctx->cs->cpu_index : -1;
+ int cpu_index;
int i;
+ /* Skip partially initialized vCPUs. This can happen on sPAPR when vCPUs
+ * are hot plugged or unplugged.
+ */
+ if (!tctx) {
+ return;
+ }
+
+ cpu_index = tctx->cs ? tctx->cs->cpu_index : -1;
+
if (kvm_irqchip_in_kernel()) {
Error *local_err = NULL;
@@ -682,6 +691,7 @@
obj = object_new(TYPE_XIVE_TCTX);
object_property_add_child(cpu, TYPE_XIVE_TCTX, obj, &error_abort);
object_unref(obj);
+ object_ref(cpu);
object_property_add_const_link(obj, "cpu", cpu, &error_abort);
object_property_set_bool(obj, true, "realized", &local_err);
if (local_err) {
@@ -696,6 +706,14 @@
return NULL;
}
+void xive_tctx_destroy(XiveTCTX *tctx)
+{
+ Object *obj = OBJECT(tctx);
+
+ object_unref(object_property_get_link(obj, "cpu", &error_abort));
+ object_unparent(obj);
+}
+
/*
* XIVE ESB helpers
*/
diff --git a/hw/misc/mos6522.c b/hw/misc/mos6522.c
index 57f13db..aa3bfe1 100644
--- a/hw/misc/mos6522.c
+++ b/hw/misc/mos6522.c
@@ -38,8 +38,10 @@
/* XXX: implement all timer modes */
-static void mos6522_timer_update(MOS6522State *s, MOS6522Timer *ti,
- int64_t current_time);
+static void mos6522_timer1_update(MOS6522State *s, MOS6522Timer *ti,
+ int64_t current_time);
+static void mos6522_timer2_update(MOS6522State *s, MOS6522Timer *ti,
+ int64_t current_time);
static void mos6522_update_irq(MOS6522State *s)
{
@@ -98,7 +100,11 @@
trace_mos6522_set_counter(1 + ti->index, val);
ti->load_time = get_load_time(s, ti);
ti->counter_value = val;
- mos6522_timer_update(s, ti, ti->load_time);
+ if (ti->index == 0) {
+ mos6522_timer1_update(s, ti, ti->load_time);
+ } else {
+ mos6522_timer2_update(s, ti, ti->load_time);
+ }
}
static int64_t get_next_irq_time(MOS6522State *s, MOS6522Timer *ti,
@@ -130,19 +136,34 @@
trace_mos6522_get_next_irq_time(ti->latch, d, next_time - d);
next_time = muldiv64(next_time, NANOSECONDS_PER_SECOND, ti->frequency) +
ti->load_time;
+
if (next_time <= current_time) {
next_time = current_time + 1;
}
return next_time;
}
-static void mos6522_timer_update(MOS6522State *s, MOS6522Timer *ti,
+static void mos6522_timer1_update(MOS6522State *s, MOS6522Timer *ti,
int64_t current_time)
{
if (!ti->timer) {
return;
}
- if (ti->index == 0 && (s->acr & T1MODE) != T1MODE_CONT) {
+ if ((s->ier & T1_INT) == 0 || (s->acr & T1MODE) != T1MODE_CONT) {
+ timer_del(ti->timer);
+ } else {
+ ti->next_irq_time = get_next_irq_time(s, ti, current_time);
+ timer_mod(ti->timer, ti->next_irq_time);
+ }
+}
+
+static void mos6522_timer2_update(MOS6522State *s, MOS6522Timer *ti,
+ int64_t current_time)
+{
+ if (!ti->timer) {
+ return;
+ }
+ if ((s->ier & T2_INT) == 0) {
timer_del(ti->timer);
} else {
ti->next_irq_time = get_next_irq_time(s, ti, current_time);
@@ -155,7 +176,7 @@
MOS6522State *s = opaque;
MOS6522Timer *ti = &s->timers[0];
- mos6522_timer_update(s, ti, ti->next_irq_time);
+ mos6522_timer1_update(s, ti, ti->next_irq_time);
s->ifr |= T1_INT;
mos6522_update_irq(s);
}
@@ -165,7 +186,7 @@
MOS6522State *s = opaque;
MOS6522Timer *ti = &s->timers[1];
- mos6522_timer_update(s, ti, ti->next_irq_time);
+ mos6522_timer2_update(s, ti, ti->next_irq_time);
s->ifr |= T2_INT;
mos6522_update_irq(s);
}
@@ -204,7 +225,16 @@
{
MOS6522State *s = opaque;
uint32_t val;
+ int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+ if (now >= s->timers[0].next_irq_time) {
+ mos6522_timer1_update(s, &s->timers[0], now);
+ s->ifr |= T1_INT;
+ }
+ if (now >= s->timers[1].next_irq_time) {
+ mos6522_timer2_update(s, &s->timers[1], now);
+ s->ifr |= T2_INT;
+ }
switch (addr) {
case VIA_REG_B:
val = s->b;
@@ -299,8 +329,8 @@
break;
case VIA_REG_T1CL:
s->timers[0].latch = (s->timers[0].latch & 0xff00) | val;
- mos6522_timer_update(s, &s->timers[0],
- qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
+ mos6522_timer1_update(s, &s->timers[0],
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
break;
case VIA_REG_T1CH:
s->timers[0].latch = (s->timers[0].latch & 0xff) | (val << 8);
@@ -309,14 +339,14 @@
break;
case VIA_REG_T1LL:
s->timers[0].latch = (s->timers[0].latch & 0xff00) | val;
- mos6522_timer_update(s, &s->timers[0],
- qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
+ mos6522_timer1_update(s, &s->timers[0],
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
break;
case VIA_REG_T1LH:
s->timers[0].latch = (s->timers[0].latch & 0xff) | (val << 8);
s->ifr &= ~T1_INT;
- mos6522_timer_update(s, &s->timers[0],
- qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
+ mos6522_timer1_update(s, &s->timers[0],
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
break;
case VIA_REG_T2CL:
s->timers[1].latch = (s->timers[1].latch & 0xff00) | val;
@@ -334,8 +364,8 @@
break;
case VIA_REG_ACR:
s->acr = val;
- mos6522_timer_update(s, &s->timers[0],
- qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
+ mos6522_timer1_update(s, &s->timers[0],
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
break;
case VIA_REG_PCR:
s->pcr = val;
@@ -354,6 +384,11 @@
s->ier &= ~val;
}
mos6522_update_irq(s);
+ /* if IER is modified starts needed timers */
+ mos6522_timer1_update(s, &s->timers[0],
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
+ mos6522_timer2_update(s, &s->timers[1],
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
break;
default:
case VIA_REG_ANH:
@@ -426,9 +461,11 @@
s->timers[0].frequency = s->frequency;
s->timers[0].latch = 0xffff;
set_counter(s, &s->timers[0], 0xffff);
+ timer_del(s->timers[0].timer);
s->timers[1].frequency = s->frequency;
s->timers[1].latch = 0xffff;
+ timer_del(s->timers[1].timer);
}
static void mos6522_init(Object *obj)
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 6063272..627c08e 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -778,6 +778,7 @@
pnv_cpu->intc = obj;
}
+
static void pnv_chip_power8_intc_reset(PnvChip *chip, PowerPCCPU *cpu)
{
PnvCPUState *pnv_cpu = pnv_cpu_state(cpu);
@@ -785,6 +786,14 @@
icp_reset(ICP(pnv_cpu->intc));
}
+static void pnv_chip_power8_intc_destroy(PnvChip *chip, PowerPCCPU *cpu)
+{
+ PnvCPUState *pnv_cpu = pnv_cpu_state(cpu);
+
+ icp_destroy(ICP(pnv_cpu->intc));
+ pnv_cpu->intc = NULL;
+}
+
/*
* 0:48 Reserved - Read as zeroes
* 49:52 Node ID
@@ -829,6 +838,14 @@
xive_tctx_reset(XIVE_TCTX(pnv_cpu->intc));
}
+static void pnv_chip_power9_intc_destroy(PnvChip *chip, PowerPCCPU *cpu)
+{
+ PnvCPUState *pnv_cpu = pnv_cpu_state(cpu);
+
+ xive_tctx_destroy(XIVE_TCTX(pnv_cpu->intc));
+ pnv_cpu->intc = NULL;
+}
+
/*
* Allowed core identifiers on a POWER8 Processor Chip :
*
@@ -999,6 +1016,7 @@
k->core_pir = pnv_chip_core_pir_p8;
k->intc_create = pnv_chip_power8_intc_create;
k->intc_reset = pnv_chip_power8_intc_reset;
+ k->intc_destroy = pnv_chip_power8_intc_destroy;
k->isa_create = pnv_chip_power8_isa_create;
k->dt_populate = pnv_chip_power8_dt_populate;
k->pic_print_info = pnv_chip_power8_pic_print_info;
@@ -1019,6 +1037,7 @@
k->core_pir = pnv_chip_core_pir_p8;
k->intc_create = pnv_chip_power8_intc_create;
k->intc_reset = pnv_chip_power8_intc_reset;
+ k->intc_destroy = pnv_chip_power8_intc_destroy;
k->isa_create = pnv_chip_power8_isa_create;
k->dt_populate = pnv_chip_power8_dt_populate;
k->pic_print_info = pnv_chip_power8_pic_print_info;
@@ -1039,6 +1058,7 @@
k->core_pir = pnv_chip_core_pir_p8;
k->intc_create = pnv_chip_power8_intc_create;
k->intc_reset = pnv_chip_power8_intc_reset;
+ k->intc_destroy = pnv_chip_power8_intc_destroy;
k->isa_create = pnv_chip_power8nvl_isa_create;
k->dt_populate = pnv_chip_power8_dt_populate;
k->pic_print_info = pnv_chip_power8_pic_print_info;
@@ -1209,6 +1229,7 @@
k->core_pir = pnv_chip_core_pir_p9;
k->intc_create = pnv_chip_power9_intc_create;
k->intc_reset = pnv_chip_power9_intc_reset;
+ k->intc_destroy = pnv_chip_power9_intc_destroy;
k->isa_create = pnv_chip_power9_isa_create;
k->dt_populate = pnv_chip_power9_dt_populate;
k->pic_print_info = pnv_chip_power9_pic_print_info;
diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c
index e81cd3a..61b3d3c 100644
--- a/hw/ppc/pnv_core.c
+++ b/hw/ppc/pnv_core.c
@@ -269,11 +269,12 @@
error_propagate(errp, local_err);
}
-static void pnv_core_cpu_unrealize(PowerPCCPU *cpu)
+static void pnv_core_cpu_unrealize(PowerPCCPU *cpu, PnvChip *chip)
{
PnvCPUState *pnv_cpu = pnv_cpu_state(cpu);
+ PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
- object_unparent(OBJECT(pnv_cpu_state(cpu)->intc));
+ pcc->intc_destroy(chip, cpu);
cpu_remove_sync(CPU(cpu));
cpu->machine_data = NULL;
g_free(pnv_cpu);
@@ -289,7 +290,7 @@
qemu_unregister_reset(pnv_core_reset, pc);
for (i = 0; i < cc->nr_threads; i++) {
- pnv_core_cpu_unrealize(pc->threads[i]);
+ pnv_core_cpu_unrealize(pc->threads[i], pc->chip);
}
g_free(pc->threads);
}
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 94f9d27..e076f60 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -917,7 +917,7 @@
return false;
}
-static void *spapr_build_fdt(SpaprMachineState *spapr);
+static void *spapr_build_fdt(SpaprMachineState *spapr, bool reset);
int spapr_h_cas_compose_response(SpaprMachineState *spapr,
target_ulong addr, target_ulong size,
@@ -939,7 +939,7 @@
size -= sizeof(hdr);
- fdt = spapr_build_fdt(spapr);
+ fdt = spapr_build_fdt(spapr, false);
_FDT((fdt_pack(fdt)));
if (fdt_totalsize(fdt) + sizeof(hdr) > size) {
@@ -1197,7 +1197,7 @@
}
}
-static void *spapr_build_fdt(SpaprMachineState *spapr)
+static void *spapr_build_fdt(SpaprMachineState *spapr, bool reset)
{
MachineState *machine = MACHINE(spapr);
MachineClass *mc = MACHINE_GET_CLASS(machine);
@@ -1297,7 +1297,9 @@
spapr_dt_rtas(spapr, fdt);
/* /chosen */
- spapr_dt_chosen(spapr, fdt);
+ if (reset) {
+ spapr_dt_chosen(spapr, fdt);
+ }
/* /hypervisor */
if (kvm_enabled()) {
@@ -1305,11 +1307,14 @@
}
/* Build memory reserve map */
- if (spapr->kernel_size) {
- _FDT((fdt_add_mem_rsv(fdt, KERNEL_LOAD_ADDR, spapr->kernel_size)));
- }
- if (spapr->initrd_size) {
- _FDT((fdt_add_mem_rsv(fdt, spapr->initrd_base, spapr->initrd_size)));
+ if (reset) {
+ if (spapr->kernel_size) {
+ _FDT((fdt_add_mem_rsv(fdt, KERNEL_LOAD_ADDR, spapr->kernel_size)));
+ }
+ if (spapr->initrd_size) {
+ _FDT((fdt_add_mem_rsv(fdt, spapr->initrd_base,
+ spapr->initrd_size)));
+ }
}
/* ibm,client-architecture-support updates */
@@ -1718,7 +1723,7 @@
*/
fdt_addr = MIN(spapr->rma_size, RTAS_MAX_ADDR) - FDT_MAX_SIZE;
- fdt = spapr_build_fdt(spapr);
+ fdt = spapr_build_fdt(spapr, true);
rc = fdt_pack(fdt);
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index ef7b27a..8339c4c 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -195,12 +195,7 @@
if (!sc->pre_3_0_migration) {
vmstate_unregister(NULL, &vmstate_spapr_cpu_state, cpu->machine_data);
}
- if (spapr_cpu_state(cpu)->icp) {
- object_unparent(OBJECT(spapr_cpu_state(cpu)->icp));
- }
- if (spapr_cpu_state(cpu)->tctx) {
- object_unparent(OBJECT(spapr_cpu_state(cpu)->tctx));
- }
+ spapr_irq_cpu_intc_destroy(SPAPR_MACHINE(qdev_get_machine()), cpu);
cpu_remove_sync(CPU(cpu));
object_unparent(OBJECT(cpu));
}
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index b941608..168044b 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -234,6 +234,20 @@
}
}
+void spapr_irq_cpu_intc_destroy(SpaprMachineState *spapr, PowerPCCPU *cpu)
+{
+ SpaprInterruptController *intcs[] = ALL_INTCS(spapr);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(intcs); i++) {
+ SpaprInterruptController *intc = intcs[i];
+ if (intc) {
+ SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
+ sicc->cpu_intc_destroy(intc, cpu);
+ }
+ }
+}
+
static void spapr_set_irq(void *opaque, int irq, int level)
{
SpaprMachineState *spapr = SPAPR_MACHINE(opaque);
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index cc8f311..23f340d 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -62,7 +62,7 @@
[VIRT_PLIC] = { 0xc000000, 0x4000000 },
[VIRT_UART0] = { 0x10000000, 0x100 },
[VIRT_VIRTIO] = { 0x10001000, 0x1000 },
- [VIRT_FLASH] = { 0x20000000, 0x2000000 },
+ [VIRT_FLASH] = { 0x20000000, 0x4000000 },
[VIRT_DRAM] = { 0x80000000, 0x0 },
[VIRT_PCIE_MMIO] = { 0x40000000, 0x40000000 },
[VIRT_PCIE_PIO] = { 0x03000000, 0x00010000 },
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 2a780e6..0b4c722 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -112,6 +112,7 @@
uint32_t (*core_pir)(PnvChip *chip, uint32_t core_id);
void (*intc_create)(PnvChip *chip, PowerPCCPU *cpu, Error **errp);
void (*intc_reset)(PnvChip *chip, PowerPCCPU *cpu);
+ void (*intc_destroy)(PnvChip *chip, PowerPCCPU *cpu);
ISABus *(*isa_create)(PnvChip *chip, Error **errp);
void (*dt_populate)(PnvChip *chip, void *fdt);
void (*pic_print_info)(PnvChip *chip, Monitor *mon);
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index 0923299..ff814d1 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -53,6 +53,7 @@
int (*cpu_intc_create)(SpaprInterruptController *intc,
PowerPCCPU *cpu, Error **errp);
void (*cpu_intc_reset)(SpaprInterruptController *intc, PowerPCCPU *cpu);
+ void (*cpu_intc_destroy)(SpaprInterruptController *intc, PowerPCCPU *cpu);
int (*claim_irq)(SpaprInterruptController *intc, int irq, bool lsi,
Error **errp);
void (*free_irq)(SpaprInterruptController *intc, int irq);
@@ -70,6 +71,7 @@
int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
PowerPCCPU *cpu, Error **errp);
void spapr_irq_cpu_intc_reset(SpaprMachineState *spapr, PowerPCCPU *cpu);
+void spapr_irq_cpu_intc_destroy(SpaprMachineState *spapr, PowerPCCPU *cpu);
void spapr_irq_print_info(SpaprMachineState *spapr, Monitor *mon);
void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers,
void *fdt, uint32_t phandle);
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index 602173c..48a75aa 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -181,6 +181,7 @@
Object *icp_create(Object *cpu, const char *type, XICSFabric *xi,
Error **errp);
+void icp_destroy(ICPState *icp);
/* KVM */
void icp_get_kvm_state(ICPState *icp);
diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
index 9938163..8fd439e 100644
--- a/include/hw/ppc/xive.h
+++ b/include/hw/ppc/xive.h
@@ -416,6 +416,7 @@
void xive_tctx_pic_print_info(XiveTCTX *tctx, Monitor *mon);
Object *xive_tctx_create(Object *cpu, XiveRouter *xrtr, Error **errp);
void xive_tctx_reset(XiveTCTX *tctx);
+void xive_tctx_destroy(XiveTCTX *tctx);
static inline uint32_t xive_nvt_cam_line(uint8_t nvt_blk, uint32_t nvt_idx)
{
diff --git a/include/qemu/qemu-plugin.h b/include/qemu/qemu-plugin.h
index a00a7de..5502e11 100644
--- a/include/qemu/qemu-plugin.h
+++ b/include/qemu/qemu-plugin.h
@@ -38,9 +38,28 @@
typedef uint64_t qemu_plugin_id_t;
+/*
+ * Versioning plugins:
+ *
+ * The plugin API will pass a minimum and current API version that
+ * QEMU currently supports. The minimum API will be incremented if an
+ * API needs to be deprecated.
+ *
+ * The plugins export the API they were built against by exposing the
+ * symbol qemu_plugin_version which can be checked.
+ */
+
+extern QEMU_PLUGIN_EXPORT int qemu_plugin_version;
+
+#define QEMU_PLUGIN_VERSION 0
+
typedef struct {
/* string describing architecture */
const char *target_name;
+ struct {
+ int min;
+ int cur;
+ } version;
/* is this a full system emulation? */
bool system_emulation;
union {
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index ab9d933..ce399a5 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -2632,6 +2632,7 @@
default:
goto unimplemented;
}
+ break;
#endif /* SOL_NETLINK */
default:
unimplemented:
@@ -7763,10 +7764,12 @@
#ifdef TARGET_NR_stime /* not on alpha */
case TARGET_NR_stime:
{
- time_t host_time;
- if (get_user_sal(host_time, arg1))
+ struct timespec ts;
+ ts.tv_nsec = 0;
+ if (get_user_sal(ts.tv_sec, arg1)) {
return -TARGET_EFAULT;
- return get_errno(stime(&host_time));
+ }
+ return get_errno(clock_settime(CLOCK_REALTIME, &ts));
}
#endif
#ifdef TARGET_NR_alarm /* not on alpha */
diff --git a/pc-bios/opensbi-riscv32-virt-fw_jump.bin b/pc-bios/opensbi-riscv32-virt-fw_jump.bin
index f5bcaa5..6c5b7b8 100644
--- a/pc-bios/opensbi-riscv32-virt-fw_jump.bin
+++ b/pc-bios/opensbi-riscv32-virt-fw_jump.bin
Binary files differ
diff --git a/pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin b/pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin
index eb22aef..971f2be 100644
--- a/pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin
+++ b/pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin
Binary files differ
diff --git a/pc-bios/opensbi-riscv64-virt-fw_jump.bin b/pc-bios/opensbi-riscv64-virt-fw_jump.bin
index 4cec6f0..45a5aed 100644
--- a/pc-bios/opensbi-riscv64-virt-fw_jump.bin
+++ b/pc-bios/opensbi-riscv64-virt-fw_jump.bin
Binary files differ
diff --git a/plugins/loader.c b/plugins/loader.c
index ce724ed..15fc7e5 100644
--- a/plugins/loader.c
+++ b/plugins/loader.c
@@ -178,6 +178,25 @@
goto err_symbol;
}
+ if (!g_module_symbol(ctx->handle, "qemu_plugin_version", &sym)) {
+ error_report("TCG plugin %s does not declare API version %s",
+ desc->path, g_module_error());
+ goto err_symbol;
+ } else {
+ int version = *(int *)sym;
+ if (version < QEMU_PLUGIN_MIN_VERSION) {
+ error_report("TCG plugin %s requires API version %d, but "
+ "this QEMU supports only a minimum version of %d",
+ desc->path, version, QEMU_PLUGIN_MIN_VERSION);
+ goto err_symbol;
+ } else if (version > QEMU_PLUGIN_VERSION) {
+ error_report("TCG plugin %s requires API version %d, but "
+ "this QEMU supports only up to version %d",
+ desc->path, version, QEMU_PLUGIN_VERSION);
+ goto err_symbol;
+ }
+ }
+
qemu_rec_mutex_lock(&plugin.lock);
/* find an unused random id with &ctx as the seed */
@@ -248,6 +267,8 @@
g_autofree qemu_info_t *info = g_new0(qemu_info_t, 1);
info->target_name = TARGET_NAME;
+ info->version.min = QEMU_PLUGIN_MIN_VERSION;
+ info->version.cur = QEMU_PLUGIN_VERSION;
#ifndef CONFIG_USER_ONLY
MachineState *ms = MACHINE(qdev_get_machine());
info->system_emulation = true;
diff --git a/plugins/plugin.h b/plugins/plugin.h
index 5482168..1aa29dc 100644
--- a/plugins/plugin.h
+++ b/plugins/plugin.h
@@ -14,6 +14,8 @@
#include <gmodule.h>
+#define QEMU_PLUGIN_MIN_VERSION 0
+
/* global state */
struct qemu_plugin_state {
QTAILQ_HEAD(, qemu_plugin_ctx) ctxs;
diff --git a/qemu-doc.texi b/qemu-doc.texi
index 3c50220..3ddf5c0 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -44,6 +44,7 @@
* Security::
* Implementation notes::
* Deprecated features::
+* Recently removed features::
* Supported build platforms::
* License::
* Index::
diff --git a/qom/object.c b/qom/object.c
index 6fa9c61..d51b57f 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1106,9 +1106,8 @@
}
if (object_property_find(obj, name, NULL) != NULL) {
- error_setg(errp, "attempt to add duplicate property '%s'"
- " to object (type '%s')", name,
- object_get_typename(obj));
+ error_setg(errp, "attempt to add duplicate property '%s' to object (type '%s')",
+ name, object_get_typename(obj));
return NULL;
}
@@ -1139,9 +1138,8 @@
ObjectProperty *prop;
if (object_class_property_find(klass, name, NULL) != NULL) {
- error_setg(errp, "attempt to add duplicate property '%s'"
- " to object (type '%s')", name,
- object_class_get_name(klass));
+ error_setg(errp, "attempt to add duplicate property '%s' to class (type '%s')",
+ name, object_class_get_name(klass));
return NULL;
}
diff --git a/roms/opensbi b/roms/opensbi
index ce228ee..be92da2 160000
--- a/roms/opensbi
+++ b/roms/opensbi
@@ -1 +1 @@
-Subproject commit ce228ee0919deb9957192d723eecc8aaae2697c6
+Subproject commit be92da280d87c38a2e0adc5d3f43bab7b5468f09
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 761f535..bdc7d53 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -962,17 +962,7 @@
switch (size) {
case 1:
{
- /* 00 -> 11
- 01 -> 10
- 10 -> 10
- 11 -> 00 */
- TCGv low = tcg_temp_new();
-
- tcg_gen_andi_tl(low, addr, 3);
- tcg_gen_sub_tl(low, tcg_const_tl(3), low);
- tcg_gen_andi_tl(addr, addr, ~3);
- tcg_gen_or_tl(addr, addr, low);
- tcg_temp_free(low);
+ tcg_gen_xori_tl(addr, addr, 3);
break;
}
@@ -1006,9 +996,16 @@
tcg_gen_qemu_ld_i32(v, addr, mem_index, mop);
if ((dc->cpu->env.pvr.regs[2] & PVR2_UNALIGNED_EXC_MASK) && size > 1) {
+ TCGv_i32 t0 = tcg_const_i32(0);
+ TCGv_i32 treg = tcg_const_i32(dc->rd);
+ TCGv_i32 tsize = tcg_const_i32(size - 1);
+
tcg_gen_movi_i64(cpu_SR[SR_PC], dc->pc);
- gen_helper_memalign(cpu_env, addr, tcg_const_i32(dc->rd),
- tcg_const_i32(0), tcg_const_i32(size - 1));
+ gen_helper_memalign(cpu_env, addr, treg, t0, tsize);
+
+ tcg_temp_free_i32(t0);
+ tcg_temp_free_i32(treg);
+ tcg_temp_free_i32(tsize);
}
if (ex) {
@@ -1095,17 +1092,7 @@
switch (size) {
case 1:
{
- /* 00 -> 11
- 01 -> 10
- 10 -> 10
- 11 -> 00 */
- TCGv low = tcg_temp_new();
-
- tcg_gen_andi_tl(low, addr, 3);
- tcg_gen_sub_tl(low, tcg_const_tl(3), low);
- tcg_gen_andi_tl(addr, addr, ~3);
- tcg_gen_or_tl(addr, addr, low);
- tcg_temp_free(low);
+ tcg_gen_xori_tl(addr, addr, 3);
break;
}
@@ -1124,6 +1111,10 @@
/* Verify alignment if needed. */
if ((dc->cpu->env.pvr.regs[2] & PVR2_UNALIGNED_EXC_MASK) && size > 1) {
+ TCGv_i32 t1 = tcg_const_i32(1);
+ TCGv_i32 treg = tcg_const_i32(dc->rd);
+ TCGv_i32 tsize = tcg_const_i32(size - 1);
+
tcg_gen_movi_i64(cpu_SR[SR_PC], dc->pc);
/* FIXME: if the alignment is wrong, we should restore the value
* in memory. One possible way to achieve this is to probe
@@ -1131,8 +1122,11 @@
* the alignment checks in between the probe and the mem
* access.
*/
- gen_helper_memalign(cpu_env, addr, tcg_const_i32(dc->rd),
- tcg_const_i32(1), tcg_const_i32(size - 1));
+ gen_helper_memalign(cpu_env, addr, treg, t1, tsize);
+
+ tcg_temp_free_i32(t1);
+ tcg_temp_free_i32(treg);
+ tcg_temp_free_i32(tsize);
}
if (ex) {
@@ -1183,6 +1177,17 @@
tcg_temp_free_i64(tmp_zero);
}
+static void dec_setup_dslot(DisasContext *dc)
+{
+ TCGv_i32 tmp = tcg_const_i32(dc->type_b && (dc->tb_flags & IMM_FLAG));
+
+ dc->delayed_branch = 2;
+ dc->tb_flags |= D_FLAG;
+
+ tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUMBState, bimm));
+ tcg_temp_free_i32(tmp);
+}
+
static void dec_bcc(DisasContext *dc)
{
unsigned int cc;
@@ -1194,10 +1199,7 @@
dc->delayed_branch = 1;
if (dslot) {
- dc->delayed_branch = 2;
- dc->tb_flags |= D_FLAG;
- tcg_gen_st_i32(tcg_const_i32(dc->type_b && (dc->tb_flags & IMM_FLAG)),
- cpu_env, offsetof(CPUMBState, bimm));
+ dec_setup_dslot(dc);
}
if (dec_alu_op_b_is_small_imm(dc)) {
@@ -1256,10 +1258,7 @@
dc->delayed_branch = 1;
if (dslot) {
- dc->delayed_branch = 2;
- dc->tb_flags |= D_FLAG;
- tcg_gen_st_i32(tcg_const_i32(dc->type_b && (dc->tb_flags & IMM_FLAG)),
- cpu_env, offsetof(CPUMBState, bimm));
+ dec_setup_dslot(dc);
}
if (link && dc->rd)
tcg_gen_movi_i32(cpu_R[dc->rd], dc->pc);
@@ -1361,10 +1360,7 @@
return;
}
- dc->delayed_branch = 2;
- dc->tb_flags |= D_FLAG;
- tcg_gen_st_i32(tcg_const_i32(dc->type_b && (dc->tb_flags & IMM_FLAG)),
- cpu_env, offsetof(CPUMBState, bimm));
+ dec_setup_dslot(dc);
if (i_bit) {
LOG_DIS("rtid ir=%x\n", dc->ir);
@@ -1685,7 +1681,10 @@
dc->tb_flags &= ~D_FLAG;
/* If it is a direct jump, try direct chaining. */
if (dc->jmp == JMP_INDIRECT) {
- eval_cond_jmp(dc, env_btarget, tcg_const_i64(dc->pc));
+ TCGv_i64 tmp_pc = tcg_const_i64(dc->pc);
+ eval_cond_jmp(dc, env_btarget, tmp_pc);
+ tcg_temp_free_i64(tmp_pc);
+
dc->is_jmp = DISAS_JUMP;
} else if (dc->jmp == JMP_DIRECT) {
t_sync_flags(dc);
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 7d2e896..c77f984 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -100,7 +100,7 @@
return kvm_vm_check_extension(ks, KVM_CAP_PPC_GET_PVINFO) != 0;
}
-static int kvm_ppc_register_host_cpu_type(MachineState *ms);
+static int kvm_ppc_register_host_cpu_type(void);
static void kvmppc_get_cpu_characteristics(KVMState *s);
static int kvmppc_get_dec_bits(void);
@@ -147,7 +147,7 @@
exit(1);
}
- kvm_ppc_register_host_cpu_type(ms);
+ kvm_ppc_register_host_cpu_type();
return 0;
}
@@ -2534,13 +2534,19 @@
return pvr_pcc;
}
-static int kvm_ppc_register_host_cpu_type(MachineState *ms)
+static void pseries_machine_class_fixup(ObjectClass *oc, void *opaque)
+{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
+ mc->default_cpu_type = TYPE_HOST_POWERPC_CPU;
+}
+
+static int kvm_ppc_register_host_cpu_type(void)
{
TypeInfo type_info = {
.name = TYPE_HOST_POWERPC_CPU,
.class_init = kvmppc_host_cpu_class_init,
};
- MachineClass *mc = MACHINE_GET_CLASS(ms);
PowerPCCPUClass *pvr_pcc;
ObjectClass *oc;
DeviceClass *dc;
@@ -2552,10 +2558,9 @@
}
type_info.parent = object_class_get_name(OBJECT_CLASS(pvr_pcc));
type_register(&type_info);
- if (object_dynamic_cast(OBJECT(ms), TYPE_SPAPR_MACHINE)) {
- /* override TCG default cpu type with 'host' cpu model */
- mc->default_cpu_type = TYPE_HOST_POWERPC_CPU;
- }
+ /* override TCG default cpu type with 'host' cpu model */
+ object_class_foreach(pseries_machine_class_fixup, TYPE_SPAPR_MACHINE,
+ false, NULL);
oc = object_class_by_name(type_info.name);
g_assert(oc);
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 3939963..d37861a 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -224,8 +224,7 @@
#ifndef CONFIG_USER_ONLY
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mhartid ", env->mhartid);
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatus ", env->mstatus);
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mip ",
- (target_ulong)atomic_read(&env->mip));
+ qemu_fprintf(f, " %s 0x%x\n", "mip ", env->mip);
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mie ", env->mie);
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mideleg ", env->mideleg);
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "medeleg ", env->medeleg);
@@ -275,7 +274,7 @@
* Definition of the WFI instruction requires it to ignore the privilege
* mode and delegation registers, but respect individual enables
*/
- return (atomic_read(&env->mip) & env->mie) != 0;
+ return (env->mip & env->mie) != 0;
#else
return true;
#endif
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 8c64c68..e59343e 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -121,15 +121,6 @@
target_ulong mhartid;
target_ulong mstatus;
- /*
- * CAUTION! Unlike the rest of this struct, mip is accessed asynchonously
- * by I/O threads. It should be read with atomic_read. It should be updated
- * using riscv_cpu_update_mip with the iothread mutex held. The iothread
- * mutex must be held because mip must be consistent with the CPU inturrept
- * state. riscv_cpu_update_mip calls cpu_interrupt or cpu_reset_interrupt
- * wuth the invariant that CPU_INTERRUPT_HARD is set iff mip is non-zero.
- * mip is 32-bits to allow atomic_read on 32-bit hosts.
- */
uint32_t mip;
uint32_t miclaim;
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index f13131a..767c876 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -19,6 +19,7 @@
#include "qemu/osdep.h"
#include "qemu/log.h"
+#include "qemu/main-loop.h"
#include "cpu.h"
#include "exec/exec-all.h"
#include "tcg-op.h"
@@ -38,7 +39,7 @@
{
target_ulong mstatus_mie = get_field(env->mstatus, MSTATUS_MIE);
target_ulong mstatus_sie = get_field(env->mstatus, MSTATUS_SIE);
- target_ulong pending = atomic_read(&env->mip) & env->mie;
+ target_ulong pending = env->mip & env->mie;
target_ulong mie = env->priv < PRV_M || (env->priv == PRV_M && mstatus_mie);
target_ulong sie = env->priv < PRV_S || (env->priv == PRV_S && mstatus_sie);
target_ulong irqs = (pending & ~env->mideleg & -mie) |
@@ -92,42 +93,29 @@
}
}
-struct CpuAsyncInfo {
- uint32_t new_mip;
-};
-
-static void riscv_cpu_update_mip_irqs_async(CPUState *target_cpu_state,
- run_on_cpu_data data)
-{
- struct CpuAsyncInfo *info = (struct CpuAsyncInfo *) data.host_ptr;
-
- if (info->new_mip) {
- cpu_interrupt(target_cpu_state, CPU_INTERRUPT_HARD);
- } else {
- cpu_reset_interrupt(target_cpu_state, CPU_INTERRUPT_HARD);
- }
-
- g_free(info);
-}
-
uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t value)
{
CPURISCVState *env = &cpu->env;
CPUState *cs = CPU(cpu);
- struct CpuAsyncInfo *info;
- uint32_t old, new, cmp = atomic_read(&env->mip);
+ uint32_t old = env->mip;
+ bool locked = false;
- do {
- old = cmp;
- new = (old & ~mask) | (value & mask);
- cmp = atomic_cmpxchg(&env->mip, old, new);
- } while (old != cmp);
+ if (!qemu_mutex_iothread_locked()) {
+ locked = true;
+ qemu_mutex_lock_iothread();
+ }
- info = g_new(struct CpuAsyncInfo, 1);
- info->new_mip = new;
+ env->mip = (env->mip & ~mask) | (value & mask);
- async_run_on_cpu(cs, riscv_cpu_update_mip_irqs_async,
- RUN_ON_CPU_HOST_PTR(info));
+ if (env->mip) {
+ cpu_interrupt(cs, CPU_INTERRUPT_HARD);
+ } else {
+ cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
+ }
+
+ if (locked) {
+ qemu_mutex_unlock_iothread();
+ }
return old;
}
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 974c9c2..da02f9f 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -579,7 +579,7 @@
if (mask) {
old_mip = riscv_cpu_update_mip(cpu, mask, (new_value & mask));
} else {
- old_mip = atomic_read(&env->mip);
+ old_mip = env->mip;
}
if (ret_value) {
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index b26533d..ab6a891 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -64,12 +64,10 @@
[0] = MO_SB,
[1] = MO_TESW,
[2] = MO_TESL,
+ [3] = MO_TEQ,
[4] = MO_UB,
[5] = MO_TEUW,
-#ifdef TARGET_RISCV64
- [3] = MO_TEQ,
[6] = MO_TEUL,
-#endif
};
#endif
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 534ee48..8566f5f 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -177,7 +177,9 @@
check-qtest-i386-$(CONFIG_SLIRP) += tests/pxe-test$(EXESUF)
check-qtest-i386-y += tests/rtc-test$(EXESUF)
check-qtest-i386-$(CONFIG_ISA_IPMI_KCS) += tests/ipmi-kcs-test$(EXESUF)
+ifdef CONFIG_LINUX
check-qtest-i386-$(CONFIG_ISA_IPMI_BT) += tests/ipmi-bt-test$(EXESUF)
+endif
check-qtest-i386-y += tests/i440fx-test$(EXESUF)
check-qtest-i386-y += tests/fw_cfg-test$(EXESUF)
check-qtest-i386-y += tests/device-plug-test$(EXESUF)
diff --git a/tests/cpu-plug-test.c b/tests/cpu-plug-test.c
index 058cef5..30e514b 100644
--- a/tests/cpu-plug-test.c
+++ b/tests/cpu-plug-test.c
@@ -99,6 +99,7 @@
cpu = qobject_to(QDict, e);
if (qdict_haskey(cpu, "qom-path")) {
+ qobject_unref(e);
continue;
}
@@ -107,6 +108,7 @@
qtest_qmp_device_add_qdict(qts, td->device_model, props);
hotplugged++;
+ qobject_unref(e);
}
/* make sure that there were hotplugged CPUs */
diff --git a/tests/libqtest.c b/tests/libqtest.c
index 3706bcc..91e9cb2 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -1274,6 +1274,7 @@
qdict_put_str(args, "id", id);
qtest_qmp_device_add_qdict(qts, driver, args);
+ qobject_unref(args);
}
static void device_deleted_cb(void *opaque, const char *name, QDict *data)
diff --git a/tests/migration-test.c b/tests/migration-test.c
index 59f291c..ac780df 100644
--- a/tests/migration-test.c
+++ b/tests/migration-test.c
@@ -899,8 +899,13 @@
do {
status = migrate_query_status(from);
- g_assert(!strcmp(status, "setup") || !strcmp(status, "failed") ||
- (allow_active && !strcmp(status, "active")));
+ bool result = !strcmp(status, "setup") || !strcmp(status, "failed") ||
+ (allow_active && !strcmp(status, "active"));
+ if (!result) {
+ fprintf(stderr, "%s: unexpected status status=%s allow_active=%d\n",
+ __func__, status, allow_active);
+ }
+ g_assert(result);
failed = !strcmp(status, "failed");
g_free(status);
} while (!failed);
diff --git a/tests/plugin/bb.c b/tests/plugin/bb.c
index 45e1de5..f30bea0 100644
--- a/tests/plugin/bb.c
+++ b/tests/plugin/bb.c
@@ -14,6 +14,8 @@
#include <qemu-plugin.h>
+QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
+
static uint64_t bb_count;
static uint64_t insn_count;
static bool do_inline;
diff --git a/tests/plugin/empty.c b/tests/plugin/empty.c
index 3f60f69..8fa6bac 100644
--- a/tests/plugin/empty.c
+++ b/tests/plugin/empty.c
@@ -13,6 +13,8 @@
#include <qemu-plugin.h>
+QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
+
/*
* Empty TB translation callback.
* This allows us to measure the overhead of injecting and then
diff --git a/tests/plugin/hotblocks.c b/tests/plugin/hotblocks.c
index 1bd1838..3942a2c 100644
--- a/tests/plugin/hotblocks.c
+++ b/tests/plugin/hotblocks.c
@@ -15,6 +15,8 @@
#include <qemu-plugin.h>
+QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
+
static bool do_inline;
/* Plugins need to take care of their own locking */
diff --git a/tests/plugin/hotpages.c b/tests/plugin/hotpages.c
index 77df07a..ecd6c18 100644
--- a/tests/plugin/hotpages.c
+++ b/tests/plugin/hotpages.c
@@ -18,6 +18,8 @@
#include <qemu-plugin.h>
+QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
+
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
static uint64_t page_size = 4096;
diff --git a/tests/plugin/howvec.c b/tests/plugin/howvec.c
index 58fa675..4ca555e 100644
--- a/tests/plugin/howvec.c
+++ b/tests/plugin/howvec.c
@@ -20,6 +20,8 @@
#include <qemu-plugin.h>
+QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
+
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
typedef enum {
diff --git a/tests/plugin/insn.c b/tests/plugin/insn.c
index e5fd07f..0a8f5a0 100644
--- a/tests/plugin/insn.c
+++ b/tests/plugin/insn.c
@@ -14,6 +14,8 @@
#include <qemu-plugin.h>
+QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
+
static uint64_t insn_count;
static bool do_inline;
diff --git a/tests/plugin/mem.c b/tests/plugin/mem.c
index d967388..878abf0 100644
--- a/tests/plugin/mem.c
+++ b/tests/plugin/mem.c
@@ -14,6 +14,8 @@
#include <qemu-plugin.h>
+QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
+
static uint64_t mem_count;
static uint64_t io_count;
static bool do_inline;
diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
index 2929de2..91a9226 100755
--- a/tests/vm/basevm.py
+++ b/tests/vm/basevm.py
@@ -95,19 +95,25 @@
logging.info("KVM not available, not using -enable-kvm")
self._data_args = []
- def _download_with_cache(self, url, sha256sum=None):
+ def _download_with_cache(self, url, sha256sum=None, sha512sum=None):
def check_sha256sum(fname):
if not sha256sum:
return True
checksum = subprocess.check_output(["sha256sum", fname]).split()[0]
return sha256sum == checksum.decode("utf-8")
+ def check_sha512sum(fname):
+ if not sha512sum:
+ return True
+ checksum = subprocess.check_output(["sha512sum", fname]).split()[0]
+ return sha512sum == checksum.decode("utf-8")
+
cache_dir = os.path.expanduser("~/.cache/qemu-vm/download")
if not os.path.exists(cache_dir):
os.makedirs(cache_dir)
fname = os.path.join(cache_dir,
hashlib.sha1(url.encode("utf-8")).hexdigest())
- if os.path.exists(fname) and check_sha256sum(fname):
+ if os.path.exists(fname) and check_sha256sum(fname) and check_sha512sum(fname):
return fname
logging.debug("Downloading %s to %s...", url, fname)
subprocess.check_call(["wget", "-c", url, "-O", fname + ".download"],
@@ -242,6 +248,25 @@
return False
return True
+ def console_consume(self):
+ vm = self._guest
+ output = ""
+ vm.console_socket.setblocking(0)
+ while True:
+ try:
+ chars = vm.console_socket.recv(1)
+ except:
+ break
+ output += chars.decode("latin1")
+ if "\r" in output or "\n" in output:
+ lines = re.split("[\r\n]", output)
+ output = lines.pop()
+ if self.debug:
+ self.console_log("\n".join(lines))
+ if self.debug:
+ self.console_log(output)
+ vm.console_socket.setblocking(1)
+
def console_send(self, command):
vm = self._guest
if self.debug:
diff --git a/tests/vm/netbsd b/tests/vm/netbsd
index 18aa56a..611e6cc 100755
--- a/tests/vm/netbsd
+++ b/tests/vm/netbsd
@@ -2,10 +2,11 @@
#
# NetBSD VM image
#
-# Copyright 2017 Red Hat Inc.
+# Copyright 2017-2019 Red Hat Inc.
#
# Authors:
# Fam Zheng <famz@redhat.com>
+# Gerd Hoffmann <kraxel@redhat.com>
#
# This code is licensed under the GPL version 2 or later. See
# the COPYING file in the top-level directory.
@@ -13,20 +14,54 @@
import os
import sys
+import time
import subprocess
import basevm
class NetBSDVM(basevm.BaseVM):
name = "netbsd"
arch = "x86_64"
+
+ link = "https://cdn.netbsd.org/pub/NetBSD/NetBSD-8.1/images/NetBSD-8.1-amd64.iso"
+ csum = "718f275b7e0879599bdac95630c5e3f2184700032fdb6cdebf3bdd63687898c48ff3f08f57b89f4437a86cdd8ea07c01a39d432dbb37e1e4b008f4985f98da3f"
+ size = "20G"
+ pkgs = [
+ # tools
+ "git-base",
+ "pkgconf",
+ "xz",
+ "python37",
+
+ # gnu tools
+ "bash",
+ "gmake",
+ "gsed",
+ "flex", "bison",
+
+ # libs: crypto
+ "gnutls",
+
+ # libs: images
+ "jpeg",
+ "png",
+
+ # libs: ui
+ "SDL2",
+ "gtk3+",
+ "libxkbcommon",
+ ]
+
BUILD_SCRIPT = """
set -e;
- rm -rf /var/tmp/qemu-test.*
- cd $(mktemp -d /var/tmp/qemu-test.XXXXXX);
+ rm -rf /home/qemu/qemu-test.*
+ cd $(mktemp -d /home/qemu/qemu-test.XXXXXX);
+ mkdir src build; cd src;
tar -xf /dev/rld1a;
- ./configure --python=python2.7 {configure_opts};
+ cd ../build
+ ../src/configure --python=python3.7 --disable-opengl {configure_opts};
gmake --output-sync -j{jobs} {target} {verbose};
"""
+ poweroff = "/sbin/poweroff"
# Workaround for NetBSD + IPv6 + slirp issues.
# NetBSD seems to ignore the ICMPv6 Destination Unreachable
@@ -36,14 +71,147 @@
ipv6 = False
def build_image(self, img):
- cimg = self._download_with_cache("http://download.patchew.org/netbsd-7.1-amd64.img.xz",
- sha256sum='b633d565b0eac3d02015cd0c81440bd8a7a8df8512615ac1ee05d318be015732')
- img_tmp_xz = img + ".tmp.xz"
+ cimg = self._download_with_cache(self.link, sha512sum=self.csum)
img_tmp = img + ".tmp"
- sys.stderr.write("Extracting the image...\n")
- subprocess.check_call(["ln", "-f", cimg, img_tmp_xz])
- subprocess.check_call(["xz", "--keep", "-dvf", img_tmp_xz])
+ iso = img + ".install.iso"
+
+ self.print_step("Preparing iso and disk image")
+ subprocess.check_call(["ln", "-f", cimg, iso])
+ subprocess.check_call(["qemu-img", "create", "-f", "qcow2",
+ img_tmp, self.size])
+
+ self.print_step("Booting installer")
+ self.boot(img_tmp, extra_args = [
+ "-bios", "pc-bios/bios-256k.bin",
+ "-machine", "graphics=off",
+ "-cdrom", iso
+ ])
+ self.console_init()
+ self.console_wait("Primary Bootstrap")
+
+ # serial console boot menu output doesn't work for some
+ # reason, so we have to fly blind ...
+ for char in list("5consdev com0\n"):
+ time.sleep(0.2)
+ self.console_send(char)
+ self.console_consume()
+ self.console_wait_send("> ", "boot\n")
+
+ self.console_wait_send("Terminal type", "xterm\n")
+ self.console_wait_send("a: Installation messages", "a\n")
+ self.console_wait_send("b: US-English", "b\n")
+ self.console_wait_send("a: Install NetBSD", "a\n")
+ self.console_wait("Shall we continue?")
+ self.console_wait_send("b: Yes", "b\n")
+
+ self.console_wait_send("a: ld0", "a\n")
+ self.console_wait_send("a: This is the correct", "a\n")
+ self.console_wait_send("b: Use the entire disk", "b\n")
+ self.console_wait("NetBSD bootcode")
+ self.console_wait_send("a: Yes", "a\n")
+ self.console_wait_send("b: Use existing part", "b\n")
+ self.console_wait_send("x: Partition sizes ok", "x\n")
+ self.console_wait_send("for your NetBSD disk", "\n")
+ self.console_wait("Shall we continue?")
+ self.console_wait_send("b: Yes", "b\n")
+
+ self.console_wait_send("b: Use serial port com0", "b\n")
+ self.console_wait_send("f: Set serial baud rate", "f\n")
+ self.console_wait_send("a: 9600", "a\n")
+ self.console_wait_send("x: Exit", "x\n")
+
+ self.console_wait_send("a: Full installation", "a\n")
+ self.console_wait_send("a: CD-ROM", "a\n")
+
+ self.print_step("Installation started now, this will take a while")
+ self.console_wait_send("Hit enter to continue", "\n")
+
+ self.console_wait_send("d: Change root password", "d\n")
+ self.console_wait_send("a: Yes", "a\n")
+ self.console_wait("New password:")
+ self.console_send("%s\n" % self.ROOT_PASS)
+ self.console_wait("New password:")
+ self.console_send("%s\n" % self.ROOT_PASS)
+ self.console_wait("Retype new password:")
+ self.console_send("%s\n" % self.ROOT_PASS)
+
+ self.console_wait_send("o: Add a user", "o\n")
+ self.console_wait("username")
+ self.console_send("%s\n" % self.GUEST_USER)
+ self.console_wait("to group wheel")
+ self.console_wait_send("a: Yes", "a\n")
+ self.console_wait_send("a: /bin/sh", "a\n")
+ self.console_wait("New password:")
+ self.console_send("%s\n" % self.GUEST_PASS)
+ self.console_wait("New password:")
+ self.console_send("%s\n" % self.GUEST_PASS)
+ self.console_wait("Retype new password:")
+ self.console_send("%s\n" % self.GUEST_PASS)
+
+ self.console_wait_send("a: Configure network", "a\n")
+ self.console_wait_send("a: vioif0", "a\n")
+ self.console_wait_send("Network media type", "\n")
+ self.console_wait("autoconfiguration")
+ self.console_wait_send("a: Yes", "a\n")
+ self.console_wait_send("DNS domain", "localnet\n")
+ self.console_wait("Are they OK?")
+ self.console_wait_send("a: Yes", "a\n")
+ self.console_wait("installed in /etc")
+ self.console_wait_send("a: Yes", "a\n")
+
+ self.console_wait_send("e: Enable install", "e\n")
+ proxy = os.environ.get("http_proxy")
+ if not proxy is None:
+ self.console_wait_send("f: Proxy", "f\n")
+ self.console_wait("Proxy")
+ self.console_send("%s\n" % proxy)
+ self.console_wait_send("x: Install pkgin", "x\n")
+ self.console_init(1200)
+ self.console_wait_send("Hit enter to continue", "\n")
+ self.console_init()
+
+ self.console_wait_send("g: Enable sshd", "g\n")
+ self.console_wait_send("x: Finished conf", "x\n")
+ self.console_wait_send("Hit enter to continue", "\n")
+
+ self.print_step("Installation finished, rebooting")
+ self.console_wait_send("d: Reboot the computer", "d\n")
+
+ # setup qemu user
+ prompt = "localhost$"
+ self.console_ssh_init(prompt, self.GUEST_USER, self.GUEST_PASS)
+ self.console_wait_send(prompt, "exit\n")
+
+ # setup root user
+ prompt = "localhost#"
+ self.console_ssh_init(prompt, "root", self.ROOT_PASS)
+ self.console_sshd_config(prompt)
+
+ # setup virtio-blk #1 (tarfile)
+ self.console_wait(prompt)
+ self.console_send("echo 'chmod 666 /dev/rld1a' >> /etc/rc.local\n")
+
+ # turn off mprotect (conflicts with tcg)
+ self.console_wait(prompt)
+ self.console_send("echo security.pax.mprotect.enabled=0 >> /etc/sysctl.conf\n")
+
+ self.print_step("Configuration finished, rebooting")
+ self.console_wait_send(prompt, "reboot\n")
+ self.console_wait("login:")
+ self.wait_ssh()
+
+ self.print_step("Installing packages")
+ self.ssh_root_check("pkgin update\n")
+ self.ssh_root_check("pkgin -y install %s\n" % " ".join(self.pkgs))
+
+ # shutdown
+ self.ssh_root(self.poweroff)
+ self.console_wait("entering state S5")
+ self.wait()
+
os.rename(img_tmp, img)
+ os.remove(iso)
+ self.print_step("All done")
if __name__ == "__main__":
sys.exit(basevm.main(NetBSDVM))