aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS9
-rw-r--r--accel/tcg/user-exec.c3
-rw-r--r--block/nfs.c2
-rw-r--r--block/vpc.c146
-rw-r--r--bsd-user/main.c1
-rwxr-xr-xconfigure1
-rw-r--r--disas/libvixl/vixl/a64/disasm-a64.cc4
-rw-r--r--disas/libvixl/vixl/globals.h6
-rw-r--r--docs/devel/migration.rst11
-rw-r--r--docs/interop/conf.py2
-rw-r--r--docs/interop/index.rst1
-rw-r--r--docs/interop/qemu-storage-daemon-qmp-ref.rst13
-rw-r--r--docs/meson.build1
-rw-r--r--docs/tools/conf.py2
-rw-r--r--docs/tools/index.rst1
-rw-r--r--docs/tools/qemu-storage-daemon.rst148
-rw-r--r--docs/user/main.rst99
-rw-r--r--hmp-commands.hx12
-rw-r--r--hw/block/nand.c12
-rw-r--r--hw/core/register.c16
-rw-r--r--hw/intc/arm_gicv3_kvm.c8
-rw-r--r--hw/intc/ibex_plic.c13
-rw-r--r--hw/riscv/boot.c70
-rw-r--r--hw/riscv/microchip_pfsoc.c21
-rw-r--r--hw/riscv/opentitan.c81
-rw-r--r--hw/riscv/sifive_u.c74
-rw-r--r--hw/riscv/spike.c52
-rw-r--r--hw/riscv/virt.c39
-rw-r--r--hw/rtc/twl92230.c44
-rw-r--r--hw/timer/renesas_tmr.c1
-rw-r--r--include/hw/riscv/boot.h14
-rw-r--r--include/hw/riscv/microchip_pfsoc.h3
-rw-r--r--include/hw/riscv/opentitan.h23
-rw-r--r--include/hw/riscv/spike.h6
-rw-r--r--include/hw/riscv/virt.h6
-rw-r--r--include/qemu/compiler.h11
-rw-r--r--linux-user/elfload.c43
-rw-r--r--linux-user/ioctls.h46
-rw-r--r--linux-user/mmap.c21
-rw-r--r--linux-user/sparc/signal.c87
-rw-r--r--linux-user/syscall.c79
-rw-r--r--linux-user/syscall_defs.h32
-rw-r--r--migration/migration.c6
-rw-r--r--migration/savevm.c11
-rw-r--r--monitor/hmp-cmds.c3
-rw-r--r--monitor/misc.c16
-rw-r--r--storage-daemon/qapi/qapi-schema.json3
-rw-r--r--target/i386/tcg/translate.c7
-rw-r--r--target/mips/cpu.h1
-rw-r--r--target/riscv/cpu.c84
-rw-r--r--target/riscv/cpu.h8
-rw-r--r--target/riscv/cpu_bits.h8
-rw-r--r--target/riscv/cpu_helper.c15
-rw-r--r--target/riscv/csr.c176
-rw-r--r--target/riscv/fpu_helper.c8
-rw-r--r--target/riscv/helper.h24
-rw-r--r--target/sparc/cpu.h28
-rw-r--r--target/sparc/int64_helper.c5
-rw-r--r--target/sparc/translate.c2
-rw-r--r--target/sparc/win_helper.c2
-rw-r--r--target/unicore32/translate.c2
-rw-r--r--tcg/optimize.c4
-rw-r--r--tests/fp/meson.build2
-rwxr-xr-xtests/qemu-iotests/1722
-rw-r--r--tests/qemu-iotests/172.out152
-rw-r--r--tests/qemu-iotests/186.out56
-rw-r--r--tests/qemu-iotests/210.out2
-rw-r--r--tests/qemu-iotests/common.filter2
-rw-r--r--tools/virtiofsd/fuse_lowlevel.c98
-rw-r--r--tools/virtiofsd/fuse_virtio.c36
-rw-r--r--tools/virtiofsd/passthrough_ll.c91
71 files changed, 1320 insertions, 798 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 1e7c8f0..0e139d9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2165,6 +2165,15 @@ F: qobject/block-qdict.c
F: tests/check-block-qdict.c
T: git https://repo.or.cz/qemu/kevin.git block
+Storage daemon
+M: Kevin Wolf <kwolf@redhat.com>
+L: qemu-block@nongnu.org
+S: Supported
+F: storage-daemon/
+F: docs/interop/qemu-storage-daemon-qmp-ref.rst
+F: docs/tools/qemu-storage-daemon.rst
+T: git https://repo.or.cz/qemu/kevin.git block
+
Block I/O path
M: Stefan Hajnoczi <stefanha@redhat.com>
M: Fam Zheng <fam@euphon.net>
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index 4ebe254..293ee86 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -49,7 +49,8 @@ __thread uintptr_t helper_retaddr;
/* exit the current TB from a signal handler. The host registers are
restored in a state compatible with the CPU emulator
*/
-static void cpu_exit_tb_from_sighandler(CPUState *cpu, sigset_t *old_set)
+static void QEMU_NORETURN cpu_exit_tb_from_sighandler(CPUState *cpu,
+ sigset_t *old_set)
{
/* XXX: use siglongjmp ? */
sigprocmask(SIG_SETMASK, old_set, NULL);
diff --git a/block/nfs.c b/block/nfs.c
index 77905f5..8c1968b 100644
--- a/block/nfs.c
+++ b/block/nfs.c
@@ -592,7 +592,7 @@ static int64_t nfs_client_open_qdict(NFSClient *client, QDict *options,
int flags, int open_flags, Error **errp)
{
BlockdevOptionsNfs *opts;
- int ret;
+ int64_t ret;
opts = nfs_options_qdict_to_qapi(options, errp);
if (opts == NULL) {
diff --git a/block/vpc.c b/block/vpc.c
index 1ab55f9..17a705b 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -39,8 +39,6 @@
/**************************************************************/
-#define HEADER_SIZE 512
-
//#define CACHE
enum vhd_type {
@@ -95,8 +93,11 @@ typedef struct vhd_footer {
QemuUUID uuid;
uint8_t in_saved_state;
+ uint8_t reserved[427];
} QEMU_PACKED VHDFooter;
+QEMU_BUILD_BUG_ON(sizeof(VHDFooter) != 512);
+
typedef struct vhd_dyndisk_header {
char magic[8]; /* "cxsparse" */
@@ -127,11 +128,14 @@ typedef struct vhd_dyndisk_header {
uint32_t reserved;
uint64_t data_offset;
} parent_locator[8];
+ uint8_t reserved2[256];
} QEMU_PACKED VHDDynDiskHeader;
+QEMU_BUILD_BUG_ON(sizeof(VHDDynDiskHeader) != 1024);
+
typedef struct BDRVVPCState {
CoMutex lock;
- uint8_t footer_buf[HEADER_SIZE];
+ VHDFooter footer;
uint64_t free_data_block_offset;
int max_table_entries;
uint32_t *pagetable;
@@ -172,8 +176,9 @@ static QemuOptsList vpc_runtime_opts = {
static QemuOptsList vpc_create_opts;
-static uint32_t vpc_checksum(uint8_t *buf, size_t size)
+static uint32_t vpc_checksum(void *p, size_t size)
{
+ uint8_t *buf = p;
uint32_t res = 0;
int i;
@@ -216,11 +221,10 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
BDRVVPCState *s = bs->opaque;
int i;
VHDFooter *footer;
- VHDDynDiskHeader *dyndisk_header;
QemuOpts *opts = NULL;
Error *local_err = NULL;
bool use_chs;
- uint8_t buf[HEADER_SIZE];
+ VHDDynDiskHeader dyndisk_header;
uint32_t checksum;
uint64_t computed_size;
uint64_t pagetable_size;
@@ -247,28 +251,28 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
goto fail;
}
- ret = bdrv_pread(bs->file, 0, s->footer_buf, HEADER_SIZE);
+ ret = bdrv_pread(bs->file, 0, &s->footer, sizeof(s->footer));
if (ret < 0) {
error_setg(errp, "Unable to read VHD header");
goto fail;
}
- footer = (VHDFooter *) s->footer_buf;
+ footer = &s->footer;
if (strncmp(footer->creator, "conectix", 8)) {
int64_t offset = bdrv_getlength(bs->file->bs);
if (offset < 0) {
ret = offset;
error_setg(errp, "Invalid file size");
goto fail;
- } else if (offset < HEADER_SIZE) {
+ } else if (offset < sizeof(*footer)) {
ret = -EINVAL;
error_setg(errp, "File too small for a VHD header");
goto fail;
}
/* If a fixed disk, the footer is found only at the end of the file */
- ret = bdrv_pread(bs->file, offset-HEADER_SIZE, s->footer_buf,
- HEADER_SIZE);
+ ret = bdrv_pread(bs->file, offset - sizeof(*footer),
+ footer, sizeof(*footer));
if (ret < 0) {
goto fail;
}
@@ -282,7 +286,7 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
checksum = be32_to_cpu(footer->checksum);
footer->checksum = 0;
- if (vpc_checksum(s->footer_buf, HEADER_SIZE) != checksum) {
+ if (vpc_checksum(footer, sizeof(*footer)) != checksum) {
error_setg(errp, "Incorrect header checksum");
ret = -EINVAL;
goto fail;
@@ -340,22 +344,20 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
}
if (disk_type == VHD_DYNAMIC) {
- ret = bdrv_pread(bs->file, be64_to_cpu(footer->data_offset), buf,
- HEADER_SIZE);
+ ret = bdrv_pread(bs->file, be64_to_cpu(footer->data_offset),
+ &dyndisk_header, sizeof(dyndisk_header));
if (ret < 0) {
error_setg(errp, "Error reading dynamic VHD header");
goto fail;
}
- dyndisk_header = (VHDDynDiskHeader *) buf;
-
- if (strncmp(dyndisk_header->magic, "cxsparse", 8)) {
+ if (strncmp(dyndisk_header.magic, "cxsparse", 8)) {
error_setg(errp, "Invalid header magic");
ret = -EINVAL;
goto fail;
}
- s->block_size = be32_to_cpu(dyndisk_header->block_size);
+ s->block_size = be32_to_cpu(dyndisk_header.block_size);
if (!is_power_of_2(s->block_size) || s->block_size < BDRV_SECTOR_SIZE) {
error_setg(errp, "Invalid block size %" PRIu32, s->block_size);
ret = -EINVAL;
@@ -363,7 +365,7 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
}
s->bitmap_size = ((s->block_size / (8 * 512)) + 511) & ~511;
- s->max_table_entries = be32_to_cpu(dyndisk_header->max_table_entries);
+ s->max_table_entries = be32_to_cpu(dyndisk_header.max_table_entries);
if ((bs->total_sectors * 512) / s->block_size > 0xffffffffU) {
error_setg(errp, "Too many blocks");
@@ -395,7 +397,7 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
goto fail;
}
- s->bat_offset = be64_to_cpu(dyndisk_header->table_offset);
+ s->bat_offset = be64_to_cpu(dyndisk_header.table_offset);
ret = bdrv_pread(bs->file, s->bat_offset, s->pagetable,
pagetable_size);
@@ -534,7 +536,7 @@ static int rewrite_footer(BlockDriverState *bs)
BDRVVPCState *s = bs->opaque;
int64_t offset = s->free_data_block_offset;
- ret = bdrv_pwrite_sync(bs->file, offset, s->footer_buf, HEADER_SIZE);
+ ret = bdrv_pwrite_sync(bs->file, offset, &s->footer, sizeof(s->footer));
if (ret < 0)
return ret;
@@ -597,9 +599,8 @@ fail:
static int vpc_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
{
BDRVVPCState *s = (BDRVVPCState *)bs->opaque;
- VHDFooter *footer = (VHDFooter *) s->footer_buf;
- if (be32_to_cpu(footer->type) != VHD_FIXED) {
+ if (be32_to_cpu(s->footer.type) != VHD_FIXED) {
bdi->cluster_size = s->block_size;
}
@@ -615,10 +616,9 @@ vpc_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
int64_t image_offset;
int64_t n_bytes;
int64_t bytes_done = 0;
- VHDFooter *footer = (VHDFooter *) s->footer_buf;
QEMUIOVector local_qiov;
- if (be32_to_cpu(footer->type) == VHD_FIXED) {
+ if (be32_to_cpu(s->footer.type) == VHD_FIXED) {
return bdrv_co_preadv(bs->file, offset, bytes, qiov, 0);
}
@@ -666,10 +666,9 @@ vpc_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
int64_t n_bytes;
int64_t bytes_done = 0;
int ret = 0;
- VHDFooter *footer = (VHDFooter *) s->footer_buf;
QEMUIOVector local_qiov;
- if (be32_to_cpu(footer->type) == VHD_FIXED) {
+ if (be32_to_cpu(s->footer.type) == VHD_FIXED) {
return bdrv_co_pwritev(bs->file, offset, bytes, qiov, 0);
}
@@ -723,13 +722,12 @@ static int coroutine_fn vpc_co_block_status(BlockDriverState *bs,
BlockDriverState **file)
{
BDRVVPCState *s = bs->opaque;
- VHDFooter *footer = (VHDFooter*) s->footer_buf;
int64_t image_offset;
bool allocated;
int ret;
int64_t n;
- if (be32_to_cpu(footer->type) == VHD_FIXED) {
+ if (be32_to_cpu(s->footer.type) == VHD_FIXED) {
*pnum = bytes;
*map = offset;
*file = bs->file->bs;
@@ -819,11 +817,11 @@ static int calculate_geometry(int64_t total_sectors, uint16_t *cyls,
return 0;
}
-static int create_dynamic_disk(BlockBackend *blk, uint8_t *buf,
+static int create_dynamic_disk(BlockBackend *blk, VHDFooter *footer,
int64_t total_sectors)
{
- VHDDynDiskHeader *dyndisk_header =
- (VHDDynDiskHeader *) buf;
+ VHDDynDiskHeader dyndisk_header;
+ uint8_t bat_sector[512];
size_t block_size, num_bat_entries;
int i;
int ret;
@@ -833,13 +831,13 @@ static int create_dynamic_disk(BlockBackend *blk, uint8_t *buf,
block_size = 0x200000;
num_bat_entries = DIV_ROUND_UP(total_sectors, block_size / 512);
- ret = blk_pwrite(blk, offset, buf, HEADER_SIZE, 0);
+ ret = blk_pwrite(blk, offset, footer, sizeof(*footer), 0);
if (ret < 0) {
goto fail;
}
offset = 1536 + ((num_bat_entries * 4 + 511) & ~511);
- ret = blk_pwrite(blk, offset, buf, HEADER_SIZE, 0);
+ ret = blk_pwrite(blk, offset, footer, sizeof(*footer), 0);
if (ret < 0) {
goto fail;
}
@@ -847,9 +845,9 @@ static int create_dynamic_disk(BlockBackend *blk, uint8_t *buf,
/* Write the initial BAT */
offset = 3 * 512;
- memset(buf, 0xFF, 512);
+ memset(bat_sector, 0xFF, 512);
for (i = 0; i < DIV_ROUND_UP(num_bat_entries * 4, 512); i++) {
- ret = blk_pwrite(blk, offset, buf, 512, 0);
+ ret = blk_pwrite(blk, offset, bat_sector, 512, 0);
if (ret < 0) {
goto fail;
}
@@ -857,26 +855,27 @@ static int create_dynamic_disk(BlockBackend *blk, uint8_t *buf,
}
/* Prepare the Dynamic Disk Header */
- memset(buf, 0, 1024);
+ memset(&dyndisk_header, 0, sizeof(dyndisk_header));
- memcpy(dyndisk_header->magic, "cxsparse", 8);
+ memcpy(dyndisk_header.magic, "cxsparse", 8);
/*
* Note: The spec is actually wrong here for data_offset, it says
* 0xFFFFFFFF, but MS tools expect all 64 bits to be set.
*/
- dyndisk_header->data_offset = cpu_to_be64(0xFFFFFFFFFFFFFFFFULL);
- dyndisk_header->table_offset = cpu_to_be64(3 * 512);
- dyndisk_header->version = cpu_to_be32(0x00010000);
- dyndisk_header->block_size = cpu_to_be32(block_size);
- dyndisk_header->max_table_entries = cpu_to_be32(num_bat_entries);
+ dyndisk_header.data_offset = cpu_to_be64(0xFFFFFFFFFFFFFFFFULL);
+ dyndisk_header.table_offset = cpu_to_be64(3 * 512);
+ dyndisk_header.version = cpu_to_be32(0x00010000);
+ dyndisk_header.block_size = cpu_to_be32(block_size);
+ dyndisk_header.max_table_entries = cpu_to_be32(num_bat_entries);
- dyndisk_header->checksum = cpu_to_be32(vpc_checksum(buf, 1024));
+ dyndisk_header.checksum = cpu_to_be32(
+ vpc_checksum(&dyndisk_header, sizeof(dyndisk_header)));
/* Write the header */
offset = 512;
- ret = blk_pwrite(blk, offset, buf, 1024, 0);
+ ret = blk_pwrite(blk, offset, &dyndisk_header, sizeof(dyndisk_header), 0);
if (ret < 0) {
goto fail;
}
@@ -886,20 +885,21 @@ static int create_dynamic_disk(BlockBackend *blk, uint8_t *buf,
return ret;
}
-static int create_fixed_disk(BlockBackend *blk, uint8_t *buf,
+static int create_fixed_disk(BlockBackend *blk, VHDFooter *footer,
int64_t total_size, Error **errp)
{
int ret;
/* Add footer to total size */
- total_size += HEADER_SIZE;
+ total_size += sizeof(*footer);
ret = blk_truncate(blk, total_size, false, PREALLOC_MODE_OFF, 0, errp);
if (ret < 0) {
return ret;
}
- ret = blk_pwrite(blk, total_size - HEADER_SIZE, buf, HEADER_SIZE, 0);
+ ret = blk_pwrite(blk, total_size - sizeof(*footer),
+ footer, sizeof(*footer), 0);
if (ret < 0) {
error_setg_errno(errp, -ret, "Unable to write VHD header");
return ret;
@@ -971,8 +971,7 @@ static int coroutine_fn vpc_co_create(BlockdevCreateOptions *opts,
BlockBackend *blk = NULL;
BlockDriverState *bs = NULL;
- uint8_t buf[1024];
- VHDFooter *footer = (VHDFooter *) buf;
+ VHDFooter footer;
uint16_t cyls = 0;
uint8_t heads = 0;
uint8_t secs_per_cyl = 0;
@@ -1035,48 +1034,48 @@ static int coroutine_fn vpc_co_create(BlockdevCreateOptions *opts,
}
/* Prepare the Hard Disk Footer */
- memset(buf, 0, 1024);
+ memset(&footer, 0, sizeof(footer));
- memcpy(footer->creator, "conectix", 8);
+ memcpy(footer.creator, "conectix", 8);
if (vpc_opts->force_size) {
- memcpy(footer->creator_app, "qem2", 4);
+ memcpy(footer.creator_app, "qem2", 4);
} else {
- memcpy(footer->creator_app, "qemu", 4);
+ memcpy(footer.creator_app, "qemu", 4);
}
- memcpy(footer->creator_os, "Wi2k", 4);
+ memcpy(footer.creator_os, "Wi2k", 4);
- footer->features = cpu_to_be32(0x02);
- footer->version = cpu_to_be32(0x00010000);
+ footer.features = cpu_to_be32(0x02);
+ footer.version = cpu_to_be32(0x00010000);
if (disk_type == VHD_DYNAMIC) {
- footer->data_offset = cpu_to_be64(HEADER_SIZE);
+ footer.data_offset = cpu_to_be64(sizeof(footer));
} else {
- footer->data_offset = cpu_to_be64(0xFFFFFFFFFFFFFFFFULL);
+ footer.data_offset = cpu_to_be64(0xFFFFFFFFFFFFFFFFULL);
}
- footer->timestamp = cpu_to_be32(time(NULL) - VHD_TIMESTAMP_BASE);
+ footer.timestamp = cpu_to_be32(time(NULL) - VHD_TIMESTAMP_BASE);
/* Version of Virtual PC 2007 */
- footer->major = cpu_to_be16(0x0005);
- footer->minor = cpu_to_be16(0x0003);
- footer->orig_size = cpu_to_be64(total_size);
- footer->current_size = cpu_to_be64(total_size);
- footer->cyls = cpu_to_be16(cyls);
- footer->heads = heads;
- footer->secs_per_cyl = secs_per_cyl;
+ footer.major = cpu_to_be16(0x0005);
+ footer.minor = cpu_to_be16(0x0003);
+ footer.orig_size = cpu_to_be64(total_size);
+ footer.current_size = cpu_to_be64(total_size);
+ footer.cyls = cpu_to_be16(cyls);
+ footer.heads = heads;
+ footer.secs_per_cyl = secs_per_cyl;
- footer->type = cpu_to_be32(disk_type);
+ footer.type = cpu_to_be32(disk_type);
qemu_uuid_generate(&uuid);
- footer->uuid = uuid;
+ footer.uuid = uuid;
- footer->checksum = cpu_to_be32(vpc_checksum(buf, HEADER_SIZE));
+ footer.checksum = cpu_to_be32(vpc_checksum(&footer, sizeof(footer)));
if (disk_type == VHD_DYNAMIC) {
- ret = create_dynamic_disk(blk, buf, total_sectors);
+ ret = create_dynamic_disk(blk, &footer, total_sectors);
if (ret < 0) {
error_setg(errp, "Unable to create or write VHD header");
}
} else {
- ret = create_fixed_disk(blk, buf, total_size, errp);
+ ret = create_fixed_disk(blk, &footer, total_size, errp);
}
out:
@@ -1170,9 +1169,8 @@ fail:
static int vpc_has_zero_init(BlockDriverState *bs)
{
BDRVVPCState *s = bs->opaque;
- VHDFooter *footer = (VHDFooter *) s->footer_buf;
- if (be32_to_cpu(footer->type) == VHD_FIXED) {
+ if (be32_to_cpu(s->footer.type) == VHD_FIXED) {
return bdrv_has_zero_init(bs->file->bs);
} else {
return 1;
diff --git a/bsd-user/main.c b/bsd-user/main.c
index 0a918e8..9c700c6 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -512,6 +512,7 @@ void cpu_loop(CPUSPARCState *env)
case 0x141:
if (bsd_type != target_freebsd)
goto badtrap;
+ /* fallthrough */
case 0x100:
#endif
syscall_nr = env->gregs[1];
diff --git a/configure b/configure
index c228f7c..881af4b 100755
--- a/configure
+++ b/configure
@@ -2023,6 +2023,7 @@ add_to warn_flags -Wempty-body
add_to warn_flags -Wnested-externs
add_to warn_flags -Wendif-labels
add_to warn_flags -Wexpansion-to-defined
+add_to warn_flags -Wimplicit-fallthrough=2
nowarn_flags=
add_to nowarn_flags -Wno-initializer-overrides
diff --git a/disas/libvixl/vixl/a64/disasm-a64.cc b/disas/libvixl/vixl/a64/disasm-a64.cc
index 7a58a5c..f34d1d6 100644
--- a/disas/libvixl/vixl/a64/disasm-a64.cc
+++ b/disas/libvixl/vixl/a64/disasm-a64.cc
@@ -2985,6 +2985,10 @@ int Disassembler::SubstituteImmediateField(const Instruction* instr,
}
return 3;
}
+ default: {
+ VIXL_UNIMPLEMENTED();
+ return 0;
+ }
}
}
case 'C': { // ICondB - Immediate Conditional Branch.
diff --git a/disas/libvixl/vixl/globals.h b/disas/libvixl/vixl/globals.h
index 61dc9f7..7099aa5 100644
--- a/disas/libvixl/vixl/globals.h
+++ b/disas/libvixl/vixl/globals.h
@@ -108,10 +108,12 @@ inline void USE(T1, T2, T3, T4) {}
#define __has_warning(x) 0
#endif
-// Note: This option is only available for Clang. And will only be enabled for
-// C++11(201103L).
+// Fallthrough annotation for Clang and C++11(201103L).
#if __has_warning("-Wimplicit-fallthrough") && __cplusplus >= 201103L
#define VIXL_FALLTHROUGH() [[clang::fallthrough]] //NOLINT
+// Fallthrough annotation for GCC >= 7.
+#elif __GNUC__ >= 7
+ #define VIXL_FALLTHROUGH() __attribute__((fallthrough))
#else
#define VIXL_FALLTHROUGH() do {} while (0)
#endif
diff --git a/docs/devel/migration.rst b/docs/devel/migration.rst
index 49112bb..ad381b8 100644
--- a/docs/devel/migration.rst
+++ b/docs/devel/migration.rst
@@ -53,22 +53,23 @@ savevm/loadvm functionality.
Debugging
=========
-The migration stream can be analyzed thanks to `scripts/analyze_migration.py`.
+The migration stream can be analyzed thanks to `scripts/analyze-migration.py`.
Example usage:
.. code-block:: shell
- $ qemu-system-x86_64
- (qemu) migrate "exec:cat > mig"
- $ ./scripts/analyze_migration.py -f mig
+ $ qemu-system-x86_64 -display none -monitor stdio
+ (qemu) migrate "exec:cat > mig"
+ (qemu) q
+ $ ./scripts/analyze-migration.py -f mig
{
"ram (3)": {
"section sizes": {
"pc.ram": "0x0000000008000000",
...
-See also ``analyze_migration.py -h`` help for more options.
+See also ``analyze-migration.py -h`` help for more options.
Common infrastructure
=====================
diff --git a/docs/interop/conf.py b/docs/interop/conf.py
index 2634ca3..f4370aa 100644
--- a/docs/interop/conf.py
+++ b/docs/interop/conf.py
@@ -23,4 +23,6 @@ man_pages = [
[], 7),
('qemu-qmp-ref', 'qemu-qmp-ref', 'QEMU QMP Reference Manual',
[], 7),
+ ('qemu-storage-daemon-qmp-ref', 'qemu-storage-daemon-qmp-ref',
+ 'QEMU Storage Daemon QMP Reference Manual', [], 7),
]
diff --git a/docs/interop/index.rst b/docs/interop/index.rst
index cd78d67..95d5649 100644
--- a/docs/interop/index.rst
+++ b/docs/interop/index.rst
@@ -20,6 +20,7 @@ Contents:
qemu-ga
qemu-ga-ref
qemu-qmp-ref
+ qemu-storage-daemon-qmp-ref
vhost-user
vhost-user-gpu
vhost-vdpa
diff --git a/docs/interop/qemu-storage-daemon-qmp-ref.rst b/docs/interop/qemu-storage-daemon-qmp-ref.rst
new file mode 100644
index 0000000..caf9dad
--- /dev/null
+++ b/docs/interop/qemu-storage-daemon-qmp-ref.rst
@@ -0,0 +1,13 @@
+QEMU Storage Daemon QMP Reference Manual
+========================================
+
+..
+ TODO: the old Texinfo manual used to note that this manual
+ is GPL-v2-or-later. We should make that reader-visible
+ both here and in our Sphinx manuals more generally.
+
+..
+ TODO: display the QEMU version, both here and in our Sphinx manuals
+ more generally.
+
+.. qapi-doc:: storage-daemon/qapi/qapi-schema.json
diff --git a/docs/meson.build b/docs/meson.build
index bb8fe4c..71641b4 100644
--- a/docs/meson.build
+++ b/docs/meson.build
@@ -56,6 +56,7 @@ if build_docs
'qemu-ga.8': (have_tools ? 'man8' : ''),
'qemu-ga-ref.7': 'man7',
'qemu-qmp-ref.7': 'man7',
+ 'qemu-storage-daemon-qmp-ref.7': (have_tools ? 'man7' : ''),
},
'tools': {
'qemu-img.1': (have_tools ? 'man1' : ''),
diff --git a/docs/tools/conf.py b/docs/tools/conf.py
index 4760d36..7072d99 100644
--- a/docs/tools/conf.py
+++ b/docs/tools/conf.py
@@ -20,6 +20,8 @@ html_theme_options['description'] = \
man_pages = [
('qemu-img', 'qemu-img', u'QEMU disk image utility',
['Fabrice Bellard'], 1),
+ ('qemu-storage-daemon', 'qemu-storage-daemon', u'QEMU storage daemon',
+ [], 1),
('qemu-nbd', 'qemu-nbd', u'QEMU Disk Network Block Device Server',
['Anthony Liguori <anthony@codemonkey.ws>'], 8),
('qemu-pr-helper', 'qemu-pr-helper', 'QEMU persistent reservation helper',
diff --git a/docs/tools/index.rst b/docs/tools/index.rst
index b99f86c..3a5829c 100644
--- a/docs/tools/index.rst
+++ b/docs/tools/index.rst
@@ -11,6 +11,7 @@ Contents:
:maxdepth: 2
qemu-img
+ qemu-storage-daemon
qemu-nbd
qemu-pr-helper
qemu-trace-stap
diff --git a/docs/tools/qemu-storage-daemon.rst b/docs/tools/qemu-storage-daemon.rst
new file mode 100644
index 0000000..f63627e
--- /dev/null
+++ b/docs/tools/qemu-storage-daemon.rst
@@ -0,0 +1,148 @@
+QEMU Storage Daemon
+===================
+
+Synopsis
+--------
+
+**qemu-storage-daemon** [options]
+
+Description
+-----------
+
+qemu-storage-daemon provides disk image functionality from QEMU, qemu-img, and
+qemu-nbd in a long-running process controlled via QMP commands without running
+a virtual machine. It can export disk images, run block job operations, and
+perform other disk-related operations. The daemon is controlled via a QMP
+monitor and initial configuration from the command-line.
+
+The daemon offers the following subset of QEMU features:
+
+* Block nodes
+* Block jobs
+* Block exports
+* Throttle groups
+* Character devices
+* Crypto and secrets
+* QMP
+* IOThreads
+
+Commands can be sent over a QEMU Monitor Protocol (QMP) connection. See the
+:manpage:`qemu-storage-daemon-qmp-ref(7)` manual page for a description of the
+commands.
+
+The daemon runs until it is stopped using the ``quit`` QMP command or
+SIGINT/SIGHUP/SIGTERM.
+
+**Warning:** Never modify images in use by a running virtual machine or any
+other process; this may destroy the image. Also, be aware that querying an
+image that is being modified by another process may encounter inconsistent
+state.
+
+Options
+-------
+
+.. program:: qemu-storage-daemon
+
+Standard options:
+
+.. option:: -h, --help
+
+ Display help and exit
+
+.. option:: -V, --version
+
+ Display version information and exit
+
+.. option:: -T, --trace [[enable=]PATTERN][,events=FILE][,file=FILE]
+
+ .. include:: ../qemu-option-trace.rst.inc
+
+.. option:: --blockdev BLOCKDEVDEF
+
+ is a block node definition. See the :manpage:`qemu(1)` manual page for a
+ description of block node properties and the :manpage:`qemu-block-drivers(7)`
+ manual page for a description of driver-specific parameters.
+
+.. option:: --chardev CHARDEVDEF
+
+ is a character device definition. See the :manpage:`qemu(1)` manual page for
+ a description of character device properties. A common character device
+ definition configures a UNIX domain socket::
+
+ --chardev socket,id=char1,path=/tmp/qmp.sock,server,nowait
+
+.. option:: --export [type=]nbd,id=<id>,node-name=<node-name>[,name=<export-name>][,writable=on|off][,bitmap=<name>]
+ --export [type=]vhost-user-blk,id=<id>,node-name=<node-name>,addr.type=unix,addr.path=<socket-path>[,writable=on|off][,logical-block-size=<block-size>][,num-queues=<num-queues>]
+ --export [type=]vhost-user-blk,id=<id>,node-name=<node-name>,addr.type=fd,addr.str=<fd>[,writable=on|off][,logical-block-size=<block-size>][,num-queues=<num-queues>]
+
+ is a block export definition. ``node-name`` is the block node that should be
+ exported. ``writable`` determines whether or not the export allows write
+ requests for modifying data (the default is off).
+
+ The ``nbd`` export type requires ``--nbd-server`` (see below). ``name`` is
+ the NBD export name. ``bitmap`` is the name of a dirty bitmap reachable from
+ the block node, so the NBD client can use NBD_OPT_SET_META_CONTEXT with the
+ metadata context name "qemu:dirty-bitmap:BITMAP" to inspect the bitmap.
+
+ The ``vhost-user-blk`` export type takes a vhost-user socket address on which
+ it accept incoming connections. Both
+ ``addr.type=unix,addr.path=<socket-path>`` for UNIX domain sockets and
+ ``addr.type=fd,addr.str=<fd>`` for file descriptor passing are supported.
+ ``logical-block-size`` sets the logical block size in bytes (the default is
+ 512). ``num-queues`` sets the number of virtqueues (the default is 1).
+
+.. option:: --monitor MONITORDEF
+
+ is a QMP monitor definition. See the :manpage:`qemu(1)` manual page for
+ a description of QMP monitor properties. A common QMP monitor definition
+ configures a monitor on character device ``char1``::
+
+ --monitor chardev=char1
+
+.. option:: --nbd-server addr.type=inet,addr.host=<host>,addr.port=<port>[,tls-creds=<id>][,tls-authz=<id>][,max-connections=<n>]
+ --nbd-server addr.type=unix,addr.path=<path>[,tls-creds=<id>][,tls-authz=<id>][,max-connections=<n>]
+
+ is a server for NBD exports. Both TCP and UNIX domain sockets are supported.
+ TLS encryption can be configured using ``--object`` tls-creds-* and authz-*
+ secrets (see below).
+
+ To configure an NBD server on UNIX domain socket path ``/tmp/nbd.sock``::
+
+ --nbd-server addr.type=unix,addr.path=/tmp/nbd.sock
+
+.. option:: --object help
+ --object <type>,help
+ --object <type>[,<property>=<value>...]
+
+ is a QEMU user creatable object definition. List object types with ``help``.
+ List object properties with ``<type>,help``. See the :manpage:`qemu(1)`
+ manual page for a description of the object properties.
+
+Examples
+--------
+Launch the daemon with QMP monitor socket ``qmp.sock`` so clients can execute
+QMP commands::
+
+ $ qemu-storage-daemon \
+ --chardev socket,path=qmp.sock,server,nowait,id=char1 \
+ --monitor chardev=char1
+
+Export raw image file ``disk.img`` over NBD UNIX domain socket ``nbd.sock``::
+
+ $ qemu-storage-daemon \
+ --blockdev driver=file,node-name=disk,filename=disk.img \
+ --nbd-server addr.type=unix,addr.path=nbd.sock \
+ --export type=nbd,id=export,node-name=disk,writable=on
+
+Export a qcow2 image file ``disk.qcow2`` as a vhosts-user-blk device over UNIX
+domain socket ``vhost-user-blk.sock``::
+
+ $ qemu-storage-daemon \
+ --blockdev driver=file,node-name=file,filename=disk.qcow2 \
+ --blockdev driver=qcow2,node-name=qcow2,file=file \
+ --export type=vhost-user-blk,id=export,addr.type=unix,addr.path=vhost-user-blk.sock,node-name=qcow2
+
+See also
+--------
+
+:manpage:`qemu(1)`, :manpage:`qemu-block-drivers(7)`, :manpage:`qemu-storage-daemon-qmp-ref(7)`
diff --git a/docs/user/main.rst b/docs/user/main.rst
index bd99b0f..8dfe232 100644
--- a/docs/user/main.rst
+++ b/docs/user/main.rst
@@ -170,68 +170,81 @@ QEMU_STRACE
Other binaries
~~~~~~~~~~~~~~
-user mode (Alpha)
-``qemu-alpha`` TODO.
+- user mode (Alpha)
-user mode (Arm)
-``qemu-armeb`` TODO.
+ * ``qemu-alpha`` TODO.
-user mode (Arm)
-``qemu-arm`` is also capable of running Arm \"Angel\" semihosted ELF
-binaries (as implemented by the arm-elf and arm-eabi Newlib/GDB
-configurations), and arm-uclinux bFLT format binaries.
+- user mode (Arm)
-user mode (ColdFire)
-user mode (M68K)
-``qemu-m68k`` is capable of running semihosted binaries using the BDM
-(m5xxx-ram-hosted.ld) or m68k-sim (sim.ld) syscall interfaces, and
-coldfire uClinux bFLT format binaries.
+ * ``qemu-armeb`` TODO.
-The binary format is detected automatically.
+ * ``qemu-arm`` is also capable of running Arm \"Angel\" semihosted ELF
+ binaries (as implemented by the arm-elf and arm-eabi Newlib/GDB
+ configurations), and arm-uclinux bFLT format binaries.
-user mode (Cris)
-``qemu-cris`` TODO.
+- user mode (ColdFire)
-user mode (i386)
-``qemu-i386`` TODO. ``qemu-x86_64`` TODO.
+- user mode (M68K)
-user mode (Microblaze)
-``qemu-microblaze`` TODO.
+ * ``qemu-m68k`` is capable of running semihosted binaries using the BDM
+ (m5xxx-ram-hosted.ld) or m68k-sim (sim.ld) syscall interfaces, and
+ coldfire uClinux bFLT format binaries.
-user mode (MIPS)
-``qemu-mips`` executes 32-bit big endian MIPS binaries (MIPS O32 ABI).
+ The binary format is detected automatically.
-``qemu-mipsel`` executes 32-bit little endian MIPS binaries (MIPS O32
-ABI).
+- user mode (Cris)
-``qemu-mips64`` executes 64-bit big endian MIPS binaries (MIPS N64 ABI).
+ * ``qemu-cris`` TODO.
-``qemu-mips64el`` executes 64-bit little endian MIPS binaries (MIPS N64
-ABI).
+- user mode (i386)
-``qemu-mipsn32`` executes 32-bit big endian MIPS binaries (MIPS N32
-ABI).
+ * ``qemu-i386`` TODO.
+ * ``qemu-x86_64`` TODO.
-``qemu-mipsn32el`` executes 32-bit little endian MIPS binaries (MIPS N32
-ABI).
+- user mode (Microblaze)
-user mode (NiosII)
-``qemu-nios2`` TODO.
+ * ``qemu-microblaze`` TODO.
-user mode (PowerPC)
-``qemu-ppc64abi32`` TODO. ``qemu-ppc64`` TODO. ``qemu-ppc`` TODO.
+- user mode (MIPS)
-user mode (SH4)
-``qemu-sh4eb`` TODO. ``qemu-sh4`` TODO.
+ * ``qemu-mips`` executes 32-bit big endian MIPS binaries (MIPS O32 ABI).
-user mode (SPARC)
-``qemu-sparc`` can execute Sparc32 binaries (Sparc32 CPU, 32 bit ABI).
+ * ``qemu-mipsel`` executes 32-bit little endian MIPS binaries (MIPS O32 ABI).
-``qemu-sparc32plus`` can execute Sparc32 and SPARC32PLUS binaries
-(Sparc64 CPU, 32 bit ABI).
+ * ``qemu-mips64`` executes 64-bit big endian MIPS binaries (MIPS N64 ABI).
-``qemu-sparc64`` can execute some Sparc64 (Sparc64 CPU, 64 bit ABI) and
-SPARC32PLUS binaries (Sparc64 CPU, 32 bit ABI).
+ * ``qemu-mips64el`` executes 64-bit little endian MIPS binaries (MIPS N64
+ ABI).
+
+ * ``qemu-mipsn32`` executes 32-bit big endian MIPS binaries (MIPS N32 ABI).
+
+ * ``qemu-mipsn32el`` executes 32-bit little endian MIPS binaries (MIPS N32
+ ABI).
+
+- user mode (NiosII)
+
+ * ``qemu-nios2`` TODO.
+
+- user mode (PowerPC)
+
+ * ``qemu-ppc64abi32`` TODO.
+ * ``qemu-ppc64`` TODO.
+ * ``qemu-ppc`` TODO.
+
+- user mode (SH4)
+
+ * ``qemu-sh4eb`` TODO.
+ * ``qemu-sh4`` TODO.
+
+- user mode (SPARC)
+
+ * ``qemu-sparc`` can execute Sparc32 binaries (Sparc32 CPU, 32 bit ABI).
+
+ * ``qemu-sparc32plus`` can execute Sparc32 and SPARC32PLUS binaries
+ (Sparc64 CPU, 32 bit ABI).
+
+ * ``qemu-sparc64`` can execute some Sparc64 (Sparc64 CPU, 64 bit ABI) and
+ SPARC32PLUS binaries (Sparc64 CPU, 32 bit ABI).
BSD User space emulator
-----------------------
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 470a420..73e0832 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -40,7 +40,7 @@ SRST
ERST
{
- .name = "q|quit",
+ .name = "quit|q",
.args_type = "",
.params = "",
.help = "quit the emulator",
@@ -49,7 +49,7 @@ ERST
},
SRST
-``q`` or ``quit``
+``quit`` or ``q``
Quit the emulator.
ERST
@@ -401,7 +401,7 @@ SRST
ERST
{
- .name = "c|cont",
+ .name = "cont|c",
.args_type = "",
.params = "",
.help = "resume emulation",
@@ -409,7 +409,7 @@ ERST
},
SRST
-``c`` or ``cont``
+``cont`` or ``c``
Resume emulation.
ERST
@@ -554,7 +554,7 @@ SRST
ERST
{
- .name = "p|print",
+ .name = "print|p",
.args_type = "fmt:/,val:l",
.params = "/fmt expr",
.help = "print expression value (use $reg for CPU register access)",
@@ -562,7 +562,7 @@ ERST
},
SRST
-``p`` or ``print/``\ *fmt* *expr*
+``print`` or ``p/``\ *fmt* *expr*
Print expression value. Only the *format* part of *fmt* is
used.
ERST
diff --git a/hw/block/nand.c b/hw/block/nand.c
index 1d7a48a..9ed54a0 100644
--- a/hw/block/nand.c
+++ b/hw/block/nand.c
@@ -137,7 +137,7 @@ static void mem_and(uint8_t *dest, const uint8_t *src, size_t n)
# define ADDR_SHIFT 16
# include "nand.c"
-/* Information based on Linux drivers/mtd/nand/nand_ids.c */
+/* Information based on Linux drivers/mtd/nand/raw/nand_ids.c */
static const struct {
int size;
int width;
@@ -147,21 +147,11 @@ static const struct {
} nand_flash_ids[0x100] = {
[0 ... 0xff] = { 0 },
- [0x6e] = { 1, 8, 8, 4, 0 },
- [0x64] = { 2, 8, 8, 4, 0 },
[0x6b] = { 4, 8, 9, 4, 0 },
- [0xe8] = { 1, 8, 8, 4, 0 },
- [0xec] = { 1, 8, 8, 4, 0 },
- [0xea] = { 2, 8, 8, 4, 0 },
- [0xd5] = { 4, 8, 9, 4, 0 },
[0xe3] = { 4, 8, 9, 4, 0 },
[0xe5] = { 4, 8, 9, 4, 0 },
[0xd6] = { 8, 8, 9, 4, 0 },
-
- [0x39] = { 8, 8, 9, 4, 0 },
[0xe6] = { 8, 8, 9, 4, 0 },
- [0x49] = { 8, 16, 9, 4, NAND_BUSWIDTH_16 },
- [0x59] = { 8, 16, 9, 4, NAND_BUSWIDTH_16 },
[0x33] = { 16, 8, 9, 5, 0 },
[0x73] = { 16, 8, 9, 5, 0 },
diff --git a/hw/core/register.c b/hw/core/register.c
index 3600ef5..d6f8c20 100644
--- a/hw/core/register.c
+++ b/hw/core/register.c
@@ -80,7 +80,7 @@ void register_write(RegisterInfo *reg, uint64_t val, uint64_t we,
if (!ac || !ac->name) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: write to undefined device state "
- "(written value: %#" PRIx64 ")\n", prefix, val);
+ "(written value: 0x%" PRIx64 ")\n", prefix, val);
return;
}
@@ -89,14 +89,14 @@ void register_write(RegisterInfo *reg, uint64_t val, uint64_t we,
test = (old_val ^ val) & ac->rsvd;
if (test) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: change of value in reserved bit"
- "fields: %#" PRIx64 ")\n", prefix, test);
+ "fields: 0x%" PRIx64 ")\n", prefix, test);
}
test = val & ac->unimp;
if (test) {
qemu_log_mask(LOG_UNIMP,
- "%s:%s writing %#" PRIx64 " to unimplemented bits:" \
- " %#" PRIx64 "\n",
+ "%s:%s writing 0x%" PRIx64 " to unimplemented bits:" \
+ " 0x%" PRIx64 "\n",
prefix, reg->access->name, val, ac->unimp);
}
@@ -112,7 +112,7 @@ void register_write(RegisterInfo *reg, uint64_t val, uint64_t we,
}
if (debug) {
- qemu_log("%s:%s: write of value %#" PRIx64 "\n", prefix, ac->name,
+ qemu_log("%s:%s: write of value 0x%" PRIx64 "\n", prefix, ac->name,
new_val);
}
@@ -150,7 +150,7 @@ uint64_t register_read(RegisterInfo *reg, uint64_t re, const char* prefix,
}
if (debug) {
- qemu_log("%s:%s: read of value %#" PRIx64 "\n", prefix,
+ qemu_log("%s:%s: read of value 0x%" PRIx64 "\n", prefix,
ac->name, ret);
}
@@ -193,7 +193,7 @@ void register_write_memory(void *opaque, hwaddr addr,
if (!reg) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: write to unimplemented register " \
- "at address: %#" PRIx64 "\n", reg_array->prefix, addr);
+ "at address: 0x%" PRIx64 "\n", reg_array->prefix, addr);
return;
}
@@ -222,7 +222,7 @@ uint64_t register_read_memory(void *opaque, hwaddr addr,
if (!reg) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: read to unimplemented register " \
- "at address: %#" PRIx64 "\n", reg_array->prefix, addr);
+ "at address: 0x%" PRIx64 "\n", reg_array->prefix, addr);
return 0;
}
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
index 187eb05..d040a5d 100644
--- a/hw/intc/arm_gicv3_kvm.c
+++ b/hw/intc/arm_gicv3_kvm.c
@@ -478,9 +478,11 @@ static void kvm_arm_gicv3_put(GICv3State *s)
kvm_gicc_access(s, ICC_AP0R_EL1(3), ncpu, &reg64, true);
reg64 = c->icc_apr[GICV3_G0][2];
kvm_gicc_access(s, ICC_AP0R_EL1(2), ncpu, &reg64, true);
+ /* fall through */
case 6:
reg64 = c->icc_apr[GICV3_G0][1];
kvm_gicc_access(s, ICC_AP0R_EL1(1), ncpu, &reg64, true);
+ /* fall through */
default:
reg64 = c->icc_apr[GICV3_G0][0];
kvm_gicc_access(s, ICC_AP0R_EL1(0), ncpu, &reg64, true);
@@ -492,9 +494,11 @@ static void kvm_arm_gicv3_put(GICv3State *s)
kvm_gicc_access(s, ICC_AP1R_EL1(3), ncpu, &reg64, true);
reg64 = c->icc_apr[GICV3_G1NS][2];
kvm_gicc_access(s, ICC_AP1R_EL1(2), ncpu, &reg64, true);
+ /* fall through */
case 6:
reg64 = c->icc_apr[GICV3_G1NS][1];
kvm_gicc_access(s, ICC_AP1R_EL1(1), ncpu, &reg64, true);
+ /* fall through */
default:
reg64 = c->icc_apr[GICV3_G1NS][0];
kvm_gicc_access(s, ICC_AP1R_EL1(0), ncpu, &reg64, true);
@@ -631,9 +635,11 @@ static void kvm_arm_gicv3_get(GICv3State *s)
c->icc_apr[GICV3_G0][3] = reg64;
kvm_gicc_access(s, ICC_AP0R_EL1(2), ncpu, &reg64, false);
c->icc_apr[GICV3_G0][2] = reg64;
+ /* fall through */
case 6:
kvm_gicc_access(s, ICC_AP0R_EL1(1), ncpu, &reg64, false);
c->icc_apr[GICV3_G0][1] = reg64;
+ /* fall through */
default:
kvm_gicc_access(s, ICC_AP0R_EL1(0), ncpu, &reg64, false);
c->icc_apr[GICV3_G0][0] = reg64;
@@ -645,9 +651,11 @@ static void kvm_arm_gicv3_get(GICv3State *s)
c->icc_apr[GICV3_G1NS][3] = reg64;
kvm_gicc_access(s, ICC_AP1R_EL1(2), ncpu, &reg64, false);
c->icc_apr[GICV3_G1NS][2] = reg64;
+ /* fall through */
case 6:
kvm_gicc_access(s, ICC_AP1R_EL1(1), ncpu, &reg64, false);
c->icc_apr[GICV3_G1NS][1] = reg64;
+ /* fall through */
default:
kvm_gicc_access(s, ICC_AP1R_EL1(0), ncpu, &reg64, false);
c->icc_apr[GICV3_G1NS][0] = reg64;
diff --git a/hw/intc/ibex_plic.c b/hw/intc/ibex_plic.c
index 341c9db..c1b72fc 100644
--- a/hw/intc/ibex_plic.c
+++ b/hw/intc/ibex_plic.c
@@ -43,16 +43,23 @@ static void ibex_plic_irqs_set_pending(IbexPlicState *s, int irq, bool level)
{
int pending_num = irq / 32;
+ if (!level) {
+ /*
+ * If the level is low make sure we clear the hidden_pending.
+ */
+ s->hidden_pending[pending_num] &= ~(1 << (irq % 32));
+ }
+
if (s->claimed[pending_num] & 1 << (irq % 32)) {
/*
* The interrupt has been claimed, but not completed.
* The pending bit can't be set.
+ * Save the pending level for after the interrupt is completed.
*/
s->hidden_pending[pending_num] |= level << (irq % 32);
- return;
+ } else {
+ s->pending[pending_num] |= level << (irq % 32);
}
-
- s->pending[pending_num] |= level << (irq % 32);
}
static bool ibex_plic_irqs_pending(IbexPlicState *s, uint32_t context)
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
index d62f3dc..83586ae 100644
--- a/hw/riscv/boot.c
+++ b/hw/riscv/boot.c
@@ -33,24 +33,16 @@
#include <libfdt.h>
-#if defined(TARGET_RISCV32)
-#define fw_dynamic_info_data(__val) cpu_to_le32(__val)
-#else
-#define fw_dynamic_info_data(__val) cpu_to_le64(__val)
-#endif
-
-bool riscv_is_32_bit(MachineState *machine)
+bool riscv_is_32bit(RISCVHartArrayState harts)
{
- if (!strncmp(machine->cpu_type, "rv32", 4)) {
- return true;
- } else {
- return false;
- }
+ RISCVCPU hart = harts.harts[0];
+
+ return riscv_cpu_is_32bit(&hart.env);
}
-target_ulong riscv_calc_kernel_start_addr(MachineState *machine,
+target_ulong riscv_calc_kernel_start_addr(RISCVHartArrayState harts,
target_ulong firmware_end_addr) {
- if (riscv_is_32_bit(machine)) {
+ if (riscv_is_32bit(harts)) {
return QEMU_ALIGN_UP(firmware_end_addr, 4 * MiB);
} else {
return QEMU_ALIGN_UP(firmware_end_addr, 2 * MiB);
@@ -218,16 +210,24 @@ uint32_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt)
return fdt_addr;
}
-void riscv_rom_copy_firmware_info(hwaddr rom_base, hwaddr rom_size,
- uint32_t reset_vec_size, uint64_t kernel_entry)
+void riscv_rom_copy_firmware_info(MachineState *machine, hwaddr rom_base,
+ hwaddr rom_size, uint32_t reset_vec_size,
+ uint64_t kernel_entry)
{
struct fw_dynamic_info dinfo;
size_t dinfo_len;
- dinfo.magic = fw_dynamic_info_data(FW_DYNAMIC_INFO_MAGIC_VALUE);
- dinfo.version = fw_dynamic_info_data(FW_DYNAMIC_INFO_VERSION);
- dinfo.next_mode = fw_dynamic_info_data(FW_DYNAMIC_INFO_NEXT_MODE_S);
- dinfo.next_addr = fw_dynamic_info_data(kernel_entry);
+ if (sizeof(dinfo.magic) == 4) {
+ dinfo.magic = cpu_to_le32(FW_DYNAMIC_INFO_MAGIC_VALUE);
+ dinfo.version = cpu_to_le32(FW_DYNAMIC_INFO_VERSION);
+ dinfo.next_mode = cpu_to_le32(FW_DYNAMIC_INFO_NEXT_MODE_S);
+ dinfo.next_addr = cpu_to_le32(kernel_entry);
+ } else {
+ dinfo.magic = cpu_to_le64(FW_DYNAMIC_INFO_MAGIC_VALUE);
+ dinfo.version = cpu_to_le64(FW_DYNAMIC_INFO_VERSION);
+ dinfo.next_mode = cpu_to_le64(FW_DYNAMIC_INFO_NEXT_MODE_S);
+ dinfo.next_addr = cpu_to_le64(kernel_entry);
+ }
dinfo.options = 0;
dinfo.boot_hart = 0;
dinfo_len = sizeof(dinfo);
@@ -247,28 +247,25 @@ void riscv_rom_copy_firmware_info(hwaddr rom_base, hwaddr rom_size,
&address_space_memory);
}
-void riscv_setup_rom_reset_vec(hwaddr start_addr, hwaddr rom_base,
- hwaddr rom_size, uint64_t kernel_entry,
+void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState harts,
+ hwaddr start_addr,
+ hwaddr rom_base, hwaddr rom_size,
+ uint64_t kernel_entry,
uint32_t fdt_load_addr, void *fdt)
{
int i;
uint32_t start_addr_hi32 = 0x00000000;
- #if defined(TARGET_RISCV64)
- start_addr_hi32 = start_addr >> 32;
- #endif
+ if (!riscv_is_32bit(harts)) {
+ start_addr_hi32 = start_addr >> 32;
+ }
/* reset vector */
uint32_t reset_vec[10] = {
0x00000297, /* 1: auipc t0, %pcrel_hi(fw_dyn) */
0x02828613, /* addi a2, t0, %pcrel_lo(1b) */
0xf1402573, /* csrr a0, mhartid */
-#if defined(TARGET_RISCV32)
- 0x0202a583, /* lw a1, 32(t0) */
- 0x0182a283, /* lw t0, 24(t0) */
-#elif defined(TARGET_RISCV64)
- 0x0202b583, /* ld a1, 32(t0) */
- 0x0182b283, /* ld t0, 24(t0) */
-#endif
+ 0,
+ 0,
0x00028067, /* jr t0 */
start_addr, /* start: .dword */
start_addr_hi32,
@@ -276,6 +273,13 @@ void riscv_setup_rom_reset_vec(hwaddr start_addr, hwaddr rom_base,
0x00000000,
/* fw_dyn: */
};
+ if (riscv_is_32bit(harts)) {
+ reset_vec[3] = 0x0202a583; /* lw a1, 32(t0) */
+ reset_vec[4] = 0x0182a283; /* lw t0, 24(t0) */
+ } else {
+ reset_vec[3] = 0x0202b583; /* ld a1, 32(t0) */
+ reset_vec[4] = 0x0182b283; /* ld t0, 24(t0) */
+ }
/* copy in the reset vector in little_endian byte order */
for (i = 0; i < ARRAY_SIZE(reset_vec); i++) {
@@ -283,7 +287,7 @@ void riscv_setup_rom_reset_vec(hwaddr start_addr, hwaddr rom_base,
}
rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec),
rom_base, &address_space_memory);
- riscv_rom_copy_firmware_info(rom_base, rom_size, sizeof(reset_vec),
+ riscv_rom_copy_firmware_info(machine, rom_base, rom_size, sizeof(reset_vec),
kernel_entry);
return;
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
index 37ac46a..e952b49 100644
--- a/hw/riscv/microchip_pfsoc.c
+++ b/hw/riscv/microchip_pfsoc.c
@@ -113,6 +113,8 @@ static const struct MemmapEntry {
[MICROCHIP_PFSOC_MMUART2] = { 0x20102000, 0x1000 },
[MICROCHIP_PFSOC_MMUART3] = { 0x20104000, 0x1000 },
[MICROCHIP_PFSOC_MMUART4] = { 0x20106000, 0x1000 },
+ [MICROCHIP_PFSOC_SPI0] = { 0x20108000, 0x1000 },
+ [MICROCHIP_PFSOC_SPI1] = { 0x20109000, 0x1000 },
[MICROCHIP_PFSOC_I2C1] = { 0x2010b000, 0x1000 },
[MICROCHIP_PFSOC_GEM0] = { 0x20110000, 0x2000 },
[MICROCHIP_PFSOC_GEM1] = { 0x20112000, 0x2000 },
@@ -121,6 +123,7 @@ static const struct MemmapEntry {
[MICROCHIP_PFSOC_GPIO2] = { 0x20122000, 0x1000 },
[MICROCHIP_PFSOC_ENVM_CFG] = { 0x20200000, 0x1000 },
[MICROCHIP_PFSOC_ENVM_DATA] = { 0x20220000, 0x20000 },
+ [MICROCHIP_PFSOC_QSPI_XIP] = { 0x21000000, 0x1000000 },
[MICROCHIP_PFSOC_IOSCB] = { 0x30000000, 0x10000000 },
[MICROCHIP_PFSOC_DRAM_LO] = { 0x80000000, 0x40000000 },
[MICROCHIP_PFSOC_DRAM_LO_ALIAS] = { 0xc0000000, 0x40000000 },
@@ -185,6 +188,7 @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
MemoryRegion *e51_dtim_mem = g_new(MemoryRegion, 1);
MemoryRegion *l2lim_mem = g_new(MemoryRegion, 1);
MemoryRegion *envm_data = g_new(MemoryRegion, 1);
+ MemoryRegion *qspi_xip_mem = g_new(MemoryRegion, 1);
char *plic_hart_config;
size_t plic_hart_config_len;
NICInfo *nd;
@@ -344,6 +348,14 @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
qdev_get_gpio_in(DEVICE(s->plic), MICROCHIP_PFSOC_MMUART4_IRQ),
serial_hd(4));
+ /* SPI */
+ create_unimplemented_device("microchip.pfsoc.spi0",
+ memmap[MICROCHIP_PFSOC_SPI0].base,
+ memmap[MICROCHIP_PFSOC_SPI0].size);
+ create_unimplemented_device("microchip.pfsoc.spi1",
+ memmap[MICROCHIP_PFSOC_SPI1].base,
+ memmap[MICROCHIP_PFSOC_SPI1].size);
+
/* I2C1 */
create_unimplemented_device("microchip.pfsoc.i2c1",
memmap[MICROCHIP_PFSOC_I2C1].base,
@@ -401,6 +413,15 @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
sysbus_realize(SYS_BUS_DEVICE(&s->ioscb), errp);
sysbus_mmio_map(SYS_BUS_DEVICE(&s->ioscb), 0,
memmap[MICROCHIP_PFSOC_IOSCB].base);
+
+ /* QSPI Flash */
+ memory_region_init_rom(qspi_xip_mem, OBJECT(dev),
+ "microchip.pfsoc.qspi_xip",
+ memmap[MICROCHIP_PFSOC_QSPI_XIP].size,
+ &error_fatal);
+ memory_region_add_subregion(system_memory,
+ memmap[MICROCHIP_PFSOC_QSPI_XIP].base,
+ qspi_xip_mem);
}
static void microchip_pfsoc_soc_class_init(ObjectClass *oc, void *data)
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
index cc758b7..af34569 100644
--- a/hw/riscv/opentitan.c
+++ b/hw/riscv/opentitan.c
@@ -35,22 +35,33 @@ static const struct MemmapEntry {
[IBEX_DEV_ROM] = { 0x00008000, 16 * KiB },
[IBEX_DEV_RAM] = { 0x10000000, 0x10000 },
[IBEX_DEV_FLASH] = { 0x20000000, 0x80000 },
- [IBEX_DEV_UART] = { 0x40000000, 0x10000 },
- [IBEX_DEV_GPIO] = { 0x40010000, 0x10000 },
- [IBEX_DEV_SPI] = { 0x40020000, 0x10000 },
- [IBEX_DEV_FLASH_CTRL] = { 0x40030000, 0x10000 },
- [IBEX_DEV_PINMUX] = { 0x40070000, 0x10000 },
- [IBEX_DEV_RV_TIMER] = { 0x40080000, 0x10000 },
- [IBEX_DEV_PLIC] = { 0x40090000, 0x10000 },
- [IBEX_DEV_PWRMGR] = { 0x400A0000, 0x10000 },
- [IBEX_DEV_RSTMGR] = { 0x400B0000, 0x10000 },
- [IBEX_DEV_CLKMGR] = { 0x400C0000, 0x10000 },
- [IBEX_DEV_AES] = { 0x40110000, 0x10000 },
- [IBEX_DEV_HMAC] = { 0x40120000, 0x10000 },
- [IBEX_DEV_ALERT_HANDLER] = { 0x40130000, 0x10000 },
- [IBEX_DEV_NMI_GEN] = { 0x40140000, 0x10000 },
- [IBEX_DEV_USBDEV] = { 0x40150000, 0x10000 },
- [IBEX_DEV_PADCTRL] = { 0x40160000, 0x10000 }
+ [IBEX_DEV_UART] = { 0x40000000, 0x1000 },
+ [IBEX_DEV_GPIO] = { 0x40040000, 0x1000 },
+ [IBEX_DEV_SPI] = { 0x40050000, 0x1000 },
+ [IBEX_DEV_I2C] = { 0x40080000, 0x1000 },
+ [IBEX_DEV_PATTGEN] = { 0x400e0000, 0x1000 },
+ [IBEX_DEV_RV_TIMER] = { 0x40100000, 0x1000 },
+ [IBEX_DEV_SENSOR_CTRL] = { 0x40110000, 0x1000 },
+ [IBEX_DEV_OTP_CTRL] = { 0x40130000, 0x4000 },
+ [IBEX_DEV_PWRMGR] = { 0x40400000, 0x1000 },
+ [IBEX_DEV_RSTMGR] = { 0x40410000, 0x1000 },
+ [IBEX_DEV_CLKMGR] = { 0x40420000, 0x1000 },
+ [IBEX_DEV_PINMUX] = { 0x40460000, 0x1000 },
+ [IBEX_DEV_PADCTRL] = { 0x40470000, 0x1000 },
+ [IBEX_DEV_USBDEV] = { 0x40500000, 0x1000 },
+ [IBEX_DEV_FLASH_CTRL] = { 0x41000000, 0x1000 },
+ [IBEX_DEV_PLIC] = { 0x41010000, 0x1000 },
+ [IBEX_DEV_AES] = { 0x41100000, 0x1000 },
+ [IBEX_DEV_HMAC] = { 0x41110000, 0x1000 },
+ [IBEX_DEV_KMAC] = { 0x41120000, 0x1000 },
+ [IBEX_DEV_KEYMGR] = { 0x41130000, 0x1000 },
+ [IBEX_DEV_CSRNG] = { 0x41150000, 0x1000 },
+ [IBEX_DEV_ENTROPY] = { 0x41160000, 0x1000 },
+ [IBEX_DEV_EDNO] = { 0x41170000, 0x1000 },
+ [IBEX_DEV_EDN1] = { 0x41180000, 0x1000 },
+ [IBEX_DEV_ALERT_HANDLER] = { 0x411b0000, 0x1000 },
+ [IBEX_DEV_NMI_GEN] = { 0x411c0000, 0x1000 },
+ [IBEX_DEV_OTBN] = { 0x411d0000, 0x10000 },
};
static void opentitan_board_init(MachineState *machine)
@@ -156,30 +167,52 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
memmap[IBEX_DEV_GPIO].base, memmap[IBEX_DEV_GPIO].size);
create_unimplemented_device("riscv.lowrisc.ibex.spi",
memmap[IBEX_DEV_SPI].base, memmap[IBEX_DEV_SPI].size);
- create_unimplemented_device("riscv.lowrisc.ibex.flash_ctrl",
- memmap[IBEX_DEV_FLASH_CTRL].base, memmap[IBEX_DEV_FLASH_CTRL].size);
+ create_unimplemented_device("riscv.lowrisc.ibex.i2c",
+ memmap[IBEX_DEV_I2C].base, memmap[IBEX_DEV_I2C].size);
+ create_unimplemented_device("riscv.lowrisc.ibex.pattgen",
+ memmap[IBEX_DEV_PATTGEN].base, memmap[IBEX_DEV_PATTGEN].size);
create_unimplemented_device("riscv.lowrisc.ibex.rv_timer",
memmap[IBEX_DEV_RV_TIMER].base, memmap[IBEX_DEV_RV_TIMER].size);
+ create_unimplemented_device("riscv.lowrisc.ibex.sensor_ctrl",
+ memmap[IBEX_DEV_SENSOR_CTRL].base, memmap[IBEX_DEV_SENSOR_CTRL].size);
+ create_unimplemented_device("riscv.lowrisc.ibex.otp_ctrl",
+ memmap[IBEX_DEV_OTP_CTRL].base, memmap[IBEX_DEV_OTP_CTRL].size);
create_unimplemented_device("riscv.lowrisc.ibex.pwrmgr",
memmap[IBEX_DEV_PWRMGR].base, memmap[IBEX_DEV_PWRMGR].size);
create_unimplemented_device("riscv.lowrisc.ibex.rstmgr",
memmap[IBEX_DEV_RSTMGR].base, memmap[IBEX_DEV_RSTMGR].size);
create_unimplemented_device("riscv.lowrisc.ibex.clkmgr",
memmap[IBEX_DEV_CLKMGR].base, memmap[IBEX_DEV_CLKMGR].size);
+ create_unimplemented_device("riscv.lowrisc.ibex.pinmux",
+ memmap[IBEX_DEV_PINMUX].base, memmap[IBEX_DEV_PINMUX].size);
+ create_unimplemented_device("riscv.lowrisc.ibex.padctrl",
+ memmap[IBEX_DEV_PADCTRL].base, memmap[IBEX_DEV_PADCTRL].size);
+ create_unimplemented_device("riscv.lowrisc.ibex.usbdev",
+ memmap[IBEX_DEV_USBDEV].base, memmap[IBEX_DEV_USBDEV].size);
+ create_unimplemented_device("riscv.lowrisc.ibex.flash_ctrl",
+ memmap[IBEX_DEV_FLASH_CTRL].base, memmap[IBEX_DEV_FLASH_CTRL].size);
create_unimplemented_device("riscv.lowrisc.ibex.aes",
memmap[IBEX_DEV_AES].base, memmap[IBEX_DEV_AES].size);
create_unimplemented_device("riscv.lowrisc.ibex.hmac",
memmap[IBEX_DEV_HMAC].base, memmap[IBEX_DEV_HMAC].size);
- create_unimplemented_device("riscv.lowrisc.ibex.pinmux",
- memmap[IBEX_DEV_PINMUX].base, memmap[IBEX_DEV_PINMUX].size);
+ create_unimplemented_device("riscv.lowrisc.ibex.kmac",
+ memmap[IBEX_DEV_KMAC].base, memmap[IBEX_DEV_KMAC].size);
+ create_unimplemented_device("riscv.lowrisc.ibex.keymgr",
+ memmap[IBEX_DEV_KEYMGR].base, memmap[IBEX_DEV_KEYMGR].size);
+ create_unimplemented_device("riscv.lowrisc.ibex.csrng",
+ memmap[IBEX_DEV_CSRNG].base, memmap[IBEX_DEV_CSRNG].size);
+ create_unimplemented_device("riscv.lowrisc.ibex.entropy",
+ memmap[IBEX_DEV_ENTROPY].base, memmap[IBEX_DEV_ENTROPY].size);
+ create_unimplemented_device("riscv.lowrisc.ibex.edn0",
+ memmap[IBEX_DEV_EDNO].base, memmap[IBEX_DEV_EDNO].size);
+ create_unimplemented_device("riscv.lowrisc.ibex.edn1",
+ memmap[IBEX_DEV_EDN1].base, memmap[IBEX_DEV_EDN1].size);
create_unimplemented_device("riscv.lowrisc.ibex.alert_handler",
memmap[IBEX_DEV_ALERT_HANDLER].base, memmap[IBEX_DEV_ALERT_HANDLER].size);
create_unimplemented_device("riscv.lowrisc.ibex.nmi_gen",
memmap[IBEX_DEV_NMI_GEN].base, memmap[IBEX_DEV_NMI_GEN].size);
- create_unimplemented_device("riscv.lowrisc.ibex.usbdev",
- memmap[IBEX_DEV_USBDEV].base, memmap[IBEX_DEV_USBDEV].size);
- create_unimplemented_device("riscv.lowrisc.ibex.padctrl",
- memmap[IBEX_DEV_PADCTRL].base, memmap[IBEX_DEV_PADCTRL].size);
+ create_unimplemented_device("riscv.lowrisc.ibex.otbn",
+ memmap[IBEX_DEV_OTBN].base, memmap[IBEX_DEV_OTBN].size);
}
static void lowrisc_ibex_soc_class_init(ObjectClass *oc, void *data)
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index e7f6dc5..f5c400d 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -60,12 +60,6 @@
#include <libfdt.h>
-#if defined(TARGET_RISCV32)
-# define BIOS_FILENAME "opensbi-riscv32-generic-fw_dynamic.bin"
-#else
-# define BIOS_FILENAME "opensbi-riscv64-generic-fw_dynamic.bin"
-#endif
-
static const struct MemmapEntry {
hwaddr base;
hwaddr size;
@@ -93,7 +87,7 @@ static const struct MemmapEntry {
#define GEM_REVISION 0x10070109
static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
- uint64_t mem_size, const char *cmdline)
+ uint64_t mem_size, const char *cmdline, bool is_32_bit)
{
MachineState *ms = MACHINE(qdev_get_machine());
void *fdt;
@@ -176,11 +170,11 @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
qemu_fdt_add_subnode(fdt, nodename);
/* cpu 0 is the management hart that does not have mmu */
if (cpu != 0) {
-#if defined(TARGET_RISCV32)
- qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv32");
-#else
- qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv48");
-#endif
+ if (is_32_bit) {
+ qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv32");
+ } else {
+ qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv48");
+ }
isa = riscv_isa_string(&s->soc.u_cpus.harts[cpu - 1]);
} else {
isa = riscv_isa_string(&s->soc.e_cpus.harts[0]);
@@ -386,6 +380,21 @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
g_free(nodename);
nodename = g_strdup_printf("/soc/serial@%lx",
+ (long)memmap[SIFIVE_U_DEV_UART1].base);
+ qemu_fdt_add_subnode(fdt, nodename);
+ qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,uart0");
+ qemu_fdt_setprop_cells(fdt, nodename, "reg",
+ 0x0, memmap[SIFIVE_U_DEV_UART1].base,
+ 0x0, memmap[SIFIVE_U_DEV_UART1].size);
+ qemu_fdt_setprop_cells(fdt, nodename, "clocks",
+ prci_phandle, PRCI_CLK_TLCLK);
+ qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
+ qemu_fdt_setprop_cell(fdt, nodename, "interrupts", SIFIVE_U_UART1_IRQ);
+
+ qemu_fdt_setprop_string(fdt, "/aliases", "serial1", nodename);
+ g_free(nodename);
+
+ nodename = g_strdup_printf("/soc/serial@%lx",
(long)memmap[SIFIVE_U_DEV_UART0].base);
qemu_fdt_add_subnode(fdt, nodename);
qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,uart0");
@@ -456,7 +465,8 @@ static void sifive_u_machine_init(MachineState *machine)
qemu_allocate_irq(sifive_u_machine_reset, NULL, 0));
/* create device tree */
- create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
+ create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline,
+ riscv_is_32bit(s->soc.u_cpus));
if (s->start_in_flash) {
/*
@@ -485,11 +495,18 @@ static void sifive_u_machine_init(MachineState *machine)
break;
}
- firmware_end_addr = riscv_find_and_load_firmware(machine, BIOS_FILENAME,
- start_addr, NULL);
+ if (riscv_is_32bit(s->soc.u_cpus)) {
+ firmware_end_addr = riscv_find_and_load_firmware(machine,
+ "opensbi-riscv32-generic-fw_dynamic.bin",
+ start_addr, NULL);
+ } else {
+ firmware_end_addr = riscv_find_and_load_firmware(machine,
+ "opensbi-riscv64-generic-fw_dynamic.bin",
+ start_addr, NULL);
+ }
if (machine->kernel_filename) {
- kernel_start_addr = riscv_calc_kernel_start_addr(machine,
+ kernel_start_addr = riscv_calc_kernel_start_addr(s->soc.u_cpus,
firmware_end_addr);
kernel_entry = riscv_load_kernel(machine->kernel_filename,
@@ -516,9 +533,9 @@ static void sifive_u_machine_init(MachineState *machine)
/* Compute the fdt load address in dram */
fdt_load_addr = riscv_load_fdt(memmap[SIFIVE_U_DEV_DRAM].base,
machine->ram_size, s->fdt);
- #if defined(TARGET_RISCV64)
- start_addr_hi32 = start_addr >> 32;
- #endif
+ if (!riscv_is_32bit(s->soc.u_cpus)) {
+ start_addr_hi32 = (uint64_t)start_addr >> 32;
+ }
/* reset vector */
uint32_t reset_vec[11] = {
@@ -526,13 +543,8 @@ static void sifive_u_machine_init(MachineState *machine)
0x00000297, /* 1: auipc t0, %pcrel_hi(fw_dyn) */
0x02828613, /* addi a2, t0, %pcrel_lo(1b) */
0xf1402573, /* csrr a0, mhartid */
-#if defined(TARGET_RISCV32)
- 0x0202a583, /* lw a1, 32(t0) */
- 0x0182a283, /* lw t0, 24(t0) */
-#elif defined(TARGET_RISCV64)
- 0x0202b583, /* ld a1, 32(t0) */
- 0x0182b283, /* ld t0, 24(t0) */
-#endif
+ 0,
+ 0,
0x00028067, /* jr t0 */
start_addr, /* start: .dword */
start_addr_hi32,
@@ -540,6 +552,14 @@ static void sifive_u_machine_init(MachineState *machine)
0x00000000,
/* fw_dyn: */
};
+ if (riscv_is_32bit(s->soc.u_cpus)) {
+ reset_vec[4] = 0x0202a583; /* lw a1, 32(t0) */
+ reset_vec[5] = 0x0182a283; /* lw t0, 24(t0) */
+ } else {
+ reset_vec[4] = 0x0202b583; /* ld a1, 32(t0) */
+ reset_vec[5] = 0x0182b283; /* ld t0, 24(t0) */
+ }
+
/* copy in the reset vector in little_endian byte order */
for (i = 0; i < ARRAY_SIZE(reset_vec); i++) {
@@ -548,7 +568,7 @@ static void sifive_u_machine_init(MachineState *machine)
rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec),
memmap[SIFIVE_U_DEV_MROM].base, &address_space_memory);
- riscv_rom_copy_firmware_info(memmap[SIFIVE_U_DEV_MROM].base,
+ riscv_rom_copy_firmware_info(machine, memmap[SIFIVE_U_DEV_MROM].base,
memmap[SIFIVE_U_DEV_MROM].size,
sizeof(reset_vec), kernel_entry);
}
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
index facac6e..e723ca0 100644
--- a/hw/riscv/spike.c
+++ b/hw/riscv/spike.c
@@ -43,17 +43,6 @@
#include "sysemu/qtest.h"
#include "sysemu/sysemu.h"
-/*
- * Not like other RISC-V machines that use plain binary bios images,
- * keeping ELF files here was intentional because BIN files don't work
- * for the Spike machine as HTIF emulation depends on ELF parsing.
- */
-#if defined(TARGET_RISCV32)
-# define BIOS_FILENAME "opensbi-riscv32-generic-fw_dynamic.elf"
-#else
-# define BIOS_FILENAME "opensbi-riscv64-generic-fw_dynamic.elf"
-#endif
-
static const struct MemmapEntry {
hwaddr base;
hwaddr size;
@@ -64,7 +53,7 @@ static const struct MemmapEntry {
};
static void create_fdt(SpikeState *s, const struct MemmapEntry *memmap,
- uint64_t mem_size, const char *cmdline)
+ uint64_t mem_size, const char *cmdline, bool is_32_bit)
{
void *fdt;
uint64_t addr, size;
@@ -115,11 +104,11 @@ static void create_fdt(SpikeState *s, const struct MemmapEntry *memmap,
cpu_name = g_strdup_printf("/cpus/cpu@%d",
s->soc[socket].hartid_base + cpu);
qemu_fdt_add_subnode(fdt, cpu_name);
-#if defined(TARGET_RISCV32)
- qemu_fdt_setprop_string(fdt, cpu_name, "mmu-type", "riscv,sv32");
-#else
- qemu_fdt_setprop_string(fdt, cpu_name, "mmu-type", "riscv,sv48");
-#endif
+ if (is_32_bit) {
+ qemu_fdt_setprop_string(fdt, cpu_name, "mmu-type", "riscv,sv32");
+ } else {
+ qemu_fdt_setprop_string(fdt, cpu_name, "mmu-type", "riscv,sv48");
+ }
name = riscv_isa_string(&s->soc[socket].harts[cpu]);
qemu_fdt_setprop_string(fdt, cpu_name, "riscv,isa", name);
g_free(name);
@@ -254,7 +243,8 @@ static void spike_board_init(MachineState *machine)
main_mem);
/* create device tree */
- create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
+ create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline,
+ riscv_is_32bit(s->soc[0]));
/* boot rom */
memory_region_init_rom(mask_rom, NULL, "riscv.spike.mrom",
@@ -262,12 +252,25 @@ static void spike_board_init(MachineState *machine)
memory_region_add_subregion(system_memory, memmap[SPIKE_MROM].base,
mask_rom);
- firmware_end_addr = riscv_find_and_load_firmware(machine, BIOS_FILENAME,
- memmap[SPIKE_DRAM].base,
- htif_symbol_callback);
+ /*
+ * Not like other RISC-V machines that use plain binary bios images,
+ * keeping ELF files here was intentional because BIN files don't work
+ * for the Spike machine as HTIF emulation depends on ELF parsing.
+ */
+ if (riscv_is_32bit(s->soc[0])) {
+ firmware_end_addr = riscv_find_and_load_firmware(machine,
+ "opensbi-riscv32-generic-fw_dynamic.elf",
+ memmap[SPIKE_DRAM].base,
+ htif_symbol_callback);
+ } else {
+ firmware_end_addr = riscv_find_and_load_firmware(machine,
+ "opensbi-riscv64-generic-fw_dynamic.elf",
+ memmap[SPIKE_DRAM].base,
+ htif_symbol_callback);
+ }
if (machine->kernel_filename) {
- kernel_start_addr = riscv_calc_kernel_start_addr(machine,
+ kernel_start_addr = riscv_calc_kernel_start_addr(s->soc[0],
firmware_end_addr);
kernel_entry = riscv_load_kernel(machine->kernel_filename,
@@ -296,7 +299,8 @@ static void spike_board_init(MachineState *machine)
fdt_load_addr = riscv_load_fdt(memmap[SPIKE_DRAM].base,
machine->ram_size, s->fdt);
/* load the reset vector */
- riscv_setup_rom_reset_vec(memmap[SPIKE_DRAM].base, memmap[SPIKE_MROM].base,
+ riscv_setup_rom_reset_vec(machine, s->soc[0], memmap[SPIKE_DRAM].base,
+ memmap[SPIKE_MROM].base,
memmap[SPIKE_MROM].size, kernel_entry,
fdt_load_addr, s->fdt);
@@ -317,7 +321,7 @@ static void spike_machine_class_init(ObjectClass *oc, void *data)
mc->init = spike_board_init;
mc->max_cpus = SPIKE_CPUS_MAX;
mc->is_default = true;
- mc->default_cpu_type = SPIKE_V1_10_0_CPU;
+ mc->default_cpu_type = TYPE_RISCV_CPU_BASE;
mc->possible_cpu_arch_ids = riscv_numa_possible_cpu_arch_ids;
mc->cpu_index_to_instance_props = riscv_numa_cpu_index_to_props;
mc->get_default_cpu_node_id = riscv_numa_get_default_cpu_node_id;
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 3cc18a7..8de4c35 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -43,12 +43,6 @@
#include "hw/pci/pci.h"
#include "hw/pci-host/gpex.h"
-#if defined(TARGET_RISCV32)
-# define BIOS_FILENAME "opensbi-riscv32-generic-fw_dynamic.bin"
-#else
-# define BIOS_FILENAME "opensbi-riscv64-generic-fw_dynamic.bin"
-#endif
-
static const struct MemmapEntry {
hwaddr base;
hwaddr size;
@@ -177,7 +171,7 @@ static void create_pcie_irq_map(void *fdt, char *nodename,
}
static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
- uint64_t mem_size, const char *cmdline)
+ uint64_t mem_size, const char *cmdline, bool is_32_bit)
{
void *fdt;
int i, cpu, socket;
@@ -240,11 +234,11 @@ static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
cpu_name = g_strdup_printf("/cpus/cpu@%d",
s->soc[socket].hartid_base + cpu);
qemu_fdt_add_subnode(fdt, cpu_name);
-#if defined(TARGET_RISCV32)
- qemu_fdt_setprop_string(fdt, cpu_name, "mmu-type", "riscv,sv32");
-#else
- qemu_fdt_setprop_string(fdt, cpu_name, "mmu-type", "riscv,sv48");
-#endif
+ if (is_32_bit) {
+ qemu_fdt_setprop_string(fdt, cpu_name, "mmu-type", "riscv,sv32");
+ } else {
+ qemu_fdt_setprop_string(fdt, cpu_name, "mmu-type", "riscv,sv48");
+ }
name = riscv_isa_string(&s->soc[socket].harts[cpu]);
qemu_fdt_setprop_string(fdt, cpu_name, "riscv,isa", name);
g_free(name);
@@ -606,7 +600,8 @@ static void virt_machine_init(MachineState *machine)
main_mem);
/* create device tree */
- create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
+ create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline,
+ riscv_is_32bit(s->soc[0]));
/* boot rom */
memory_region_init_rom(mask_rom, NULL, "riscv_virt_board.mrom",
@@ -614,11 +609,18 @@ static void virt_machine_init(MachineState *machine)
memory_region_add_subregion(system_memory, memmap[VIRT_MROM].base,
mask_rom);
- firmware_end_addr = riscv_find_and_load_firmware(machine, BIOS_FILENAME,
- start_addr, NULL);
+ if (riscv_is_32bit(s->soc[0])) {
+ firmware_end_addr = riscv_find_and_load_firmware(machine,
+ "opensbi-riscv32-generic-fw_dynamic.bin",
+ start_addr, NULL);
+ } else {
+ firmware_end_addr = riscv_find_and_load_firmware(machine,
+ "opensbi-riscv64-generic-fw_dynamic.bin",
+ start_addr, NULL);
+ }
if (machine->kernel_filename) {
- kernel_start_addr = riscv_calc_kernel_start_addr(machine,
+ kernel_start_addr = riscv_calc_kernel_start_addr(s->soc[0],
firmware_end_addr);
kernel_entry = riscv_load_kernel(machine->kernel_filename,
@@ -654,7 +656,8 @@ static void virt_machine_init(MachineState *machine)
fdt_load_addr = riscv_load_fdt(memmap[VIRT_DRAM].base,
machine->ram_size, s->fdt);
/* load the reset vector */
- riscv_setup_rom_reset_vec(start_addr, virt_memmap[VIRT_MROM].base,
+ riscv_setup_rom_reset_vec(machine, s->soc[0], start_addr,
+ virt_memmap[VIRT_MROM].base,
virt_memmap[VIRT_MROM].size, kernel_entry,
fdt_load_addr, s->fdt);
@@ -704,7 +707,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
mc->desc = "RISC-V VirtIO board";
mc->init = virt_machine_init;
mc->max_cpus = VIRT_CPUS_MAX;
- mc->default_cpu_type = VIRT_CPU;
+ mc->default_cpu_type = TYPE_RISCV_CPU_BASE;
mc->pci_allow_0_address = true;
mc->possible_cpu_arch_ids = riscv_numa_possible_cpu_arch_ids;
mc->cpu_index_to_instance_props = riscv_numa_cpu_index_to_props;
diff --git a/hw/rtc/twl92230.c b/hw/rtc/twl92230.c
index f838913..006d75e 100644
--- a/hw/rtc/twl92230.c
+++ b/hw/rtc/twl92230.c
@@ -271,37 +271,23 @@ static void menelaus_gpio_set(void *opaque, int line, int level)
static uint8_t menelaus_read(void *opaque, uint8_t addr)
{
MenelausState *s = (MenelausState *) opaque;
- int reg = 0;
switch (addr) {
case MENELAUS_REV:
return 0x22;
- case MENELAUS_VCORE_CTRL5: reg ++;
- case MENELAUS_VCORE_CTRL4: reg ++;
- case MENELAUS_VCORE_CTRL3: reg ++;
- case MENELAUS_VCORE_CTRL2: reg ++;
- case MENELAUS_VCORE_CTRL1:
- return s->vcore[reg];
+ case MENELAUS_VCORE_CTRL1 ... MENELAUS_VCORE_CTRL5:
+ return s->vcore[addr - MENELAUS_VCORE_CTRL1];
- case MENELAUS_DCDC_CTRL3: reg ++;
- case MENELAUS_DCDC_CTRL2: reg ++;
- case MENELAUS_DCDC_CTRL1:
- return s->dcdc[reg];
-
- case MENELAUS_LDO_CTRL8: reg ++;
- case MENELAUS_LDO_CTRL7: reg ++;
- case MENELAUS_LDO_CTRL6: reg ++;
- case MENELAUS_LDO_CTRL5: reg ++;
- case MENELAUS_LDO_CTRL4: reg ++;
- case MENELAUS_LDO_CTRL3: reg ++;
- case MENELAUS_LDO_CTRL2: reg ++;
- case MENELAUS_LDO_CTRL1:
- return s->ldo[reg];
+ case MENELAUS_DCDC_CTRL1 ... MENELAUS_DCDC_CTRL3:
+ return s->dcdc[addr - MENELAUS_DCDC_CTRL1];
+
+ case MENELAUS_LDO_CTRL1 ... MENELAUS_LDO_CTRL8:
+ return s->ldo[addr - MENELAUS_LDO_CTRL1];
- case MENELAUS_SLEEP_CTRL2: reg ++;
case MENELAUS_SLEEP_CTRL1:
- return s->sleep[reg];
+ case MENELAUS_SLEEP_CTRL2:
+ return s->sleep[addr - MENELAUS_SLEEP_CTRL1];
case MENELAUS_DEVICE_OFF:
return 0;
@@ -395,10 +381,8 @@ static uint8_t menelaus_read(void *opaque, uint8_t addr)
case MENELAUS_S2_PULL_DIR:
return s->pull[3];
- case MENELAUS_MCT_CTRL3: reg ++;
- case MENELAUS_MCT_CTRL2: reg ++;
- case MENELAUS_MCT_CTRL1:
- return s->mmc_ctrl[reg];
+ case MENELAUS_MCT_CTRL1 ... MENELAUS_MCT_CTRL3:
+ return s->mmc_ctrl[addr - MENELAUS_MCT_CTRL1];
case MENELAUS_MCT_PIN_ST:
/* TODO: return the real Card Detect */
return 0;
@@ -418,7 +402,6 @@ static void menelaus_write(void *opaque, uint8_t addr, uint8_t value)
{
MenelausState *s = (MenelausState *) opaque;
int line;
- int reg = 0;
struct tm tm;
switch (addr) {
@@ -496,9 +479,9 @@ static void menelaus_write(void *opaque, uint8_t addr, uint8_t value)
s->ldo[7] = value & 3;
break;
- case MENELAUS_SLEEP_CTRL2: reg ++;
case MENELAUS_SLEEP_CTRL1:
- s->sleep[reg] = value;
+ case MENELAUS_SLEEP_CTRL2:
+ s->sleep[addr - MENELAUS_SLEEP_CTRL1] = value;
break;
case MENELAUS_DEVICE_OFF:
@@ -714,6 +697,7 @@ static void menelaus_write(void *opaque, uint8_t addr, uint8_t value)
#ifdef VERBOSE
printf("%s: unknown register %02x\n", __func__, addr);
#endif
+ break;
}
}
diff --git a/hw/timer/renesas_tmr.c b/hw/timer/renesas_tmr.c
index 446f2ea..e03a815 100644
--- a/hw/timer/renesas_tmr.c
+++ b/hw/timer/renesas_tmr.c
@@ -221,6 +221,7 @@ static uint64_t tmr_read(void *opaque, hwaddr addr, unsigned size)
} else if (ch == 0) {
return concat_reg(tmr->tcora);
}
+ /* fall through */
case A_TCORB:
if (size == 1) {
return tmr->tcorb[ch];
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
index 0b01988..20ff5fe 100644
--- a/include/hw/riscv/boot.h
+++ b/include/hw/riscv/boot.h
@@ -22,10 +22,11 @@
#include "exec/cpu-defs.h"
#include "hw/loader.h"
+#include "hw/riscv/riscv_hart.h"
-bool riscv_is_32_bit(MachineState *machine);
+bool riscv_is_32bit(RISCVHartArrayState harts);
-target_ulong riscv_calc_kernel_start_addr(MachineState *machine,
+target_ulong riscv_calc_kernel_start_addr(RISCVHartArrayState harts,
target_ulong firmware_end_addr);
target_ulong riscv_find_and_load_firmware(MachineState *machine,
const char *default_machine_firmware,
@@ -41,10 +42,13 @@ target_ulong riscv_load_kernel(const char *kernel_filename,
hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size,
uint64_t kernel_entry, hwaddr *start);
uint32_t riscv_load_fdt(hwaddr dram_start, uint64_t dram_size, void *fdt);
-void riscv_setup_rom_reset_vec(hwaddr saddr, hwaddr rom_base,
- hwaddr rom_size, uint64_t kernel_entry,
+void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState harts,
+ hwaddr saddr,
+ hwaddr rom_base, hwaddr rom_size,
+ uint64_t kernel_entry,
uint32_t fdt_load_addr, void *fdt);
-void riscv_rom_copy_firmware_info(hwaddr rom_base, hwaddr rom_size,
+void riscv_rom_copy_firmware_info(MachineState *machine, hwaddr rom_base,
+ hwaddr rom_size,
uint32_t reset_vec_size,
uint64_t kernel_entry);
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
index 51d4463..d0c666a 100644
--- a/include/hw/riscv/microchip_pfsoc.h
+++ b/include/hw/riscv/microchip_pfsoc.h
@@ -97,6 +97,8 @@ enum {
MICROCHIP_PFSOC_MMUART2,
MICROCHIP_PFSOC_MMUART3,
MICROCHIP_PFSOC_MMUART4,
+ MICROCHIP_PFSOC_SPI0,
+ MICROCHIP_PFSOC_SPI1,
MICROCHIP_PFSOC_I2C1,
MICROCHIP_PFSOC_GEM0,
MICROCHIP_PFSOC_GEM1,
@@ -105,6 +107,7 @@ enum {
MICROCHIP_PFSOC_GPIO2,
MICROCHIP_PFSOC_ENVM_CFG,
MICROCHIP_PFSOC_ENVM_DATA,
+ MICROCHIP_PFSOC_QSPI_XIP,
MICROCHIP_PFSOC_IOSCB,
MICROCHIP_PFSOC_DRAM_LO,
MICROCHIP_PFSOC_DRAM_LO_ALIAS,
diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
index 5ff0c0f..a5ea3a5 100644
--- a/include/hw/riscv/opentitan.h
+++ b/include/hw/riscv/opentitan.h
@@ -55,19 +55,30 @@ enum {
IBEX_DEV_UART,
IBEX_DEV_GPIO,
IBEX_DEV_SPI,
- IBEX_DEV_FLASH_CTRL,
+ IBEX_DEV_I2C,
+ IBEX_DEV_PATTGEN,
IBEX_DEV_RV_TIMER,
- IBEX_DEV_AES,
- IBEX_DEV_HMAC,
- IBEX_DEV_PLIC,
+ IBEX_DEV_SENSOR_CTRL,
+ IBEX_DEV_OTP_CTRL,
IBEX_DEV_PWRMGR,
IBEX_DEV_RSTMGR,
IBEX_DEV_CLKMGR,
IBEX_DEV_PINMUX,
+ IBEX_DEV_PADCTRL,
+ IBEX_DEV_USBDEV,
+ IBEX_DEV_FLASH_CTRL,
+ IBEX_DEV_PLIC,
+ IBEX_DEV_AES,
+ IBEX_DEV_HMAC,
+ IBEX_DEV_KMAC,
+ IBEX_DEV_KEYMGR,
+ IBEX_DEV_CSRNG,
+ IBEX_DEV_ENTROPY,
+ IBEX_DEV_EDNO,
+ IBEX_DEV_EDN1,
IBEX_DEV_ALERT_HANDLER,
IBEX_DEV_NMI_GEN,
- IBEX_DEV_USBDEV,
- IBEX_DEV_PADCTRL,
+ IBEX_DEV_OTBN,
};
enum {
diff --git a/include/hw/riscv/spike.h b/include/hw/riscv/spike.h
index cddeca2..cdd1a13 100644
--- a/include/hw/riscv/spike.h
+++ b/include/hw/riscv/spike.h
@@ -47,10 +47,4 @@ enum {
SPIKE_DRAM
};
-#if defined(TARGET_RISCV32)
-#define SPIKE_V1_10_0_CPU TYPE_RISCV_CPU_BASE32
-#elif defined(TARGET_RISCV64)
-#define SPIKE_V1_10_0_CPU TYPE_RISCV_CPU_BASE64
-#endif
-
#endif
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
index b4ed9a3..84b7a38 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -89,10 +89,4 @@ enum {
#define FDT_INT_MAP_WIDTH (FDT_PCI_ADDR_CELLS + FDT_PCI_INT_CELLS + 1 + \
FDT_PLIC_ADDR_CELLS + FDT_PLIC_INT_CELLS)
-#if defined(TARGET_RISCV32)
-#define VIRT_CPU TYPE_RISCV_CPU_BASE32
-#elif defined(TARGET_RISCV64)
-#define VIRT_CPU TYPE_RISCV_CPU_BASE64
-#endif
-
#endif
diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h
index 1b9e58e..df9ec08 100644
--- a/include/qemu/compiler.h
+++ b/include/qemu/compiler.h
@@ -222,4 +222,15 @@ extern void QEMU_NORETURN QEMU_ERROR("code path is reachable")
#define qemu_build_not_reached() g_assert_not_reached()
#endif
+/**
+ * In most cases, normal "fallthrough" comments are good enough for
+ * switch-case statements, but sometimes the compiler has problems
+ * with those. In that case you can use QEMU_FALLTHROUGH instead.
+ */
+#if __has_attribute(fallthrough)
+# define QEMU_FALLTHROUGH __attribute__((fallthrough))
+#else
+# define QEMU_FALLTHROUGH do {} while (0) /* fallthrough */
+#endif
+
#endif /* COMPILER_H */
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 0b02a92..a640507 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -7,6 +7,7 @@
#include "qemu.h"
#include "disas/disas.h"
+#include "qemu/bitops.h"
#include "qemu/path.h"
#include "qemu/queue.h"
#include "qemu/guest-random.h"
@@ -985,26 +986,54 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUMIPSState *e
enum {
HWCAP_MIPS_R6 = (1 << 0),
HWCAP_MIPS_MSA = (1 << 1),
+ HWCAP_MIPS_CRC32 = (1 << 2),
+ HWCAP_MIPS_MIPS16 = (1 << 3),
+ HWCAP_MIPS_MDMX = (1 << 4),
+ HWCAP_MIPS_MIPS3D = (1 << 5),
+ HWCAP_MIPS_SMARTMIPS = (1 << 6),
+ HWCAP_MIPS_DSP = (1 << 7),
+ HWCAP_MIPS_DSP2 = (1 << 8),
+ HWCAP_MIPS_DSP3 = (1 << 9),
+ HWCAP_MIPS_MIPS16E2 = (1 << 10),
+ HWCAP_LOONGSON_MMI = (1 << 11),
+ HWCAP_LOONGSON_EXT = (1 << 12),
+ HWCAP_LOONGSON_EXT2 = (1 << 13),
+ HWCAP_LOONGSON_CPUCFG = (1 << 14),
};
#define ELF_HWCAP get_elf_hwcap()
+#define GET_FEATURE_INSN(_flag, _hwcap) \
+ do { if (cpu->env.insn_flags & (_flag)) { hwcaps |= _hwcap; } } while (0)
+
+#define GET_FEATURE_REG_SET(_reg, _mask, _hwcap) \
+ do { if (cpu->env._reg & (_mask)) { hwcaps |= _hwcap; } } while (0)
+
+#define GET_FEATURE_REG_EQU(_reg, _start, _length, _val, _hwcap) \
+ do { \
+ if (extract32(cpu->env._reg, (_start), (_length)) == (_val)) { \
+ hwcaps |= _hwcap; \
+ } \
+ } while (0)
+
static uint32_t get_elf_hwcap(void)
{
MIPSCPU *cpu = MIPS_CPU(thread_cpu);
uint32_t hwcaps = 0;
-#define GET_FEATURE(flag, hwcap) \
- do { if (cpu->env.insn_flags & (flag)) { hwcaps |= hwcap; } } while (0)
-
- GET_FEATURE(ISA_MIPS32R6 | ISA_MIPS64R6, HWCAP_MIPS_R6);
- GET_FEATURE(ASE_MSA, HWCAP_MIPS_MSA);
-
-#undef GET_FEATURE
+ GET_FEATURE_REG_EQU(CP0_Config0, CP0C0_AR, CP0C0_AR_LENGTH,
+ 2, HWCAP_MIPS_R6);
+ GET_FEATURE_REG_SET(CP0_Config3, 1 << CP0C3_MSAP, HWCAP_MIPS_MSA);
+ GET_FEATURE_INSN(ASE_LMMI, HWCAP_LOONGSON_MMI);
+ GET_FEATURE_INSN(ASE_LEXT, HWCAP_LOONGSON_EXT);
return hwcaps;
}
+#undef GET_FEATURE_REG_EQU
+#undef GET_FEATURE_REG_SET
+#undef GET_FEATURE_INSN
+
#endif /* TARGET_MIPS */
#ifdef TARGET_MICROBLAZE
diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
index 8efb4d3..661b5da 100644
--- a/linux-user/ioctls.h
+++ b/linux-user/ioctls.h
@@ -720,3 +720,49 @@
IOCTL(KCOV_DISABLE, 0, TYPE_NULL)
IOCTL(KCOV_INIT_TRACE, IOC_R, TYPE_ULONG)
#endif
+
+ IOCTL(TUNSETDEBUG, IOC_W, TYPE_INT)
+ IOCTL(TUNSETIFF, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_short_ifreq)))
+ IOCTL(TUNSETPERSIST, IOC_W, TYPE_INT)
+ IOCTL(TUNSETOWNER, IOC_W, TYPE_INT)
+ IOCTL(TUNSETLINK, IOC_W, TYPE_INT)
+ IOCTL(TUNSETGROUP, IOC_W, TYPE_INT)
+ IOCTL(TUNGETFEATURES, IOC_R, MK_PTR(TYPE_INT))
+ IOCTL(TUNSETOFFLOAD, IOC_W, TYPE_LONG)
+ IOCTL_SPECIAL(TUNSETTXFILTER, IOC_W, do_ioctl_TUNSETTXFILTER,
+ /*
+ * We can't represent `struct tun_filter` in thunk so leaving
+ * it uninterpreted. do_ioctl_TUNSETTXFILTER will do the
+ * conversion.
+ */
+ TYPE_PTRVOID)
+ IOCTL(TUNGETIFF, IOC_R, MK_PTR(MK_STRUCT(STRUCT_short_ifreq)))
+ IOCTL(TUNGETSNDBUF, IOC_R, MK_PTR(TYPE_INT))
+ IOCTL(TUNSETSNDBUF, IOC_W, MK_PTR(TYPE_INT))
+ /*
+ * TUNATTACHFILTER and TUNDETACHFILTER are not supported. Linux kernel keeps a
+ * user pointer in TUNATTACHFILTER, which we are not able to correctly handle.
+ */
+ IOCTL(TUNGETVNETHDRSZ, IOC_R, MK_PTR(TYPE_INT))
+ IOCTL(TUNSETVNETHDRSZ, IOC_W, MK_PTR(TYPE_INT))
+ IOCTL(TUNSETQUEUE, IOC_W, MK_PTR(MK_STRUCT(STRUCT_short_ifreq)))
+ IOCTL(TUNSETIFINDEX , IOC_W, MK_PTR(TYPE_INT))
+ /* TUNGETFILTER is not supported: see TUNATTACHFILTER. */
+ IOCTL(TUNSETVNETLE, IOC_W, MK_PTR(TYPE_INT))
+ IOCTL(TUNGETVNETLE, IOC_R, MK_PTR(TYPE_INT))
+#ifdef TUNSETVNETBE
+ IOCTL(TUNSETVNETBE, IOC_W, MK_PTR(TYPE_INT))
+ IOCTL(TUNGETVNETBE, IOC_R, MK_PTR(TYPE_INT))
+#endif
+#ifdef TUNSETSTEERINGEBPF
+ IOCTL(TUNSETSTEERINGEBPF, IOC_W, MK_PTR(TYPE_INT))
+#endif
+#ifdef TUNSETFILTEREBPF
+ IOCTL(TUNSETFILTEREBPF, IOC_W, MK_PTR(TYPE_INT))
+#endif
+#ifdef TUNSETCARRIER
+ IOCTL(TUNSETCARRIER, IOC_W, MK_PTR(TYPE_INT))
+#endif
+#ifdef TUNGETDEVNETNS
+ IOCTL(TUNGETDEVNETNS, IOC_R, TYPE_NULL)
+#endif
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 00c05e6..810653c 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -767,20 +767,23 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
}
if (prot == 0) {
host_addr = mremap(g2h(old_addr), old_size, new_size, flags);
- if (host_addr != MAP_FAILED && reserved_va && old_size > new_size) {
- mmap_reserve(old_addr + old_size, old_size - new_size);
+
+ if (host_addr != MAP_FAILED) {
+ /* Check if address fits target address space */
+ if (!guest_range_valid(h2g(host_addr), new_size)) {
+ /* Revert mremap() changes */
+ host_addr = mremap(g2h(old_addr), new_size, old_size,
+ flags);
+ errno = ENOMEM;
+ host_addr = MAP_FAILED;
+ } else if (reserved_va && old_size > new_size) {
+ mmap_reserve(old_addr + old_size, old_size - new_size);
+ }
}
} else {
errno = ENOMEM;
host_addr = MAP_FAILED;
}
- /* Check if address fits target address space */
- if ((unsigned long)host_addr + new_size > (abi_ulong)-1) {
- /* Revert mremap() changes */
- host_addr = mremap(g2h(old_addr), new_size, old_size, flags);
- errno = ENOMEM;
- host_addr = MAP_FAILED;
- }
}
if (host_addr == MAP_FAILED) {
diff --git a/linux-user/sparc/signal.c b/linux-user/sparc/signal.c
index d12adc8..d27b7a3 100644
--- a/linux-user/sparc/signal.c
+++ b/linux-user/sparc/signal.c
@@ -402,8 +402,10 @@ void sparc64_set_context(CPUSPARCState *env)
abi_ulong ucp_addr;
struct target_ucontext *ucp;
target_mc_gregset_t *grp;
+ target_mc_fpu_t *fpup;
abi_ulong pc, npc, tstate;
unsigned int i;
+ unsigned char fenab;
ucp_addr = env->regwptr[WREG_O0];
if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1)) {
@@ -436,16 +438,16 @@ void sparc64_set_context(CPUSPARCState *env)
env->npc = npc;
__get_user(env->y, &((*grp)[SPARC_MC_Y]));
__get_user(tstate, &((*grp)[SPARC_MC_TSTATE]));
+ /* Honour TSTATE_ASI, TSTATE_ICC and TSTATE_XCC only */
env->asi = (tstate >> 24) & 0xff;
- cpu_put_ccr(env, tstate >> 32);
- cpu_put_cwp64(env, tstate & 0x1f);
+ cpu_put_ccr(env, (tstate >> 32) & 0xff);
__get_user(env->gregs[1], (&(*grp)[SPARC_MC_G1]));
__get_user(env->gregs[2], (&(*grp)[SPARC_MC_G2]));
__get_user(env->gregs[3], (&(*grp)[SPARC_MC_G3]));
__get_user(env->gregs[4], (&(*grp)[SPARC_MC_G4]));
__get_user(env->gregs[5], (&(*grp)[SPARC_MC_G5]));
__get_user(env->gregs[6], (&(*grp)[SPARC_MC_G6]));
- __get_user(env->gregs[7], (&(*grp)[SPARC_MC_G7]));
+ /* Skip g7 as that's the thread register in userspace */
/*
* Note that unlike the kernel, we didn't need to mess with the
@@ -467,26 +469,42 @@ void sparc64_set_context(CPUSPARCState *env)
__get_user(env->regwptr[WREG_FP], &(ucp->tuc_mcontext.mc_fp));
__get_user(env->regwptr[WREG_I7], &(ucp->tuc_mcontext.mc_i7));
- /* FIXME this does not match how the kernel handles the FPU in
- * its sparc64_set_context implementation. In particular the FPU
- * is only restored if fenab is non-zero in:
- * __get_user(fenab, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_enab));
- */
- __get_user(env->fprs, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fprs));
- {
- uint32_t *src = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
- for (i = 0; i < 64; i++, src++) {
- if (i & 1) {
- __get_user(env->fpr[i/2].l.lower, src);
- } else {
- __get_user(env->fpr[i/2].l.upper, src);
+ fpup = &ucp->tuc_mcontext.mc_fpregs;
+
+ __get_user(fenab, &(fpup->mcfpu_enab));
+ if (fenab) {
+ abi_ulong fprs;
+
+ /*
+ * We use the FPRS from the guest only in deciding whether
+ * to restore the upper, lower, or both banks of the FPU regs.
+ * The kernel here writes the FPU register data into the
+ * process's current_thread_info state and unconditionally
+ * clears FPRS and TSTATE_PEF: this disables the FPU so that the
+ * next FPU-disabled trap will copy the data out of
+ * current_thread_info and into the real FPU registers.
+ * QEMU doesn't need to handle lazy-FPU-state-restoring like that,
+ * so we always load the data directly into the FPU registers
+ * and leave FPRS and TSTATE_PEF alone (so the FPU stays enabled).
+ * Note that because we (and the kernel) always write zeroes for
+ * the fenab and fprs in sparc64_get_context() none of this code
+ * will execute unless the guest manually constructed or changed
+ * the context structure.
+ */
+ __get_user(fprs, &(fpup->mcfpu_fprs));
+ if (fprs & FPRS_DL) {
+ for (i = 0; i < 16; i++) {
+ __get_user(env->fpr[i].ll, &(fpup->mcfpu_fregs.dregs[i]));
+ }
+ }
+ if (fprs & FPRS_DU) {
+ for (i = 16; i < 32; i++) {
+ __get_user(env->fpr[i].ll, &(fpup->mcfpu_fregs.dregs[i]));
}
}
+ __get_user(env->fsr, &(fpup->mcfpu_fsr));
+ __get_user(env->gsr, &(fpup->mcfpu_gsr));
}
- __get_user(env->fsr,
- &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fsr));
- __get_user(env->gsr,
- &(ucp->tuc_mcontext.mc_fpregs.mcfpu_gsr));
unlock_user_struct(ucp, ucp_addr, 0);
return;
do_sigsegv:
@@ -509,7 +527,9 @@ void sparc64_get_context(CPUSPARCState *env)
if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0)) {
goto do_sigsegv;
}
-
+
+ memset(ucp, 0, sizeof(*ucp));
+
mcp = &ucp->tuc_mcontext;
grp = &mcp->mc_gregs;
@@ -535,12 +555,9 @@ void sparc64_get_context(CPUSPARCState *env)
for (i = 0; i < TARGET_NSIG_WORDS; i++, dst++, src++) {
__put_user(*src, dst);
}
- if (err)
- goto do_sigsegv;
}
- /* XXX: tstate must be saved properly */
- // __put_user(env->tstate, &((*grp)[SPARC_MC_TSTATE]));
+ __put_user(sparc64_tstate(env), &((*grp)[SPARC_MC_TSTATE]));
__put_user(env->pc, &((*grp)[SPARC_MC_PC]));
__put_user(env->npc, &((*grp)[SPARC_MC_NPC]));
__put_user(env->y, &((*grp)[SPARC_MC_Y]));
@@ -572,22 +589,12 @@ void sparc64_get_context(CPUSPARCState *env)
__put_user(env->regwptr[WREG_FP], &(mcp->mc_fp));
__put_user(env->regwptr[WREG_I7], &(mcp->mc_i7));
- {
- uint32_t *dst = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
- for (i = 0; i < 64; i++, dst++) {
- if (i & 1) {
- __put_user(env->fpr[i/2].l.lower, dst);
- } else {
- __put_user(env->fpr[i/2].l.upper, dst);
- }
- }
- }
- __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr));
- __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr));
- __put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs));
+ /*
+ * We don't write out the FPU state. This matches the kernel's
+ * implementation (which has the code for doing this but
+ * hidden behind an "if (fenab)" where fenab is always 0).
+ */
- if (err)
- goto do_sigsegv;
unlock_user_struct(ucp, ucp_addr, 1);
return;
do_sigsegv:
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 7bf99be..d182890 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -56,6 +56,7 @@
#include <linux/wireless.h>
#include <linux/icmp.h>
#include <linux/icmpv6.h>
+#include <linux/if_tun.h>
#include <linux/errqueue.h>
#include <linux/random.h>
#ifdef CONFIG_TIMERFD
@@ -813,6 +814,12 @@ safe_syscall5(int, mq_timedsend, int, mqdes, const char *, msg_ptr,
safe_syscall5(int, mq_timedreceive, int, mqdes, char *, msg_ptr,
size_t, len, unsigned *, prio, const struct timespec *, timeout)
#endif
+#if defined(TARGET_NR_copy_file_range) && defined(__NR_copy_file_range)
+safe_syscall6(ssize_t, copy_file_range, int, infd, loff_t *, pinoff,
+ int, outfd, loff_t *, poutoff, size_t, length,
+ unsigned int, flags)
+#endif
+
/* We do ioctl like this rather than via safe_syscall3 to preserve the
* "third argument might be integer or pointer or not present" behaviour of
* the libc function.
@@ -5703,6 +5710,42 @@ static abi_long do_ioctl_drm_i915(const IOCTLEntry *ie, uint8_t *buf_temp,
#endif
+static abi_long do_ioctl_TUNSETTXFILTER(const IOCTLEntry *ie, uint8_t *buf_temp,
+ int fd, int cmd, abi_long arg)
+{
+ struct tun_filter *filter = (struct tun_filter *)buf_temp;
+ struct tun_filter *target_filter;
+ char *target_addr;
+
+ assert(ie->access == IOC_W);
+
+ target_filter = lock_user(VERIFY_READ, arg, sizeof(*target_filter), 1);
+ if (!target_filter) {
+ return -TARGET_EFAULT;
+ }
+ filter->flags = tswap16(target_filter->flags);
+ filter->count = tswap16(target_filter->count);
+ unlock_user(target_filter, arg, 0);
+
+ if (filter->count) {
+ if (offsetof(struct tun_filter, addr) + filter->count * ETH_ALEN >
+ MAX_STRUCT_SIZE) {
+ return -TARGET_EFAULT;
+ }
+
+ target_addr = lock_user(VERIFY_READ,
+ arg + offsetof(struct tun_filter, addr),
+ filter->count * ETH_ALEN, 1);
+ if (!target_addr) {
+ return -TARGET_EFAULT;
+ }
+ memcpy(filter->addr, target_addr, filter->count * ETH_ALEN);
+ unlock_user(target_addr, arg + offsetof(struct tun_filter, addr), 0);
+ }
+
+ return get_errno(safe_ioctl(fd, ie->host_cmd, filter));
+}
+
IOCTLEntry ioctl_entries[] = {
#define IOCTL(cmd, access, ...) \
{ TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } },
@@ -13065,6 +13108,42 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
return get_errno(membarrier(arg1, arg2));
#endif
+#if defined(TARGET_NR_copy_file_range) && defined(__NR_copy_file_range)
+ case TARGET_NR_copy_file_range:
+ {
+ loff_t inoff, outoff;
+ loff_t *pinoff = NULL, *poutoff = NULL;
+
+ if (arg2) {
+ if (get_user_u64(inoff, arg2)) {
+ return -TARGET_EFAULT;
+ }
+ pinoff = &inoff;
+ }
+ if (arg4) {
+ if (get_user_u64(outoff, arg4)) {
+ return -TARGET_EFAULT;
+ }
+ poutoff = &outoff;
+ }
+ ret = get_errno(safe_copy_file_range(arg1, pinoff, arg3, poutoff,
+ arg5, arg6));
+ if (!is_error(ret) && ret > 0) {
+ if (arg2) {
+ if (put_user_u64(inoff, arg2)) {
+ return -TARGET_EFAULT;
+ }
+ }
+ if (arg4) {
+ if (put_user_u64(outoff, arg4)) {
+ return -TARGET_EFAULT;
+ }
+ }
+ }
+ }
+ return ret;
+#endif
+
default:
qemu_log_mask(LOG_UNIMP, "Unsupported syscall: %d\n", num);
return -TARGET_ENOSYS;
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index b934d0b..a00bfc2 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -929,6 +929,38 @@ struct target_rtc_pll_info {
#define TARGET_SIOCGIWNAME 0x8B01 /* get name == wireless protocol */
+/* From <linux/if_tun.h> */
+
+#define TARGET_TUNSETDEBUG TARGET_IOW('T', 201, int)
+#define TARGET_TUNSETIFF TARGET_IOW('T', 202, int)
+#define TARGET_TUNSETPERSIST TARGET_IOW('T', 203, int)
+#define TARGET_TUNSETOWNER TARGET_IOW('T', 204, int)
+#define TARGET_TUNSETLINK TARGET_IOW('T', 205, int)
+#define TARGET_TUNSETGROUP TARGET_IOW('T', 206, int)
+#define TARGET_TUNGETFEATURES TARGET_IOR('T', 207, unsigned int)
+#define TARGET_TUNSETOFFLOAD TARGET_IOW('T', 208, unsigned int)
+#define TARGET_TUNSETTXFILTER TARGET_IOW('T', 209, unsigned int)
+#define TARGET_TUNGETIFF TARGET_IOR('T', 210, unsigned int)
+#define TARGET_TUNGETSNDBUF TARGET_IOR('T', 211, int)
+#define TARGET_TUNSETSNDBUF TARGET_IOW('T', 212, int)
+/*
+ * TUNATTACHFILTER and TUNDETACHFILTER are not supported. Linux kernel keeps a
+ * user pointer in TUNATTACHFILTER, which we are not able to correctly handle.
+ */
+#define TARGET_TUNGETVNETHDRSZ TARGET_IOR('T', 215, int)
+#define TARGET_TUNSETVNETHDRSZ TARGET_IOW('T', 216, int)
+#define TARGET_TUNSETQUEUE TARGET_IOW('T', 217, int)
+#define TARGET_TUNSETIFINDEX TARGET_IOW('T', 218, unsigned int)
+/* TUNGETFILTER is not supported: see TUNATTACHFILTER. */
+#define TARGET_TUNSETVNETLE TARGET_IOW('T', 220, int)
+#define TARGET_TUNGETVNETLE TARGET_IOR('T', 221, int)
+#define TARGET_TUNSETVNETBE TARGET_IOW('T', 222, int)
+#define TARGET_TUNGETVNETBE TARGET_IOR('T', 223, int)
+#define TARGET_TUNSETSTEERINGEBPF TARGET_IOR('T', 224, int)
+#define TARGET_TUNSETFILTEREBPF TARGET_IOR('T', 225, int)
+#define TARGET_TUNSETCARRIER TARGET_IOW('T', 226, int)
+#define TARGET_TUNGETDEVNETNS TARGET_IO('T', 227)
+
/* From <linux/random.h> */
#define TARGET_RNDGETENTCNT TARGET_IOR('R', 0x00, int)
diff --git a/migration/migration.c b/migration/migration.c
index e0dbde4..f5d4a52 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -2102,6 +2102,12 @@ static bool migrate_prepare(MigrationState *s, bool blk, bool blk_inc,
return false;
}
+ if (runstate_check(RUN_STATE_POSTMIGRATE)) {
+ error_setg(errp, "Can't migrate the vm that was paused due to "
+ "previous migration");
+ return false;
+ }
+
if (migration_is_blocked(errp)) {
return false;
}
diff --git a/migration/savevm.c b/migration/savevm.c
index 5f937a2..4a18c9d 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -2728,7 +2728,7 @@ int qemu_load_device_state(QEMUFile *f)
int save_snapshot(const char *name, Error **errp)
{
BlockDriverState *bs, *bs1;
- QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1;
+ QEMUSnapshotInfo sn1, *sn = &sn1;
int ret = -1, ret2;
QEMUFile *f;
int saved_vm_running;
@@ -2797,13 +2797,7 @@ int save_snapshot(const char *name, Error **errp)
}
if (name) {
- ret = bdrv_snapshot_find(bs, old_sn, name);
- if (ret >= 0) {
- pstrcpy(sn->name, sizeof(sn->name), old_sn->name);
- pstrcpy(sn->id_str, sizeof(sn->id_str), old_sn->id_str);
- } else {
- pstrcpy(sn->name, sizeof(sn->name), name);
- }
+ pstrcpy(sn->name, sizeof(sn->name), name);
} else {
/* cast below needed for OpenBSD where tv_sec is still 'long' */
localtime_r((const time_t *)&tv.tv_sec, &tm);
@@ -2839,6 +2833,7 @@ int save_snapshot(const char *name, Error **errp)
if (ret < 0) {
error_setg(errp, "Error while creating snapshot on '%s'",
bdrv_get_device_or_node_name(bs));
+ bdrv_all_delete_snapshot(sn->name, &bs, NULL);
goto the_end;
}
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index 65d8ff4..79c8432 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -1549,8 +1549,7 @@ end:
hmp_handle_error(mon, err);
}
-typedef struct HMPMigrationStatus
-{
+typedef struct HMPMigrationStatus {
QEMUTimer *timer;
Monitor *mon;
bool is_block_migration;
diff --git a/monitor/misc.c b/monitor/misc.c
index fde6e36..6f5ae09 100644
--- a/monitor/misc.c
+++ b/monitor/misc.c
@@ -492,8 +492,10 @@ static void hmp_singlestep(Monitor *mon, const QDict *qdict)
static void hmp_gdbserver(Monitor *mon, const QDict *qdict)
{
const char *device = qdict_get_try_str(qdict, "device");
- if (!device)
+ if (!device) {
device = "tcp::" DEFAULT_GDBSTUB_PORT;
+ }
+
if (gdbserver_start(device) < 0) {
monitor_printf(mon, "Could not open gdbserver on device '%s'\n",
device);
@@ -559,10 +561,11 @@ static void memory_dump(Monitor *mon, int count, int format, int wsize,
}
len = wsize * count;
- if (wsize == 1)
+ if (wsize == 1) {
line_size = 8;
- else
+ } else {
line_size = 16;
+ }
max_digits = 0;
switch(format) {
@@ -583,10 +586,11 @@ static void memory_dump(Monitor *mon, int count, int format, int wsize,
}
while (len > 0) {
- if (is_physical)
+ if (is_physical) {
monitor_printf(mon, TARGET_FMT_plx ":", addr);
- else
+ } else {
monitor_printf(mon, TARGET_FMT_lx ":", (target_ulong)addr);
+ }
l = len;
if (l > line_size)
l = line_size;
@@ -915,7 +919,7 @@ static void hmp_ioport_read(Monitor *mon, const QDict *qdict)
suffix = 'l';
break;
}
- monitor_printf(mon, "port%c[0x%04x] = %#0*x\n",
+ monitor_printf(mon, "port%c[0x%04x] = 0x%0*x\n",
suffix, addr, size * 2, val);
}
diff --git a/storage-daemon/qapi/qapi-schema.json b/storage-daemon/qapi/qapi-schema.json
index c6ad5ae..28117c3 100644
--- a/storage-daemon/qapi/qapi-schema.json
+++ b/storage-daemon/qapi/qapi-schema.json
@@ -15,6 +15,9 @@
{ 'include': '../../qapi/pragma.json' }
+##
+# = Block devices
+##
{ 'include': '../../qapi/block-core.json' }
{ 'include': '../../qapi/block-export.json' }
{ 'include': '../../qapi/char.json' }
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 750f75c..11db2f3 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -1778,9 +1778,12 @@ static void gen_shiftd_rm_T1(DisasContext *s, MemOp ot, int op1,
} else {
tcg_gen_deposit_tl(s->T1, s->T0, s->T1, 16, 16);
}
- /* FALLTHRU */
-#ifdef TARGET_X86_64
+ /*
+ * If TARGET_X86_64 defined then fall through into MO_32 case,
+ * otherwise fall through default case.
+ */
case MO_32:
+#ifdef TARGET_X86_64
/* Concatenate the two 32-bit values and use a 64-bit shift. */
tcg_gen_subi_tl(s->tmp0, count, 1);
if (is_right) {
diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 3ac21d0..4cbc31c 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -844,6 +844,7 @@ struct CPUMIPSState {
#define CP0C0_MT 7 /* 9..7 */
#define CP0C0_VI 3
#define CP0C0_K0 0 /* 2..0 */
+#define CP0C0_AR_LENGTH 3
int32_t CP0_Config1;
#define CP0C1_M 31
#define CP0C1_MMU 25 /* 30..25 */
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 6a0264f..254cd83 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -108,6 +108,15 @@ const char *riscv_cpu_get_trap_name(target_ulong cause, bool async)
}
}
+bool riscv_cpu_is_32bit(CPURISCVState *env)
+{
+ if (env->misa & RV64) {
+ return false;
+ }
+
+ return true;
+}
+
static void set_misa(CPURISCVState *env, target_ulong misa)
{
env->misa_mask = env->misa = misa;
@@ -142,29 +151,50 @@ static void riscv_any_cpu_init(Object *obj)
set_priv_version(env, PRIV_VERSION_1_11_0);
}
-static void riscv_base_cpu_init(Object *obj)
+#if defined(TARGET_RISCV64)
+static void rv64_base_cpu_init(Object *obj)
{
CPURISCVState *env = &RISCV_CPU(obj)->env;
/* We set this in the realise function */
- set_misa(env, 0);
+ set_misa(env, RV64);
}
-static void rvxx_sifive_u_cpu_init(Object *obj)
+static void rv64_sifive_u_cpu_init(Object *obj)
{
CPURISCVState *env = &RISCV_CPU(obj)->env;
- set_misa(env, RVXLEN | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
+ set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
set_priv_version(env, PRIV_VERSION_1_10_0);
}
-static void rvxx_sifive_e_cpu_init(Object *obj)
+static void rv64_sifive_e_cpu_init(Object *obj)
{
CPURISCVState *env = &RISCV_CPU(obj)->env;
- set_misa(env, RVXLEN | RVI | RVM | RVA | RVC | RVU);
+ set_misa(env, RV64 | RVI | RVM | RVA | RVC | RVU);
set_priv_version(env, PRIV_VERSION_1_10_0);
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
}
+#else
+static void rv32_base_cpu_init(Object *obj)
+{
+ CPURISCVState *env = &RISCV_CPU(obj)->env;
+ /* We set this in the realise function */
+ set_misa(env, RV32);
+}
-#if defined(TARGET_RISCV32)
+static void rv32_sifive_u_cpu_init(Object *obj)
+{
+ CPURISCVState *env = &RISCV_CPU(obj)->env;
+ set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
+ set_priv_version(env, PRIV_VERSION_1_10_0);
+}
+
+static void rv32_sifive_e_cpu_init(Object *obj)
+{
+ CPURISCVState *env = &RISCV_CPU(obj)->env;
+ set_misa(env, RV32 | RVI | RVM | RVA | RVC | RVU);
+ set_priv_version(env, PRIV_VERSION_1_10_0);
+ qdev_prop_set_bit(DEVICE(obj), "mmu", false);
+}
static void rv32_ibex_cpu_init(Object *obj)
{
@@ -182,7 +212,6 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
set_resetvec(env, DEFAULT_RSTVEC);
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
}
-
#endif
static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
@@ -218,10 +247,10 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
#ifndef CONFIG_USER_ONLY
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mhartid ", env->mhartid);
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatus ", (target_ulong)env->mstatus);
-#ifdef TARGET_RISCV32
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatush ",
- (target_ulong)(env->mstatus >> 32));
-#endif
+ if (riscv_cpu_is_32bit(env)) {
+ qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatush ",
+ (target_ulong)(env->mstatus >> 32));
+ }
if (riscv_has_ext(env, RVH)) {
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "hstatus ", env->hstatus);
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "vsstatus ",
@@ -334,11 +363,12 @@ static void riscv_cpu_reset(DeviceState *dev)
static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info)
{
-#if defined(TARGET_RISCV32)
- info->print_insn = print_insn_riscv32;
-#elif defined(TARGET_RISCV64)
- info->print_insn = print_insn_riscv64;
-#endif
+ RISCVCPU *cpu = RISCV_CPU(s);
+ if (riscv_cpu_is_32bit(&cpu->env)) {
+ info->print_insn = print_insn_riscv32;
+ } else {
+ info->print_insn = print_insn_riscv64;
+ }
}
static void riscv_cpu_realize(DeviceState *dev, Error **errp)
@@ -349,7 +379,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
int priv_version = PRIV_VERSION_1_11_0;
int vext_version = VEXT_VERSION_0_07_1;
- target_ulong target_misa = 0;
+ target_ulong target_misa = env->misa;
Error *local_err = NULL;
cpu_exec_realizefn(cs, &local_err);
@@ -384,8 +414,8 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
set_resetvec(env, cpu->cfg.resetvec);
- /* If misa isn't set (rv32 and rv64 machines) set it here */
- if (!env->misa) {
+ /* If only XLEN is set for misa, then set misa from properties */
+ if (env->misa == RV32 || env->misa == RV64) {
/* Do some ISA extension error checking */
if (cpu->cfg.ext_i && cpu->cfg.ext_e) {
error_setg(errp,
@@ -481,7 +511,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
set_vext_version(env, vext_version);
}
- set_misa(env, RVXLEN | target_misa);
+ set_misa(env, target_misa);
}
riscv_cpu_register_gdb_regs_for_features(cs);
@@ -632,15 +662,15 @@ static const TypeInfo riscv_cpu_type_infos[] = {
},
DEFINE_CPU(TYPE_RISCV_CPU_ANY, riscv_any_cpu_init),
#if defined(TARGET_RISCV32)
- DEFINE_CPU(TYPE_RISCV_CPU_BASE32, riscv_base_cpu_init),
+ DEFINE_CPU(TYPE_RISCV_CPU_BASE32, rv32_base_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32_ibex_cpu_init),
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rvxx_sifive_e_cpu_init),
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rv32_sifive_e_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32_imafcu_nommu_cpu_init),
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rvxx_sifive_u_cpu_init),
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rv32_sifive_u_cpu_init),
#elif defined(TARGET_RISCV64)
- DEFINE_CPU(TYPE_RISCV_CPU_BASE64, riscv_base_cpu_init),
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rvxx_sifive_e_cpu_init),
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rvxx_sifive_u_cpu_init),
+ DEFINE_CPU(TYPE_RISCV_CPU_BASE64, rv64_base_cpu_init),
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64_sifive_e_cpu_init),
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rv64_sifive_u_cpu_init),
#endif
};
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index c0a326c..6339e84 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -44,6 +44,12 @@
#define TYPE_RISCV_CPU_SIFIVE_U34 RISCV_CPU_TYPE_NAME("sifive-u34")
#define TYPE_RISCV_CPU_SIFIVE_U54 RISCV_CPU_TYPE_NAME("sifive-u54")
+#if defined(TARGET_RISCV32)
+# define TYPE_RISCV_CPU_BASE TYPE_RISCV_CPU_BASE32
+#elif defined(TARGET_RISCV64)
+# define TYPE_RISCV_CPU_BASE TYPE_RISCV_CPU_BASE64
+#endif
+
#define RV32 ((target_ulong)1 << (TARGET_LONG_BITS - 2))
#define RV64 ((target_ulong)2 << (TARGET_LONG_BITS - 2))
@@ -378,6 +384,8 @@ FIELD(TB_FLAGS, VILL, 8, 1)
/* Is a Hypervisor instruction load/store allowed? */
FIELD(TB_FLAGS, HLSX, 9, 1)
+bool riscv_cpu_is_32bit(CPURISCVState *env);
+
/*
* A simplification for VLMAX
* = (1 << LMUL) * VLEN / (8 * (1 << SEW))
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 24b24c6..b41e883 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -379,8 +379,8 @@
#define MSTATUS_MXR 0x00080000
#define MSTATUS_VM 0x1F000000 /* until: priv-1.9.1 */
#define MSTATUS_TVM 0x00100000 /* since: priv-1.10 */
-#define MSTATUS_TW 0x20000000 /* since: priv-1.10 */
-#define MSTATUS_TSR 0x40000000 /* since: priv-1.10 */
+#define MSTATUS_TW 0x00200000 /* since: priv-1.10 */
+#define MSTATUS_TSR 0x00400000 /* since: priv-1.10 */
#define MSTATUS_GVA 0x4000000000ULL
#define MSTATUS_MPV 0x8000000000ULL
@@ -437,9 +437,7 @@
#define HSTATUS_VGEIN 0x0003F000
#define HSTATUS_VTVM 0x00100000
#define HSTATUS_VTSR 0x00400000
-#if defined(TARGET_RISCV64)
-#define HSTATUS_VSXL 0x300000000
-#endif
+#define HSTATUS_VSXL 0x300000000
#define HSTATUS32_WPRI 0xFF8FF87E
#define HSTATUS64_WPRI 0xFFFFFFFFFF8FF87EULL
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index a2787b1..a2afb95 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -367,7 +367,8 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
vm = get_field(env->hgatp, HGATP_MODE);
widened = 2;
}
- sum = get_field(env->mstatus, MSTATUS_SUM);
+ /* status.SUM will be ignored if execute on background */
+ sum = get_field(env->mstatus, MSTATUS_SUM) || use_background;
switch (vm) {
case VM_1_10_SV32:
levels = 2; ptidxbits = 10; ptesize = 4; break;
@@ -446,11 +447,13 @@ restart:
return TRANSLATE_PMP_FAIL;
}
-#if defined(TARGET_RISCV32)
- target_ulong pte = address_space_ldl(cs->as, pte_addr, attrs, &res);
-#elif defined(TARGET_RISCV64)
- target_ulong pte = address_space_ldq(cs->as, pte_addr, attrs, &res);
-#endif
+ target_ulong pte;
+ if (riscv_cpu_is_32bit(env)) {
+ pte = address_space_ldl(cs->as, pte_addr, attrs, &res);
+ } else {
+ pte = address_space_ldq(cs->as, pte_addr, attrs, &res);
+ }
+
if (res != MEMTX_OK) {
return TRANSLATE_FAIL;
}
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 93263f8..10ab82e 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -102,44 +102,65 @@ static int ctr(CPURISCVState *env, int csrno)
return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
}
break;
-#if defined(TARGET_RISCV32)
- case CSR_CYCLEH:
- if (!get_field(env->hcounteren, HCOUNTEREN_CY) &&
- get_field(env->mcounteren, HCOUNTEREN_CY)) {
- return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
- }
- break;
- case CSR_TIMEH:
- if (!get_field(env->hcounteren, HCOUNTEREN_TM) &&
- get_field(env->mcounteren, HCOUNTEREN_TM)) {
- return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
- }
- break;
- case CSR_INSTRETH:
- if (!get_field(env->hcounteren, HCOUNTEREN_IR) &&
- get_field(env->mcounteren, HCOUNTEREN_IR)) {
- return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
- }
- break;
- case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
- if (!get_field(env->hcounteren, 1 << (csrno - CSR_HPMCOUNTER3H)) &&
- get_field(env->mcounteren, 1 << (csrno - CSR_HPMCOUNTER3H))) {
- return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+ }
+ if (riscv_cpu_is_32bit(env)) {
+ switch (csrno) {
+ case CSR_CYCLEH:
+ if (!get_field(env->hcounteren, HCOUNTEREN_CY) &&
+ get_field(env->mcounteren, HCOUNTEREN_CY)) {
+ return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+ }
+ break;
+ case CSR_TIMEH:
+ if (!get_field(env->hcounteren, HCOUNTEREN_TM) &&
+ get_field(env->mcounteren, HCOUNTEREN_TM)) {
+ return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+ }
+ break;
+ case CSR_INSTRETH:
+ if (!get_field(env->hcounteren, HCOUNTEREN_IR) &&
+ get_field(env->mcounteren, HCOUNTEREN_IR)) {
+ return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+ }
+ break;
+ case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
+ if (!get_field(env->hcounteren, 1 << (csrno - CSR_HPMCOUNTER3H)) &&
+ get_field(env->mcounteren, 1 << (csrno - CSR_HPMCOUNTER3H))) {
+ return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+ }
+ break;
}
- break;
-#endif
}
}
#endif
return 0;
}
+static int ctr32(CPURISCVState *env, int csrno)
+{
+ if (!riscv_cpu_is_32bit(env)) {
+ return -RISCV_EXCP_ILLEGAL_INST;
+ }
+
+ return ctr(env, csrno);
+}
+
#if !defined(CONFIG_USER_ONLY)
static int any(CPURISCVState *env, int csrno)
{
return 0;
}
+static int any32(CPURISCVState *env, int csrno)
+{
+ if (!riscv_cpu_is_32bit(env)) {
+ return -RISCV_EXCP_ILLEGAL_INST;
+ }
+
+ return any(env, csrno);
+
+}
+
static int smode(CPURISCVState *env, int csrno)
{
return -!riscv_has_ext(env, RVS);
@@ -161,6 +182,16 @@ static int hmode(CPURISCVState *env, int csrno)
return -RISCV_EXCP_ILLEGAL_INST;
}
+static int hmode32(CPURISCVState *env, int csrno)
+{
+ if (!riscv_cpu_is_32bit(env)) {
+ return 0;
+ }
+
+ return hmode(env, csrno);
+
+}
+
static int pmp(CPURISCVState *env, int csrno)
{
return -!riscv_feature(env, RISCV_FEATURE_PMP);
@@ -310,7 +341,6 @@ static int read_instret(CPURISCVState *env, int csrno, target_ulong *val)
return 0;
}
-#if defined(TARGET_RISCV32)
static int read_instreth(CPURISCVState *env, int csrno, target_ulong *val)
{
#if !defined(CONFIG_USER_ONLY)
@@ -324,7 +354,6 @@ static int read_instreth(CPURISCVState *env, int csrno, target_ulong *val)
#endif
return 0;
}
-#endif /* TARGET_RISCV32 */
#if defined(CONFIG_USER_ONLY)
static int read_time(CPURISCVState *env, int csrno, target_ulong *val)
@@ -333,13 +362,11 @@ static int read_time(CPURISCVState *env, int csrno, target_ulong *val)
return 0;
}
-#if defined(TARGET_RISCV32)
static int read_timeh(CPURISCVState *env, int csrno, target_ulong *val)
{
*val = cpu_get_host_ticks() >> 32;
return 0;
}
-#endif
#else /* CONFIG_USER_ONLY */
@@ -355,7 +382,6 @@ static int read_time(CPURISCVState *env, int csrno, target_ulong *val)
return 0;
}
-#if defined(TARGET_RISCV32)
static int read_timeh(CPURISCVState *env, int csrno, target_ulong *val)
{
uint64_t delta = riscv_cpu_virt_enabled(env) ? env->htimedelta : 0;
@@ -367,7 +393,6 @@ static int read_timeh(CPURISCVState *env, int csrno, target_ulong *val)
*val = (env->rdtime_fn(env->rdtime_fn_arg) + delta) >> 32;
return 0;
}
-#endif
/* Machine constants */
@@ -406,19 +431,17 @@ static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP;
static const target_ulong hip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP;
static const target_ulong vsip_writable_mask = MIP_VSSIP;
-#if defined(TARGET_RISCV32)
-static const char valid_vm_1_10[16] = {
+static const char valid_vm_1_10_32[16] = {
[VM_1_10_MBARE] = 1,
[VM_1_10_SV32] = 1
};
-#elif defined(TARGET_RISCV64)
-static const char valid_vm_1_10[16] = {
+
+static const char valid_vm_1_10_64[16] = {
[VM_1_10_MBARE] = 1,
[VM_1_10_SV39] = 1,
[VM_1_10_SV48] = 1,
[VM_1_10_SV57] = 1
};
-#endif /* CONFIG_USER_ONLY */
/* Machine Information Registers */
static int read_zero(CPURISCVState *env, int csrno, target_ulong *val)
@@ -441,7 +464,11 @@ static int read_mstatus(CPURISCVState *env, int csrno, target_ulong *val)
static int validate_vm(CPURISCVState *env, target_ulong vm)
{
- return valid_vm_1_10[vm & 0xf];
+ if (riscv_cpu_is_32bit(env)) {
+ return valid_vm_1_10_32[vm & 0xf];
+ } else {
+ return valid_vm_1_10_64[vm & 0xf];
+ }
}
static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val)
@@ -459,13 +486,14 @@ static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val)
MSTATUS_SPP | MSTATUS_FS | MSTATUS_MPRV | MSTATUS_SUM |
MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
MSTATUS_TW;
-#if defined(TARGET_RISCV64)
- /*
- * RV32: MPV and GVA are not in mstatus. The current plan is to
- * add them to mstatush. For now, we just don't support it.
- */
- mask |= MSTATUS_MPV | MSTATUS_GVA;
-#endif
+
+ if (!riscv_cpu_is_32bit(env)) {
+ /*
+ * RV32: MPV and GVA are not in mstatus. The current plan is to
+ * add them to mstatush. For now, we just don't support it.
+ */
+ mask |= MSTATUS_MPV | MSTATUS_GVA;
+ }
mstatus = (mstatus & ~mask) | (val & mask);
@@ -477,7 +505,6 @@ static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val)
return 0;
}
-#ifdef TARGET_RISCV32
static int read_mstatush(CPURISCVState *env, int csrno, target_ulong *val)
{
*val = env->mstatus >> 32;
@@ -497,7 +524,6 @@ static int write_mstatush(CPURISCVState *env, int csrno, target_ulong val)
return 0;
}
-#endif
static int read_misa(CPURISCVState *env, int csrno, target_ulong *val)
{
@@ -895,10 +921,10 @@ static int write_satp(CPURISCVState *env, int csrno, target_ulong val)
static int read_hstatus(CPURISCVState *env, int csrno, target_ulong *val)
{
*val = env->hstatus;
-#ifdef TARGET_RISCV64
- /* We only support 64-bit VSXL */
- *val = set_field(*val, HSTATUS_VSXL, 2);
-#endif
+ if (!riscv_cpu_is_32bit(env)) {
+ /* We only support 64-bit VSXL */
+ *val = set_field(*val, HSTATUS_VSXL, 2);
+ }
/* We only support little endian */
*val = set_field(*val, HSTATUS_VSBE, 0);
return 0;
@@ -907,11 +933,9 @@ static int read_hstatus(CPURISCVState *env, int csrno, target_ulong *val)
static int write_hstatus(CPURISCVState *env, int csrno, target_ulong val)
{
env->hstatus = val;
-#ifdef TARGET_RISCV64
- if (get_field(val, HSTATUS_VSXL) != 2) {
+ if (!riscv_cpu_is_32bit(env) && get_field(val, HSTATUS_VSXL) != 2) {
qemu_log_mask(LOG_UNIMP, "QEMU does not support mixed HSXLEN options.");
}
-#endif
if (get_field(val, HSTATUS_VSBE) != 0) {
qemu_log_mask(LOG_UNIMP, "QEMU does not support big endian guests.");
}
@@ -1053,11 +1077,7 @@ static int read_htimedelta(CPURISCVState *env, int csrno, target_ulong *val)
return -RISCV_EXCP_ILLEGAL_INST;
}
-#if defined(TARGET_RISCV32)
- *val = env->htimedelta & 0xffffffff;
-#else
*val = env->htimedelta;
-#endif
return 0;
}
@@ -1067,15 +1087,14 @@ static int write_htimedelta(CPURISCVState *env, int csrno, target_ulong val)
return -RISCV_EXCP_ILLEGAL_INST;
}
-#if defined(TARGET_RISCV32)
- env->htimedelta = deposit64(env->htimedelta, 0, 32, (uint64_t)val);
-#else
- env->htimedelta = val;
-#endif
+ if (riscv_cpu_is_32bit(env)) {
+ env->htimedelta = deposit64(env->htimedelta, 0, 32, (uint64_t)val);
+ } else {
+ env->htimedelta = val;
+ }
return 0;
}
-#if defined(TARGET_RISCV32)
static int read_htimedeltah(CPURISCVState *env, int csrno, target_ulong *val)
{
if (!env->rdtime_fn) {
@@ -1095,7 +1114,6 @@ static int write_htimedeltah(CPURISCVState *env, int csrno, target_ulong val)
env->htimedelta = deposit64(env->htimedelta, 32, 32, (uint64_t)val);
return 0;
}
-#endif
/* Virtual CSR Registers */
static int read_vsstatus(CPURISCVState *env, int csrno, target_ulong *val)
@@ -1374,26 +1392,20 @@ static riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
/* User Timers and Counters */
[CSR_CYCLE] = { ctr, read_instret },
[CSR_INSTRET] = { ctr, read_instret },
-#if defined(TARGET_RISCV32)
- [CSR_CYCLEH] = { ctr, read_instreth },
- [CSR_INSTRETH] = { ctr, read_instreth },
-#endif
+ [CSR_CYCLEH] = { ctr32, read_instreth },
+ [CSR_INSTRETH] = { ctr32, read_instreth },
/* In privileged mode, the monitor will have to emulate TIME CSRs only if
* rdtime callback is not provided by machine/platform emulation */
[CSR_TIME] = { ctr, read_time },
-#if defined(TARGET_RISCV32)
- [CSR_TIMEH] = { ctr, read_timeh },
-#endif
+ [CSR_TIMEH] = { ctr32, read_timeh },
#if !defined(CONFIG_USER_ONLY)
/* Machine Timers and Counters */
[CSR_MCYCLE] = { any, read_instret },
[CSR_MINSTRET] = { any, read_instret },
-#if defined(TARGET_RISCV32)
- [CSR_MCYCLEH] = { any, read_instreth },
- [CSR_MINSTRETH] = { any, read_instreth },
-#endif
+ [CSR_MCYCLEH] = { any32, read_instreth },
+ [CSR_MINSTRETH] = { any32, read_instreth },
/* Machine Information Registers */
[CSR_MVENDORID] = { any, read_zero },
@@ -1410,9 +1422,7 @@ static riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
[CSR_MTVEC] = { any, read_mtvec, write_mtvec },
[CSR_MCOUNTEREN] = { any, read_mcounteren, write_mcounteren },
-#if defined(TARGET_RISCV32)
- [CSR_MSTATUSH] = { any, read_mstatush, write_mstatush },
-#endif
+ [CSR_MSTATUSH] = { any32, read_mstatush, write_mstatush },
[CSR_MSCOUNTEREN] = { any, read_mscounteren, write_mscounteren },
@@ -1452,9 +1462,7 @@ static riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
[CSR_HGEIP] = { hmode, read_hgeip, write_hgeip },
[CSR_HGATP] = { hmode, read_hgatp, write_hgatp },
[CSR_HTIMEDELTA] = { hmode, read_htimedelta, write_htimedelta },
-#if defined(TARGET_RISCV32)
- [CSR_HTIMEDELTAH] = { hmode, read_htimedeltah, write_htimedeltah},
-#endif
+ [CSR_HTIMEDELTAH] = { hmode32, read_htimedeltah, write_htimedeltah},
[CSR_VSSTATUS] = { hmode, read_vsstatus, write_vsstatus },
[CSR_VSIP] = { hmode, NULL, NULL, rmw_vsip },
@@ -1477,9 +1485,7 @@ static riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
[CSR_HPMCOUNTER3 ... CSR_HPMCOUNTER31] = { ctr, read_zero },
[CSR_MHPMCOUNTER3 ... CSR_MHPMCOUNTER31] = { any, read_zero },
[CSR_MHPMEVENT3 ... CSR_MHPMEVENT31] = { any, read_zero },
-#if defined(TARGET_RISCV32)
- [CSR_HPMCOUNTER3H ... CSR_HPMCOUNTER31H] = { ctr, read_zero },
- [CSR_MHPMCOUNTER3H ... CSR_MHPMCOUNTER31H] = { any, read_zero },
-#endif
+ [CSR_HPMCOUNTER3H ... CSR_HPMCOUNTER31H] = { ctr32, read_zero },
+ [CSR_MHPMCOUNTER3H ... CSR_MHPMCOUNTER31H] = { any32, read_zero },
#endif /* !CONFIG_USER_ONLY */
};
diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
index bb346a8..7c4ab92 100644
--- a/target/riscv/fpu_helper.c
+++ b/target/riscv/fpu_helper.c
@@ -223,7 +223,6 @@ target_ulong helper_fcvt_wu_s(CPURISCVState *env, uint64_t rs1)
return (int32_t)float32_to_uint32(frs1, &env->fp_status);
}
-#if defined(TARGET_RISCV64)
uint64_t helper_fcvt_l_s(CPURISCVState *env, uint64_t rs1)
{
float32 frs1 = check_nanbox_s(rs1);
@@ -235,7 +234,6 @@ uint64_t helper_fcvt_lu_s(CPURISCVState *env, uint64_t rs1)
float32 frs1 = check_nanbox_s(rs1);
return float32_to_uint64(frs1, &env->fp_status);
}
-#endif
uint64_t helper_fcvt_s_w(CPURISCVState *env, target_ulong rs1)
{
@@ -247,7 +245,6 @@ uint64_t helper_fcvt_s_wu(CPURISCVState *env, target_ulong rs1)
return nanbox_s(uint32_to_float32((uint32_t)rs1, &env->fp_status));
}
-#if defined(TARGET_RISCV64)
uint64_t helper_fcvt_s_l(CPURISCVState *env, uint64_t rs1)
{
return nanbox_s(int64_to_float32(rs1, &env->fp_status));
@@ -257,7 +254,6 @@ uint64_t helper_fcvt_s_lu(CPURISCVState *env, uint64_t rs1)
{
return nanbox_s(uint64_to_float32(rs1, &env->fp_status));
}
-#endif
target_ulong helper_fclass_s(uint64_t rs1)
{
@@ -336,7 +332,6 @@ target_ulong helper_fcvt_wu_d(CPURISCVState *env, uint64_t frs1)
return (int32_t)float64_to_uint32(frs1, &env->fp_status);
}
-#if defined(TARGET_RISCV64)
uint64_t helper_fcvt_l_d(CPURISCVState *env, uint64_t frs1)
{
return float64_to_int64(frs1, &env->fp_status);
@@ -346,7 +341,6 @@ uint64_t helper_fcvt_lu_d(CPURISCVState *env, uint64_t frs1)
{
return float64_to_uint64(frs1, &env->fp_status);
}
-#endif
uint64_t helper_fcvt_d_w(CPURISCVState *env, target_ulong rs1)
{
@@ -358,7 +352,6 @@ uint64_t helper_fcvt_d_wu(CPURISCVState *env, target_ulong rs1)
return uint32_to_float64((uint32_t)rs1, &env->fp_status);
}
-#if defined(TARGET_RISCV64)
uint64_t helper_fcvt_d_l(CPURISCVState *env, uint64_t rs1)
{
return int64_to_float64(rs1, &env->fp_status);
@@ -368,7 +361,6 @@ uint64_t helper_fcvt_d_lu(CPURISCVState *env, uint64_t rs1)
{
return uint64_to_float64(rs1, &env->fp_status);
}
-#endif
target_ulong helper_fclass_d(uint64_t frs1)
{
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 939731c..e3f3f41 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -27,16 +27,12 @@ DEF_HELPER_FLAGS_3(flt_s, TCG_CALL_NO_RWG, tl, env, i64, i64)
DEF_HELPER_FLAGS_3(feq_s, TCG_CALL_NO_RWG, tl, env, i64, i64)
DEF_HELPER_FLAGS_2(fcvt_w_s, TCG_CALL_NO_RWG, tl, env, i64)
DEF_HELPER_FLAGS_2(fcvt_wu_s, TCG_CALL_NO_RWG, tl, env, i64)
-#if defined(TARGET_RISCV64)
-DEF_HELPER_FLAGS_2(fcvt_l_s, TCG_CALL_NO_RWG, tl, env, i64)
-DEF_HELPER_FLAGS_2(fcvt_lu_s, TCG_CALL_NO_RWG, tl, env, i64)
-#endif
+DEF_HELPER_FLAGS_2(fcvt_l_s, TCG_CALL_NO_RWG, i64, env, i64)
+DEF_HELPER_FLAGS_2(fcvt_lu_s, TCG_CALL_NO_RWG, i64, env, i64)
DEF_HELPER_FLAGS_2(fcvt_s_w, TCG_CALL_NO_RWG, i64, env, tl)
DEF_HELPER_FLAGS_2(fcvt_s_wu, TCG_CALL_NO_RWG, i64, env, tl)
-#if defined(TARGET_RISCV64)
-DEF_HELPER_FLAGS_2(fcvt_s_l, TCG_CALL_NO_RWG, i64, env, tl)
-DEF_HELPER_FLAGS_2(fcvt_s_lu, TCG_CALL_NO_RWG, i64, env, tl)
-#endif
+DEF_HELPER_FLAGS_2(fcvt_s_l, TCG_CALL_NO_RWG, i64, env, i64)
+DEF_HELPER_FLAGS_2(fcvt_s_lu, TCG_CALL_NO_RWG, i64, env, i64)
DEF_HELPER_FLAGS_1(fclass_s, TCG_CALL_NO_RWG_SE, tl, i64)
/* Floating Point - Double Precision */
@@ -54,16 +50,12 @@ DEF_HELPER_FLAGS_3(flt_d, TCG_CALL_NO_RWG, tl, env, i64, i64)
DEF_HELPER_FLAGS_3(feq_d, TCG_CALL_NO_RWG, tl, env, i64, i64)
DEF_HELPER_FLAGS_2(fcvt_w_d, TCG_CALL_NO_RWG, tl, env, i64)
DEF_HELPER_FLAGS_2(fcvt_wu_d, TCG_CALL_NO_RWG, tl, env, i64)
-#if defined(TARGET_RISCV64)
-DEF_HELPER_FLAGS_2(fcvt_l_d, TCG_CALL_NO_RWG, tl, env, i64)
-DEF_HELPER_FLAGS_2(fcvt_lu_d, TCG_CALL_NO_RWG, tl, env, i64)
-#endif
+DEF_HELPER_FLAGS_2(fcvt_l_d, TCG_CALL_NO_RWG, i64, env, i64)
+DEF_HELPER_FLAGS_2(fcvt_lu_d, TCG_CALL_NO_RWG, i64, env, i64)
DEF_HELPER_FLAGS_2(fcvt_d_w, TCG_CALL_NO_RWG, i64, env, tl)
DEF_HELPER_FLAGS_2(fcvt_d_wu, TCG_CALL_NO_RWG, i64, env, tl)
-#if defined(TARGET_RISCV64)
-DEF_HELPER_FLAGS_2(fcvt_d_l, TCG_CALL_NO_RWG, i64, env, tl)
-DEF_HELPER_FLAGS_2(fcvt_d_lu, TCG_CALL_NO_RWG, i64, env, tl)
-#endif
+DEF_HELPER_FLAGS_2(fcvt_d_l, TCG_CALL_NO_RWG, i64, env, i64)
+DEF_HELPER_FLAGS_2(fcvt_d_lu, TCG_CALL_NO_RWG, i64, env, i64)
DEF_HELPER_FLAGS_1(fclass_d, TCG_CALL_NO_RWG_SE, tl, i64)
/* Special functions */
diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index b936939..4b22906 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -156,7 +156,9 @@ enum {
#define PS_IE (1<<1)
#define PS_AG (1<<0) /* v9, zero on UA2007 */
-#define FPRS_FEF (1<<2)
+#define FPRS_DL (1 << 0)
+#define FPRS_DU (1 << 1)
+#define FPRS_FEF (1 << 2)
#define HS_PRIV (1<<2)
#endif
@@ -606,10 +608,6 @@ target_ulong cpu_get_psr(CPUSPARCState *env1);
void cpu_put_psr(CPUSPARCState *env1, target_ulong val);
void cpu_put_psr_raw(CPUSPARCState *env1, target_ulong val);
#ifdef TARGET_SPARC64
-target_ulong cpu_get_ccr(CPUSPARCState *env1);
-void cpu_put_ccr(CPUSPARCState *env1, target_ulong val);
-target_ulong cpu_get_cwp64(CPUSPARCState *env1);
-void cpu_put_cwp64(CPUSPARCState *env1, int cwp);
void cpu_change_pstate(CPUSPARCState *env1, uint32_t new_pstate);
void cpu_gl_switch_gregs(CPUSPARCState *env, uint32_t new_gl);
#endif
@@ -827,4 +825,24 @@ static inline bool tb_am_enabled(int tb_flags)
#endif
}
+#ifdef TARGET_SPARC64
+/* win_helper.c */
+target_ulong cpu_get_ccr(CPUSPARCState *env1);
+void cpu_put_ccr(CPUSPARCState *env1, target_ulong val);
+target_ulong cpu_get_cwp64(CPUSPARCState *env1);
+void cpu_put_cwp64(CPUSPARCState *env1, int cwp);
+
+static inline uint64_t sparc64_tstate(CPUSPARCState *env)
+{
+ uint64_t tstate = (cpu_get_ccr(env) << 32) |
+ ((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) |
+ cpu_get_cwp64(env);
+
+ if (env->def.features & CPU_FEATURE_GL) {
+ tstate |= (env->gl & 7ULL) << 40;
+ }
+ return tstate;
+}
+#endif
+
#endif
diff --git a/target/sparc/int64_helper.c b/target/sparc/int64_helper.c
index ba95bf2..7fb8ab2 100644
--- a/target/sparc/int64_helper.c
+++ b/target/sparc/int64_helper.c
@@ -131,9 +131,7 @@ void sparc_cpu_do_interrupt(CPUState *cs)
}
tsptr = cpu_tsptr(env);
- tsptr->tstate = (cpu_get_ccr(env) << 32) |
- ((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) |
- cpu_get_cwp64(env);
+ tsptr->tstate = sparc64_tstate(env);
tsptr->tpc = env->pc;
tsptr->tnpc = env->npc;
tsptr->tt = intno;
@@ -148,7 +146,6 @@ void sparc_cpu_do_interrupt(CPUState *cs)
}
if (env->def.features & CPU_FEATURE_GL) {
- tsptr->tstate |= (env->gl & 7ULL) << 40;
cpu_gl_switch_gregs(env, env->gl + 1);
env->gl++;
}
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 30c73f8..4bfa317 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -2324,8 +2324,8 @@ static void gen_st_asi(DisasContext *dc, TCGv src, TCGv addr,
}
/* in OpenSPARC T1+ CPUs TWINX ASIs in store instructions
* are ST_BLKINIT_ ASIs */
- /* fall through */
#endif
+ /* fall through */
case GET_ASI_DIRECT:
gen_address_mask(dc, addr);
tcg_gen_qemu_st_tl(src, addr, da.mem_idx, da.memop);
diff --git a/target/sparc/win_helper.c b/target/sparc/win_helper.c
index 5b57892..3a7c0ff 100644
--- a/target/sparc/win_helper.c
+++ b/target/sparc/win_helper.c
@@ -302,7 +302,7 @@ static inline uint64_t *get_gregset(CPUSPARCState *env, uint32_t pstate)
switch (pstate) {
default:
trace_win_helper_gregset_error(pstate);
- /* pass through to normal set of global registers */
+ /* fall through to normal set of global registers */
case 0:
return env->bgregs;
case PS_AG:
diff --git a/target/unicore32/translate.c b/target/unicore32/translate.c
index d4b06df..962f987 100644
--- a/target/unicore32/translate.c
+++ b/target/unicore32/translate.c
@@ -1801,6 +1801,7 @@ static void disas_uc32_insn(CPUUniCore32State *env, DisasContext *s)
do_misc(env, s, insn);
break;
}
+ /* fallthrough */
case 0x1:
if (((UCOP_OPCODES >> 2) == 2) && !UCOP_SET_S) {
do_misc(env, s, insn);
@@ -1817,6 +1818,7 @@ static void disas_uc32_insn(CPUUniCore32State *env, DisasContext *s)
if (UCOP_SET(8) || UCOP_SET(5)) {
ILLEGAL;
}
+ /* fallthrough */
case 0x3:
do_ldst_ir(env, s, insn);
break;
diff --git a/tcg/optimize.c b/tcg/optimize.c
index 220f460..7ca71de 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -855,6 +855,7 @@ void tcg_optimize(TCGContext *s)
if ((arg_info(op->args[1])->mask & 0x80) != 0) {
break;
}
+ QEMU_FALLTHROUGH;
CASE_OP_32_64(ext8u):
mask = 0xff;
goto and_const;
@@ -862,6 +863,7 @@ void tcg_optimize(TCGContext *s)
if ((arg_info(op->args[1])->mask & 0x8000) != 0) {
break;
}
+ QEMU_FALLTHROUGH;
CASE_OP_32_64(ext16u):
mask = 0xffff;
goto and_const;
@@ -869,6 +871,7 @@ void tcg_optimize(TCGContext *s)
if ((arg_info(op->args[1])->mask & 0x80000000) != 0) {
break;
}
+ QEMU_FALLTHROUGH;
case INDEX_op_ext32u_i64:
mask = 0xffffffffU;
goto and_const;
@@ -886,6 +889,7 @@ void tcg_optimize(TCGContext *s)
if ((arg_info(op->args[1])->mask & 0x80000000) != 0) {
break;
}
+ QEMU_FALLTHROUGH;
case INDEX_op_extu_i32_i64:
/* We do not compute affected as it is a size changing op. */
mask = (uint32_t)arg_info(op->args[1])->mask;
diff --git a/tests/fp/meson.build b/tests/fp/meson.build
index 3d4fb00..8d739c4 100644
--- a/tests/fp/meson.build
+++ b/tests/fp/meson.build
@@ -27,6 +27,7 @@ tfdir = 'berkeley-testfloat-3/source'
sfinc = include_directories(sfdir / 'include', sfspedir)
tfcflags = [
+ '-Wno-implicit-fallthrough',
'-Wno-strict-prototypes',
'-Wno-unknown-pragmas',
'-Wno-uninitialized',
@@ -209,6 +210,7 @@ libtestfloat = static_library(
)
sfcflags = [
+ '-Wno-implicit-fallthrough',
'-Wno-missing-prototypes',
'-Wno-redundant-decls',
'-Wno-return-type',
diff --git a/tests/qemu-iotests/172 b/tests/qemu-iotests/172
index 3abfa72..b45782e 100755
--- a/tests/qemu-iotests/172
+++ b/tests/qemu-iotests/172
@@ -73,7 +73,7 @@ check_floppy_qtree()
(QEMU_OPTIONS="" do_run_qemu "$@" |
_filter_testdir |_filter_generated_node_ids | _filter_hmp |
sed -ne '/^ dev: isa-fdc/,/^ dev:/{x;p};/^[a-z][^ ]* (NODE_NAME):* /,/^(qemu)$/{p}') 2>&1 |
- _filter_win32 | _filter_qemu
+ _filter_win32 | _filter_qemu | _filter_qom_path
}
check_cache_mode()
diff --git a/tests/qemu-iotests/172.out b/tests/qemu-iotests/172.out
index cca2894..2cd4a8f 100644
--- a/tests/qemu-iotests/172.out
+++ b/tests/qemu-iotests/172.out
@@ -63,12 +63,12 @@ Testing: -fda TEST_DIR/t.qcow2
share-rw = false
drive-type = "144"
floppy0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
- Attached to: /machine/unattached/device[15]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
ide1-cd0: [not inserted]
- Attached to: /machine/unattached/device[22]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
sd0: [not inserted]
@@ -114,16 +114,16 @@ Testing: -fdb TEST_DIR/t.qcow2
share-rw = false
drive-type = "288"
floppy1 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
- Attached to: /machine/unattached/device[16]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
ide1-cd0: [not inserted]
- Attached to: /machine/unattached/device[23]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
floppy0: [not inserted]
- Attached to: /machine/unattached/device[15]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
sd0: [not inserted]
@@ -169,17 +169,17 @@ Testing: -fda TEST_DIR/t.qcow2 -fdb TEST_DIR/t.qcow2.2
share-rw = false
drive-type = "144"
floppy0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
- Attached to: /machine/unattached/device[15]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
floppy1 (NODE_NAME): TEST_DIR/t.qcow2.2 (qcow2)
- Attached to: /machine/unattached/device[16]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
ide1-cd0: [not inserted]
- Attached to: /machine/unattached/device[23]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
sd0: [not inserted]
@@ -255,12 +255,12 @@ Testing: -drive if=floppy,file=TEST_DIR/t.qcow2
share-rw = false
drive-type = "144"
floppy0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
- Attached to: /machine/unattached/device[15]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
ide1-cd0: [not inserted]
- Attached to: /machine/unattached/device[22]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
sd0: [not inserted]
@@ -306,16 +306,16 @@ Testing: -drive if=floppy,file=TEST_DIR/t.qcow2,index=1
share-rw = false
drive-type = "288"
floppy1 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
- Attached to: /machine/unattached/device[16]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
ide1-cd0: [not inserted]
- Attached to: /machine/unattached/device[23]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
floppy0: [not inserted]
- Attached to: /machine/unattached/device[15]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
sd0: [not inserted]
@@ -361,17 +361,17 @@ Testing: -drive if=floppy,file=TEST_DIR/t.qcow2 -drive if=floppy,file=TEST_DIR/t
share-rw = false
drive-type = "144"
floppy0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
- Attached to: /machine/unattached/device[15]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
floppy1 (NODE_NAME): TEST_DIR/t.qcow2.2 (qcow2)
- Attached to: /machine/unattached/device[16]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
ide1-cd0: [not inserted]
- Attached to: /machine/unattached/device[23]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
sd0: [not inserted]
@@ -411,12 +411,12 @@ Use -device floppy,unit=0,drive=... instead.
share-rw = false
drive-type = "144"
none0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
- Attached to: /machine/unattached/device[15]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
ide1-cd0: [not inserted]
- Attached to: /machine/unattached/device[22]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
sd0: [not inserted]
@@ -453,12 +453,12 @@ Use -device floppy,unit=1,drive=... instead.
share-rw = false
drive-type = "144"
none0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
- Attached to: /machine/unattached/device[15]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
ide1-cd0: [not inserted]
- Attached to: /machine/unattached/device[22]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
sd0: [not inserted]
@@ -508,17 +508,17 @@ Use -device floppy,unit=1,drive=... instead.
share-rw = false
drive-type = "144"
none0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
- Attached to: /machine/unattached/device[15]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
none1 (NODE_NAME): TEST_DIR/t.qcow2.2 (qcow2)
- Attached to: /machine/unattached/device[16]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
ide1-cd0: [not inserted]
- Attached to: /machine/unattached/device[23]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
sd0: [not inserted]
@@ -556,12 +556,12 @@ Testing: -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0
share-rw = false
drive-type = "144"
none0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
- Attached to: /machine/peripheral-anon/device[0]
+ Attached to: /machine/peripheral-anon/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
ide1-cd0: [not inserted]
- Attached to: /machine/unattached/device[21]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
sd0: [not inserted]
@@ -596,12 +596,12 @@ Testing: -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0,unit=1
share-rw = false
drive-type = "144"
none0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
- Attached to: /machine/peripheral-anon/device[0]
+ Attached to: /machine/peripheral-anon/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
ide1-cd0: [not inserted]
- Attached to: /machine/unattached/device[21]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
sd0: [not inserted]
@@ -647,17 +647,17 @@ Testing: -drive if=none,file=TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qco
share-rw = false
drive-type = "144"
none0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
- Attached to: /machine/peripheral-anon/device[0]
+ Attached to: /machine/peripheral-anon/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
none1 (NODE_NAME): TEST_DIR/t.qcow2.2 (qcow2)
- Attached to: /machine/peripheral-anon/device[1]
+ Attached to: /machine/peripheral-anon/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
ide1-cd0: [not inserted]
- Attached to: /machine/unattached/device[21]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
sd0: [not inserted]
@@ -708,17 +708,17 @@ Use -device floppy,unit=1,drive=... instead.
share-rw = false
drive-type = "144"
floppy0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
- Attached to: /machine/unattached/device[16]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
none0 (NODE_NAME): TEST_DIR/t.qcow2.2 (qcow2)
- Attached to: /machine/unattached/device[15]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
ide1-cd0: [not inserted]
- Attached to: /machine/unattached/device[23]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
sd0: [not inserted]
@@ -766,17 +766,17 @@ Use -device floppy,unit=0,drive=... instead.
share-rw = false
drive-type = "144"
floppy1 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
- Attached to: /machine/unattached/device[16]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
none0 (NODE_NAME): TEST_DIR/t.qcow2.2 (qcow2)
- Attached to: /machine/unattached/device[15]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
ide1-cd0: [not inserted]
- Attached to: /machine/unattached/device[23]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
sd0: [not inserted]
@@ -838,17 +838,17 @@ Testing: -fda TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2.2 -device fl
share-rw = false
drive-type = "144"
floppy0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
- Attached to: /machine/unattached/device[15]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
none0 (NODE_NAME): TEST_DIR/t.qcow2.2 (qcow2)
- Attached to: /machine/peripheral-anon/device[0]
+ Attached to: /machine/peripheral-anon/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
ide1-cd0: [not inserted]
- Attached to: /machine/unattached/device[22]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
sd0: [not inserted]
@@ -894,17 +894,17 @@ Testing: -fda TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2.2 -device fl
share-rw = false
drive-type = "144"
floppy0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
- Attached to: /machine/unattached/device[15]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
none0 (NODE_NAME): TEST_DIR/t.qcow2.2 (qcow2)
- Attached to: /machine/peripheral-anon/device[0]
+ Attached to: /machine/peripheral-anon/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
ide1-cd0: [not inserted]
- Attached to: /machine/unattached/device[22]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
sd0: [not inserted]
@@ -950,17 +950,17 @@ Testing: -fdb TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2.2 -device fl
share-rw = false
drive-type = "144"
floppy1 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
- Attached to: /machine/unattached/device[15]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
none0 (NODE_NAME): TEST_DIR/t.qcow2.2 (qcow2)
- Attached to: /machine/peripheral-anon/device[0]
+ Attached to: /machine/peripheral-anon/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
ide1-cd0: [not inserted]
- Attached to: /machine/unattached/device[22]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
sd0: [not inserted]
@@ -1006,17 +1006,17 @@ Testing: -fdb TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2.2 -device fl
share-rw = false
drive-type = "144"
floppy1 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
- Attached to: /machine/unattached/device[15]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
none0 (NODE_NAME): TEST_DIR/t.qcow2.2 (qcow2)
- Attached to: /machine/peripheral-anon/device[0]
+ Attached to: /machine/peripheral-anon/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
ide1-cd0: [not inserted]
- Attached to: /machine/unattached/device[22]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
sd0: [not inserted]
@@ -1071,17 +1071,17 @@ Testing: -drive if=floppy,file=TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.q
share-rw = false
drive-type = "144"
floppy0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
- Attached to: /machine/unattached/device[15]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
none0 (NODE_NAME): TEST_DIR/t.qcow2.2 (qcow2)
- Attached to: /machine/peripheral-anon/device[0]
+ Attached to: /machine/peripheral-anon/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
ide1-cd0: [not inserted]
- Attached to: /machine/unattached/device[22]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
sd0: [not inserted]
@@ -1127,17 +1127,17 @@ Testing: -drive if=floppy,file=TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.q
share-rw = false
drive-type = "144"
floppy0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
- Attached to: /machine/unattached/device[15]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
none0 (NODE_NAME): TEST_DIR/t.qcow2.2 (qcow2)
- Attached to: /machine/peripheral-anon/device[0]
+ Attached to: /machine/peripheral-anon/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
ide1-cd0: [not inserted]
- Attached to: /machine/unattached/device[22]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
sd0: [not inserted]
@@ -1191,17 +1191,17 @@ Use -device floppy,unit=0,drive=... instead.
share-rw = false
drive-type = "144"
none0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
- Attached to: /machine/unattached/device[15]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
none1 (NODE_NAME): TEST_DIR/t.qcow2.2 (qcow2)
- Attached to: /machine/peripheral-anon/device[0]
+ Attached to: /machine/peripheral-anon/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
ide1-cd0: [not inserted]
- Attached to: /machine/unattached/device[22]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
sd0: [not inserted]
@@ -1249,17 +1249,17 @@ Use -device floppy,unit=0,drive=... instead.
share-rw = false
drive-type = "144"
none0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
- Attached to: /machine/unattached/device[15]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
none1 (NODE_NAME): TEST_DIR/t.qcow2.2 (qcow2)
- Attached to: /machine/peripheral-anon/device[0]
+ Attached to: /machine/peripheral-anon/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
ide1-cd0: [not inserted]
- Attached to: /machine/unattached/device[22]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
sd0: [not inserted]
@@ -1307,17 +1307,17 @@ Use -device floppy,unit=1,drive=... instead.
share-rw = false
drive-type = "144"
none0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
- Attached to: /machine/unattached/device[15]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
none1 (NODE_NAME): TEST_DIR/t.qcow2.2 (qcow2)
- Attached to: /machine/peripheral-anon/device[0]
+ Attached to: /machine/peripheral-anon/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
ide1-cd0: [not inserted]
- Attached to: /machine/unattached/device[22]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
sd0: [not inserted]
@@ -1365,17 +1365,17 @@ Use -device floppy,unit=1,drive=... instead.
share-rw = false
drive-type = "144"
none0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
- Attached to: /machine/unattached/device[15]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
none1 (NODE_NAME): TEST_DIR/t.qcow2.2 (qcow2)
- Attached to: /machine/peripheral-anon/device[0]
+ Attached to: /machine/peripheral-anon/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
ide1-cd0: [not inserted]
- Attached to: /machine/unattached/device[22]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
sd0: [not inserted]
@@ -1410,12 +1410,12 @@ Testing: -drive if=none,file=TEST_DIR/t.qcow2 -global floppy.drive=none0 -device
share-rw = false
drive-type = "144"
none0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
- Attached to: /machine/peripheral-anon/device[0]
+ Attached to: /machine/peripheral-anon/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
ide1-cd0: [not inserted]
- Attached to: /machine/unattached/device[21]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
sd0: [not inserted]
@@ -1603,12 +1603,12 @@ Testing: -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0,drive-t
share-rw = false
drive-type = "120"
none0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
- Attached to: /machine/peripheral-anon/device[0]
+ Attached to: /machine/peripheral-anon/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
ide1-cd0: [not inserted]
- Attached to: /machine/unattached/device[21]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
sd0: [not inserted]
@@ -1643,12 +1643,12 @@ Testing: -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0,drive-t
share-rw = false
drive-type = "288"
none0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
- Attached to: /machine/peripheral-anon/device[0]
+ Attached to: /machine/peripheral-anon/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
ide1-cd0: [not inserted]
- Attached to: /machine/unattached/device[21]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
sd0: [not inserted]
@@ -1686,12 +1686,12 @@ Testing: -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0,logical
share-rw = false
drive-type = "144"
none0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
- Attached to: /machine/peripheral-anon/device[0]
+ Attached to: /machine/peripheral-anon/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
ide1-cd0: [not inserted]
- Attached to: /machine/unattached/device[21]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
sd0: [not inserted]
@@ -1726,12 +1726,12 @@ Testing: -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0,physica
share-rw = false
drive-type = "144"
none0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
- Attached to: /machine/peripheral-anon/device[0]
+ Attached to: /machine/peripheral-anon/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
ide1-cd0: [not inserted]
- Attached to: /machine/unattached/device[21]
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
sd0: [not inserted]
diff --git a/tests/qemu-iotests/186.out b/tests/qemu-iotests/186.out
index 5b35040..0153004 100644
--- a/tests/qemu-iotests/186.out
+++ b/tests/qemu-iotests/186.out
@@ -7,7 +7,7 @@ Testing: -device floppy
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
/machine/peripheral-anon/device[1]: [not inserted]
- Attached to: PATH
+ Attached to: /machine/peripheral-anon/device[N]
Removable device: not locked, tray closed
(qemu) quit
@@ -23,7 +23,7 @@ Testing: -device ide-cd
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
/machine/peripheral-anon/device[1]: [not inserted]
- Attached to: PATH
+ Attached to: /machine/peripheral-anon/device[N]
Removable device: not locked, tray closed
(qemu) quit
@@ -39,7 +39,7 @@ Testing: -device scsi-cd
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
/machine/peripheral-anon/device[1]: [not inserted]
- Attached to: PATH
+ Attached to: /machine/peripheral-anon/device[N]
Removable device: not locked, tray closed
(qemu) quit
@@ -58,7 +58,7 @@ Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device ide-hd,d
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
- Attached to: PATH
+ Attached to: /machine/peripheral-anon/device[N]
Cache mode: writeback
(qemu) quit
@@ -74,7 +74,7 @@ Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device scsi-hd,
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
- Attached to: PATH
+ Attached to: /machine/peripheral-anon/device[N]
Cache mode: writeback
(qemu) quit
@@ -90,7 +90,7 @@ Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device virtio-b
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
- Attached to: PATH
+ Attached to: /machine/peripheral-anon/device[N]/virtio-backend
Cache mode: writeback
(qemu) quit
@@ -98,7 +98,7 @@ Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device virtio-b
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
- Attached to: PATH
+ Attached to: /machine/peripheral/qdev_id/virtio-backend
Cache mode: writeback
(qemu) quit
@@ -106,7 +106,7 @@ Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device floppy,d
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
- Attached to: PATH
+ Attached to: /machine/peripheral-anon/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
(qemu) quit
@@ -124,7 +124,7 @@ Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device ide-cd,d
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
- Attached to: PATH
+ Attached to: /machine/peripheral-anon/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
(qemu) quit
@@ -142,7 +142,7 @@ Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device scsi-cd,
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
- Attached to: PATH
+ Attached to: /machine/peripheral-anon/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
(qemu) quit
@@ -191,7 +191,7 @@ none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
Cache mode: writeback
null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
- Attached to: PATH
+ Attached to: /machine/peripheral/qdev_id/virtio-backend
Cache mode: writeback
(qemu) quit
@@ -241,7 +241,7 @@ Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device ide
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
- Attached to: PATH
+ Attached to: /machine/peripheral-anon/device[N]
Cache mode: writeback
(qemu) quit
@@ -257,7 +257,7 @@ Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device scs
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
- Attached to: PATH
+ Attached to: /machine/peripheral-anon/device[N]
Cache mode: writeback
(qemu) quit
@@ -273,7 +273,7 @@ Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device vir
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
- Attached to: PATH
+ Attached to: /machine/peripheral-anon/device[N]/virtio-backend
Cache mode: writeback
(qemu) quit
@@ -281,7 +281,7 @@ Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device vir
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
- Attached to: PATH
+ Attached to: /machine/peripheral/qdev_id/virtio-backend
Cache mode: writeback
(qemu) quit
@@ -289,7 +289,7 @@ Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device flo
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
- Attached to: PATH
+ Attached to: /machine/peripheral-anon/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
(qemu) quit
@@ -307,7 +307,7 @@ Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device ide
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
- Attached to: PATH
+ Attached to: /machine/peripheral-anon/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
(qemu) quit
@@ -325,7 +325,7 @@ Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device scs
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
- Attached to: PATH
+ Attached to: /machine/peripheral-anon/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
(qemu) quit
@@ -353,7 +353,7 @@ Testing: -drive if=none -device floppy,drive=none0
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
none0: [not inserted]
- Attached to: PATH
+ Attached to: /machine/peripheral-anon/device[N]
Removable device: not locked, tray closed
(qemu) quit
@@ -369,7 +369,7 @@ Testing: -drive if=none -device ide-cd,drive=none0
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
none0: [not inserted]
- Attached to: PATH
+ Attached to: /machine/peripheral-anon/device[N]
Removable device: not locked, tray closed
(qemu) quit
@@ -385,7 +385,7 @@ Testing: -drive if=none -device scsi-cd,drive=none0
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
none0: [not inserted]
- Attached to: PATH
+ Attached to: /machine/peripheral-anon/device[N]
Removable device: not locked, tray closed
(qemu) quit
@@ -404,7 +404,7 @@ Testing: -drive if=floppy
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
floppy0: [not inserted]
- Attached to: PATH
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
(qemu) quit
@@ -412,7 +412,7 @@ Testing: -drive if=floppy,driver=null-co,read-zeroes=on
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
floppy0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
- Attached to: PATH
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
(qemu) quit
@@ -421,7 +421,7 @@ Testing: -drive if=ide,driver=null-co,read-zeroes=on
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
ide0-hd0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
- Attached to: PATH
+ Attached to: /machine/unattached/device[N]
Cache mode: writeback
(qemu) quit
@@ -429,7 +429,7 @@ Testing: -drive if=ide,media=cdrom
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
ide0-cd0: [not inserted]
- Attached to: PATH
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
(qemu) quit
@@ -437,7 +437,7 @@ Testing: -drive if=ide,driver=null-co,read-zeroes=on,media=cdrom
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
ide0-cd0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co"} (null-co, read-only)
- Attached to: PATH
+ Attached to: /machine/unattached/device[N]
Removable device: not locked, tray closed
Cache mode: writeback
(qemu) quit
@@ -446,7 +446,7 @@ Testing: -drive if=virtio,driver=null-co,read-zeroes=on
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
virtio0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
- Attached to: PATH
+ Attached to: /machine/peripheral-anon/device[N]/virtio-backend
Cache mode: writeback
(qemu) quit
@@ -454,7 +454,7 @@ Testing: -drive if=pflash,driver=null-co,read-zeroes=on,size=1M
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) info block
pflash0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co", "size": "1M"} (null-co)
- Attached to: PATH
+ Attached to: /machine/system.flash0
Cache mode: writeback
(qemu) quit
diff --git a/tests/qemu-iotests/210.out b/tests/qemu-iotests/210.out
index a5e88e2..dc1a3c9 100644
--- a/tests/qemu-iotests/210.out
+++ b/tests/qemu-iotests/210.out
@@ -182,7 +182,7 @@ Job failed: The requested file size is too large
=== Resize image with invalid sizes ===
{"execute": "block_resize", "arguments": {"node-name": "node1", "size": 9223372036854775296}}
-{"error": {"class": "GenericError", "desc": "The requested file size is too large"}}
+{"error": {"class": "GenericError", "desc": "Required too big image size, it must be not greater than 9223372035781033984"}}
{"execute": "block_resize", "arguments": {"node-name": "node1", "size": 9223372036854775808}}
{"error": {"class": "GenericError", "desc": "Invalid parameter type for 'size', expected: integer"}}
{"execute": "block_resize", "arguments": {"node-name": "node1", "size": 18446744073709551104}}
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
index 172ea57..268b749 100644
--- a/tests/qemu-iotests/common.filter
+++ b/tests/qemu-iotests/common.filter
@@ -37,7 +37,7 @@ _filter_generated_node_ids()
_filter_qom_path()
{
- $SED -e 's#\(Attached to: *\) /.*#\1 PATH#'
+ $SED -e '/Attached to:/s/\device[[0-9]\+\]/device[N]/g'
}
# replace occurrences of the actual TEST_DIR value with TEST_DIR
diff --git a/tools/virtiofsd/fuse_lowlevel.c b/tools/virtiofsd/fuse_lowlevel.c
index d4119e9..e94b711 100644
--- a/tools/virtiofsd/fuse_lowlevel.c
+++ b/tools/virtiofsd/fuse_lowlevel.c
@@ -2143,104 +2143,6 @@ static void do_destroy(fuse_req_t req, fuse_ino_t nodeid,
send_reply_ok(req, NULL, 0);
}
-static int send_notify_iov(struct fuse_session *se, int notify_code,
- struct iovec *iov, int count)
-{
- struct fuse_out_header out = {
- .error = notify_code,
- };
-
- if (!se->got_init) {
- return -ENOTCONN;
- }
-
- iov[0].iov_base = &out;
- iov[0].iov_len = sizeof(struct fuse_out_header);
-
- return fuse_send_msg(se, NULL, iov, count);
-}
-
-int fuse_lowlevel_notify_poll(struct fuse_pollhandle *ph)
-{
- if (ph != NULL) {
- struct fuse_notify_poll_wakeup_out outarg = {
- .kh = ph->kh,
- };
- struct iovec iov[2];
-
- iov[1].iov_base = &outarg;
- iov[1].iov_len = sizeof(outarg);
-
- return send_notify_iov(ph->se, FUSE_NOTIFY_POLL, iov, 2);
- } else {
- return 0;
- }
-}
-
-int fuse_lowlevel_notify_inval_inode(struct fuse_session *se, fuse_ino_t ino,
- off_t off, off_t len)
-{
- struct fuse_notify_inval_inode_out outarg = {
- .ino = ino,
- .off = off,
- .len = len,
- };
- struct iovec iov[2];
-
- if (!se) {
- return -EINVAL;
- }
-
- iov[1].iov_base = &outarg;
- iov[1].iov_len = sizeof(outarg);
-
- return send_notify_iov(se, FUSE_NOTIFY_INVAL_INODE, iov, 2);
-}
-
-int fuse_lowlevel_notify_inval_entry(struct fuse_session *se, fuse_ino_t parent,
- const char *name, size_t namelen)
-{
- struct fuse_notify_inval_entry_out outarg = {
- .parent = parent,
- .namelen = namelen,
- };
- struct iovec iov[3];
-
- if (!se) {
- return -EINVAL;
- }
-
- iov[1].iov_base = &outarg;
- iov[1].iov_len = sizeof(outarg);
- iov[2].iov_base = (void *)name;
- iov[2].iov_len = namelen + 1;
-
- return send_notify_iov(se, FUSE_NOTIFY_INVAL_ENTRY, iov, 3);
-}
-
-int fuse_lowlevel_notify_delete(struct fuse_session *se, fuse_ino_t parent,
- fuse_ino_t child, const char *name,
- size_t namelen)
-{
- struct fuse_notify_delete_out outarg = {
- .parent = parent,
- .child = child,
- .namelen = namelen,
- };
- struct iovec iov[3];
-
- if (!se) {
- return -EINVAL;
- }
-
- iov[1].iov_base = &outarg;
- iov[1].iov_len = sizeof(outarg);
- iov[2].iov_base = (void *)name;
- iov[2].iov_len = namelen + 1;
-
- return send_notify_iov(se, FUSE_NOTIFY_DELETE, iov, 3);
-}
-
int fuse_lowlevel_notify_store(struct fuse_session *se, fuse_ino_t ino,
off_t offset, struct fuse_bufvec *bufv)
{
diff --git a/tools/virtiofsd/fuse_virtio.c b/tools/virtiofsd/fuse_virtio.c
index b264dcb..ddcefee 100644
--- a/tools/virtiofsd/fuse_virtio.c
+++ b/tools/virtiofsd/fuse_virtio.c
@@ -578,13 +578,18 @@ static void *fv_queue_thread(void *opaque)
struct VuDev *dev = &qi->virtio_dev->dev;
struct VuVirtq *q = vu_get_queue(dev, qi->qidx);
struct fuse_session *se = qi->virtio_dev->se;
- GThreadPool *pool;
-
- pool = g_thread_pool_new(fv_queue_worker, qi, se->thread_pool_size, FALSE,
- NULL);
- if (!pool) {
- fuse_log(FUSE_LOG_ERR, "%s: g_thread_pool_new failed\n", __func__);
- return NULL;
+ GThreadPool *pool = NULL;
+ GList *req_list = NULL;
+
+ if (se->thread_pool_size) {
+ fuse_log(FUSE_LOG_DEBUG, "%s: Creating thread pool for Queue %d\n",
+ __func__, qi->qidx);
+ pool = g_thread_pool_new(fv_queue_worker, qi, se->thread_pool_size,
+ FALSE, NULL);
+ if (!pool) {
+ fuse_log(FUSE_LOG_ERR, "%s: g_thread_pool_new failed\n", __func__);
+ return NULL;
+ }
}
fuse_log(FUSE_LOG_INFO, "%s: Start for queue %d kick_fd %d\n", __func__,
@@ -659,14 +664,27 @@ static void *fv_queue_thread(void *opaque)
req->reply_sent = false;
- g_thread_pool_push(pool, req, NULL);
+ if (!se->thread_pool_size) {
+ req_list = g_list_prepend(req_list, req);
+ } else {
+ g_thread_pool_push(pool, req, NULL);
+ }
}
pthread_mutex_unlock(&qi->vq_lock);
pthread_rwlock_unlock(&qi->virtio_dev->vu_dispatch_rwlock);
+
+ /* Process all the requests. */
+ if (!se->thread_pool_size && req_list != NULL) {
+ g_list_foreach(req_list, fv_queue_worker, qi);
+ g_list_free(req_list);
+ req_list = NULL;
+ }
}
- g_thread_pool_free(pool, FALSE, TRUE);
+ if (pool) {
+ g_thread_pool_free(pool, FALSE, TRUE);
+ }
return NULL;
}
diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c
index 12de321..5fb36d9 100644
--- a/tools/virtiofsd/passthrough_ll.c
+++ b/tools/virtiofsd/passthrough_ll.c
@@ -101,7 +101,7 @@ struct lo_inode {
* This counter keeps the inode alive during the FUSE session.
* Incremented when the FUSE inode number is sent in a reply
* (FUSE_LOOKUP, FUSE_READDIRPLUS, etc). Decremented when an inode is
- * released by requests like FUSE_FORGET, FUSE_RMDIR, FUSE_RENAME, etc.
+ * released by a FUSE_FORGET request.
*
* Note that this value is untrusted because the client can manipulate
* it arbitrarily using FUSE_FORGET requests.
@@ -902,10 +902,11 @@ static int lo_do_lookup(fuse_req_t req, fuse_ino_t parent, const char *name,
inode->key.ino = e->attr.st_ino;
inode->key.dev = e->attr.st_dev;
inode->key.mnt_id = mnt_id;
- pthread_mutex_init(&inode->plock_mutex, NULL);
- inode->posix_locks = g_hash_table_new_full(
- g_direct_hash, g_direct_equal, NULL, posix_locks_value_destroy);
-
+ if (lo->posix_lock) {
+ pthread_mutex_init(&inode->plock_mutex, NULL);
+ inode->posix_locks = g_hash_table_new_full(
+ g_direct_hash, g_direct_equal, NULL, posix_locks_value_destroy);
+ }
pthread_mutex_lock(&lo->mutex);
inode->fuse_ino = lo_add_inode_mapping(req, inode);
g_hash_table_insert(lo->inodes, &inode->key, inode);
@@ -1291,12 +1292,13 @@ static void unref_inode(struct lo_data *lo, struct lo_inode *inode, uint64_t n)
if (!inode->nlookup) {
lo_map_remove(&lo->ino_map, inode->fuse_ino);
g_hash_table_remove(lo->inodes, &inode->key);
- if (g_hash_table_size(inode->posix_locks)) {
- fuse_log(FUSE_LOG_WARNING, "Hash table is not empty\n");
+ if (lo->posix_lock) {
+ if (g_hash_table_size(inode->posix_locks)) {
+ fuse_log(FUSE_LOG_WARNING, "Hash table is not empty\n");
+ }
+ g_hash_table_destroy(inode->posix_locks);
+ pthread_mutex_destroy(&inode->plock_mutex);
}
- g_hash_table_destroy(inode->posix_locks);
- pthread_mutex_destroy(&inode->plock_mutex);
-
/* Drop our refcount from lo_do_lookup() */
lo_inode_put(lo, &inode);
}
@@ -1772,6 +1774,11 @@ static void lo_getlk(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi,
ino, fi->flags, fi->lock_owner, lock->l_type, lock->l_start,
lock->l_len);
+ if (!lo->posix_lock) {
+ fuse_reply_err(req, ENOSYS);
+ return;
+ }
+
inode = lo_inode(req, ino);
if (!inode) {
fuse_reply_err(req, EBADF);
@@ -1817,6 +1824,11 @@ static void lo_setlk(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi,
ino, fi->flags, lock->l_type, lock->l_pid, fi->lock_owner, sleep,
lock->l_whence, lock->l_start, lock->l_len);
+ if (!lo->posix_lock) {
+ fuse_reply_err(req, ENOSYS);
+ return;
+ }
+
if (sleep) {
fuse_reply_err(req, EOPNOTSUPP);
return;
@@ -1941,6 +1953,7 @@ static void lo_flush(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
int res;
(void)ino;
struct lo_inode *inode;
+ struct lo_data *lo = lo_data(req);
inode = lo_inode(req, ino);
if (!inode) {
@@ -1948,13 +1961,21 @@ static void lo_flush(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
return;
}
- /* An fd is going away. Cleanup associated posix locks */
- pthread_mutex_lock(&inode->plock_mutex);
- g_hash_table_remove(inode->posix_locks, GUINT_TO_POINTER(fi->lock_owner));
- pthread_mutex_unlock(&inode->plock_mutex);
+ if (!S_ISREG(inode->filetype)) {
+ lo_inode_put(lo, &inode);
+ fuse_reply_err(req, EBADF);
+ return;
+ }
+ /* An fd is going away. Cleanup associated posix locks */
+ if (lo->posix_lock) {
+ pthread_mutex_lock(&inode->plock_mutex);
+ g_hash_table_remove(inode->posix_locks,
+ GUINT_TO_POINTER(fi->lock_owner));
+ pthread_mutex_unlock(&inode->plock_mutex);
+ }
res = close(dup(lo_fi_fd(req, fi)));
- lo_inode_put(lo_data(req), &inode);
+ lo_inode_put(lo, &inode);
fuse_reply_err(req, res == -1 ? errno : 0);
}
@@ -3284,18 +3305,38 @@ static void setup_nofile_rlimit(unsigned long rlimit_nofile)
static void log_func(enum fuse_log_level level, const char *fmt, va_list ap)
{
g_autofree char *localfmt = NULL;
+ struct timespec ts;
+ struct tm tm;
+ char sec_fmt[sizeof "2020-12-07 18:17:54"];
+ char zone_fmt[sizeof "+0100"];
if (current_log_level < level) {
return;
}
if (current_log_level == FUSE_LOG_DEBUG) {
- if (!use_syslog) {
- localfmt = g_strdup_printf("[%" PRId64 "] [ID: %08ld] %s",
- get_clock(), syscall(__NR_gettid), fmt);
- } else {
+ if (use_syslog) {
+ /* no timestamp needed */
localfmt = g_strdup_printf("[ID: %08ld] %s", syscall(__NR_gettid),
fmt);
+ } else {
+ /* try formatting a broken-down timestamp */
+ if (clock_gettime(CLOCK_REALTIME, &ts) != -1 &&
+ localtime_r(&ts.tv_sec, &tm) != NULL &&
+ strftime(sec_fmt, sizeof sec_fmt, "%Y-%m-%d %H:%M:%S",
+ &tm) != 0 &&
+ strftime(zone_fmt, sizeof zone_fmt, "%z", &tm) != 0) {
+ localfmt = g_strdup_printf("[%s.%02ld%s] [ID: %08ld] %s",
+ sec_fmt,
+ ts.tv_nsec / (10L * 1000 * 1000),
+ zone_fmt, syscall(__NR_gettid),
+ fmt);
+ } else {
+ /* fall back to a flat timestamp */
+ localfmt = g_strdup_printf("[%" PRId64 "] [ID: %08ld] %s",
+ get_clock(), syscall(__NR_gettid),
+ fmt);
+ }
}
fmt = localfmt;
}
@@ -3360,6 +3401,11 @@ static void setup_root(struct lo_data *lo, struct lo_inode *root)
root->key.mnt_id = mnt_id;
root->nlookup = 2;
g_atomic_int_set(&root->refcount, 2);
+ if (lo->posix_lock) {
+ pthread_mutex_init(&root->plock_mutex, NULL);
+ root->posix_locks = g_hash_table_new_full(
+ g_direct_hash, g_direct_equal, NULL, posix_locks_value_destroy);
+ }
}
static guint lo_key_hash(gconstpointer key)
@@ -3382,6 +3428,10 @@ static void fuse_lo_data_cleanup(struct lo_data *lo)
if (lo->inodes) {
g_hash_table_destroy(lo->inodes);
}
+
+ if (lo->root.posix_locks) {
+ g_hash_table_destroy(lo->root.posix_locks);
+ }
lo_map_destroy(&lo->fd_map);
lo_map_destroy(&lo->dirp_map);
lo_map_destroy(&lo->ino_map);
@@ -3416,6 +3466,9 @@ int main(int argc, char *argv[])
struct lo_map_elem *reserve_elem;
int ret = -1;
+ /* Initialize time conversion information for localtime_r(). */
+ tzset();
+
/* Don't mask creation mode, kernel already did that */
umask(0);