aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS5
-rw-r--r--backends/baum.c10
-rw-r--r--backends/msmouse.c10
-rw-r--r--backends/rng-random.c4
-rw-r--r--block.c8
-rw-r--r--block/iscsi.c426
-rw-r--r--block/sheepdog.c315
-rwxr-xr-xconfigure20
-rw-r--r--cpu-exec.c59
-rw-r--r--exec.c2
-rw-r--r--gdbstub.c5
-rw-r--r--hmp-commands.hx2
-rw-r--r--hw/a15mpcore.c8
-rw-r--r--hw/arm/Makefile.objs2
-rw-r--r--hw/arm/pic_cpu.c26
-rw-r--r--hw/arm_gic.c23
-rw-r--r--hw/arm_gic_common.c36
-rw-r--r--hw/arm_gic_internal.h4
-rw-r--r--hw/armv7m_nvic.c15
-rw-r--r--hw/dataplane/Makefile.objs2
-rw-r--r--hw/dataplane/event-poll.c100
-rw-r--r--hw/dataplane/event-poll.h40
-rw-r--r--hw/dataplane/virtio-blk.c50
-rw-r--r--hw/e1000.c25
-rw-r--r--hw/i386/pc_piix.c4
-rw-r--r--hw/ich9.h11
-rw-r--r--hw/kvm/arm_gic.c167
-rw-r--r--hw/lpc_ich9.c57
-rw-r--r--hw/macio.c2
-rw-r--r--hw/milkymist-hw.h16
-rw-r--r--hw/nand.c3
-rw-r--r--hw/pc.h5
-rw-r--r--hw/pci/pci_host.h1
-rw-r--r--hw/piix_pci.c1
-rw-r--r--hw/ppc/prep.c1
-rw-r--r--hw/scsi-bus.c4
-rw-r--r--hw/scsi-disk.c36
-rw-r--r--hw/serial.c28
-rw-r--r--hw/serial.h2
-rw-r--r--hw/sysbus.c27
-rw-r--r--hw/sysbus.h2
-rw-r--r--hw/vhost.c49
-rw-r--r--hw/virtio-blk.c4
-rw-r--r--hw/virtio-console.c28
-rw-r--r--hw/virtio-net.c6
-rw-r--r--hw/virtio-pci.c5
-rw-r--r--hw/virtio-serial-bus.c19
-rw-r--r--include/char/baum.h30
-rw-r--r--include/char/char.h8
-rw-r--r--include/char/msmouse.h7
-rw-r--r--include/exec/gen-icount.h18
-rw-r--r--include/net/net.h2
-rw-r--r--include/qemu/sockets.h1
-rw-r--r--include/qom/cpu.h3
-rw-r--r--linux-headers/asm-arm/kvm.h180
-rw-r--r--linux-headers/asm-arm/kvm_para.h1
-rw-r--r--linux-headers/asm-generic/kvm_para.h4
-rw-r--r--linux-headers/linux/kvm.h17
-rw-r--r--linux-user/main.c101
-rw-r--r--linux-user/mips64/syscall.h18
-rw-r--r--linux-user/mips64/syscall_nr.h920
-rw-r--r--linux-user/mipsn32/syscall.h224
-rw-r--r--linux-user/mipsn32/syscall_nr.h311
-rw-r--r--linux-user/mipsn32/target_signal.h29
-rw-r--r--linux-user/mipsn32/termbits.h245
-rw-r--r--linux-user/signal.c245
-rw-r--r--net/hub.c14
-rw-r--r--net/hub.h1
-rw-r--r--net/net.c25
-rw-r--r--net/queue.c15
-rw-r--r--net/tap-linux.c10
-rw-r--r--net/tap-linux.h9
-rw-r--r--net/tap.c7
-rw-r--r--pc-bios/bios.binbin131072 -> 131072 bytes
-rw-r--r--qemu-char.c771
-rw-r--r--qemu-doc.texi22
-rw-r--r--qemu-options.hx31
-rw-r--r--qmp-commands.hx2
m---------roms/seabios0
-rw-r--r--slirp/tcp_subr.c139
-rw-r--r--spice-qemu-char.c10
-rw-r--r--target-alpha/cpu-qom.h1
-rw-r--r--target-alpha/translate.c4
-rw-r--r--target-arm/Makefile.objs1
-rw-r--r--target-arm/cpu-qom.h2
-rw-r--r--target-arm/cpu.h1
-rw-r--r--target-arm/helper.c13
-rw-r--r--target-arm/kvm.c493
-rw-r--r--target-arm/kvm_arm.h32
-rw-r--r--target-arm/translate.c145
-rw-r--r--target-cris/cpu-qom.h1
-rw-r--r--target-cris/translate.c4
-rw-r--r--target-i386/cpu-qom.h1
-rw-r--r--target-i386/cpu.c3
-rw-r--r--target-i386/translate.c4
-rw-r--r--target-lm32/cpu-qom.h1
-rw-r--r--target-lm32/translate.c4
-rw-r--r--target-m68k/cpu-qom.h1
-rw-r--r--target-m68k/translate.c4
-rw-r--r--target-microblaze/cpu-qom.h1
-rw-r--r--target-microblaze/translate.c4
-rw-r--r--target-mips/cpu-qom.h1
-rw-r--r--target-mips/cpu.h3
-rw-r--r--target-mips/dsp_helper.c106
-rw-r--r--target-mips/translate.c164
-rw-r--r--target-openrisc/cpu.h2
-rw-r--r--target-openrisc/translate.c4
-rw-r--r--target-ppc/cpu-qom.h3
-rw-r--r--target-ppc/translate.c4
-rw-r--r--target-s390x/cpu-qom.h1
-rw-r--r--target-s390x/translate.c4
-rw-r--r--target-sh4/cpu-qom.h1
-rw-r--r--target-sh4/translate.c4
-rw-r--r--target-sparc/cpu-qom.h1
-rw-r--r--target-sparc/translate.c4
-rw-r--r--target-unicore32/cpu-qom.h1
-rw-r--r--target-unicore32/translate.c4
-rw-r--r--target-xtensa/cpu-qom.h1
-rw-r--r--target-xtensa/translate.c4
-rw-r--r--tcg/sparc/tcg-target.c2
-rw-r--r--tcg/tcg.h49
-rw-r--r--tests/rtc-test.c4
-rw-r--r--tests/tcg/mips/mips32-dsp/subq_s_ph.c22
-rw-r--r--tests/tcg/mips/mips32-dsp/subq_s_w.c36
-rw-r--r--trace-events1
-rw-r--r--translate-all.c73
-rw-r--r--ui/console.c7
-rw-r--r--util/osdep.c8
-rw-r--r--util/oslib-posix.c2
-rw-r--r--util/qemu-sockets.c4
-rw-r--r--vl.c1
131 files changed, 3705 insertions, 2631 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 21043e4b4a..2439614ad2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -140,6 +140,11 @@ S: Supported
F: kvm-*
F: */kvm.*
+ARM
+M: Peter Maydell <peter.maydell@linaro.org>
+S: Maintained
+F: target-arm/kvm.c
+
PPC
M: Alexander Graf <agraf@suse.de>
S: Maintained
diff --git a/backends/baum.c b/backends/baum.c
index 37ccca8211..9063aea2cf 100644
--- a/backends/baum.c
+++ b/backends/baum.c
@@ -25,7 +25,6 @@
#include "char/char.h"
#include "qemu/timer.h"
#include "hw/usb.h"
-#include "char/baum.h"
#include <brlapi.h>
#include <brlapi_constants.h>
#include <brlapi_keycodes.h>
@@ -562,7 +561,7 @@ static void baum_close(struct CharDriverState *chr)
g_free(baum);
}
-CharDriverState *chr_baum_init(QemuOpts *opts)
+static CharDriverState *chr_baum_init(QemuOpts *opts)
{
BaumDriverState *baum;
CharDriverState *chr;
@@ -625,3 +624,10 @@ fail_handle:
g_free(baum);
return NULL;
}
+
+static void register_types(void)
+{
+ register_char_driver("braille", chr_baum_init);
+}
+
+type_init(register_types);
diff --git a/backends/msmouse.c b/backends/msmouse.c
index bf2ff2aca8..407ec87784 100644
--- a/backends/msmouse.c
+++ b/backends/msmouse.c
@@ -25,7 +25,6 @@
#include "qemu-common.h"
#include "char/char.h"
#include "ui/console.h"
-#include "char/msmouse.h"
#define MSMOUSE_LO6(n) ((n) & 0x3f)
#define MSMOUSE_HI2(n) (((n) & 0xc0) >> 6)
@@ -64,7 +63,7 @@ static void msmouse_chr_close (struct CharDriverState *chr)
g_free (chr);
}
-CharDriverState *qemu_chr_open_msmouse(QemuOpts *opts)
+static CharDriverState *qemu_chr_open_msmouse(QemuOpts *opts)
{
CharDriverState *chr;
@@ -76,3 +75,10 @@ CharDriverState *qemu_chr_open_msmouse(QemuOpts *opts)
return chr;
}
+
+static void register_types(void)
+{
+ register_char_driver("msmouse", qemu_chr_open_msmouse);
+}
+
+type_init(register_types);
diff --git a/backends/rng-random.c b/backends/rng-random.c
index 0d1108811d..acd20afad2 100644
--- a/backends/rng-random.c
+++ b/backends/rng-random.c
@@ -74,7 +74,7 @@ static void rng_random_opened(RngBackend *b, Error **errp)
error_set(errp, QERR_INVALID_PARAMETER_VALUE,
"filename", "a valid filename");
} else {
- s->fd = open(s->filename, O_RDONLY | O_NONBLOCK);
+ s->fd = qemu_open(s->filename, O_RDONLY | O_NONBLOCK);
if (s->fd == -1) {
error_set(errp, QERR_OPEN_FILE_FAILED, s->filename);
@@ -130,7 +130,7 @@ static void rng_random_finalize(Object *obj)
qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
if (s->fd != -1) {
- close(s->fd);
+ qemu_close(s->fd);
}
g_free(s->filename);
diff --git a/block.c b/block.c
index 4582961965..124a9ebf65 100644
--- a/block.c
+++ b/block.c
@@ -1640,9 +1640,11 @@ int bdrv_commit_all(void)
BlockDriverState *bs;
QTAILQ_FOREACH(bs, &bdrv_states, list) {
- int ret = bdrv_commit(bs);
- if (ret < 0) {
- return ret;
+ if (bs->drv && bs->backing_hd) {
+ int ret = bdrv_commit(bs);
+ if (ret < 0) {
+ return ret;
+ }
}
}
return 0;
diff --git a/block/iscsi.c b/block/iscsi.c
index deb3b68890..3d529213ff 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -60,8 +60,11 @@ typedef struct IscsiAIOCB {
uint8_t *buf;
int status;
int canceled;
+ int retries;
size_t read_size;
size_t read_offset;
+ int64_t sector_num;
+ int nb_sectors;
#ifdef __linux__
sg_io_hdr_t *ioh;
#endif
@@ -69,6 +72,7 @@ typedef struct IscsiAIOCB {
#define NOP_INTERVAL 5000
#define MAX_NOP_FAILURES 3
+#define ISCSI_CMD_RETRIES 5
static void
iscsi_bh_cb(void *p)
@@ -191,6 +195,8 @@ iscsi_process_write(void *arg)
iscsi_set_events(iscsilun);
}
+static int
+iscsi_aio_writev_acb(IscsiAIOCB *acb);
static void
iscsi_aio_write16_cb(struct iscsi_context *iscsi, int status,
@@ -208,7 +214,19 @@ iscsi_aio_write16_cb(struct iscsi_context *iscsi, int status,
}
acb->status = 0;
- if (status < 0) {
+ if (status != 0) {
+ if (status == SCSI_STATUS_CHECK_CONDITION
+ && acb->task->sense.key == SCSI_SENSE_UNIT_ATTENTION
+ && acb->retries-- > 0) {
+ if (acb->task != NULL) {
+ scsi_free_scsi_task(acb->task);
+ acb->task = NULL;
+ }
+ if (iscsi_aio_writev_acb(acb) == 0) {
+ iscsi_set_events(acb->iscsilun);
+ return;
+ }
+ }
error_report("Failed to write16 data to iSCSI lun. %s",
iscsi_get_error(iscsi));
acb->status = -EIO;
@@ -222,15 +240,10 @@ static int64_t sector_qemu2lun(int64_t sector, IscsiLun *iscsilun)
return sector * BDRV_SECTOR_SIZE / iscsilun->block_size;
}
-static BlockDriverAIOCB *
-iscsi_aio_writev(BlockDriverState *bs, int64_t sector_num,
- QEMUIOVector *qiov, int nb_sectors,
- BlockDriverCompletionFunc *cb,
- void *opaque)
+static int
+iscsi_aio_writev_acb(IscsiAIOCB *acb)
{
- IscsiLun *iscsilun = bs->opaque;
- struct iscsi_context *iscsi = iscsilun->iscsi;
- IscsiAIOCB *acb;
+ struct iscsi_context *iscsi = acb->iscsilun->iscsi;
size_t size;
uint32_t num_sectors;
uint64_t lba;
@@ -239,19 +252,13 @@ iscsi_aio_writev(BlockDriverState *bs, int64_t sector_num,
#endif
int ret;
- acb = qemu_aio_get(&iscsi_aiocb_info, bs, cb, opaque);
- trace_iscsi_aio_writev(iscsi, sector_num, nb_sectors, opaque, acb);
-
- acb->iscsilun = iscsilun;
- acb->qiov = qiov;
-
acb->canceled = 0;
acb->bh = NULL;
acb->status = -EINPROGRESS;
acb->buf = NULL;
/* this will allow us to get rid of 'buf' completely */
- size = nb_sectors * BDRV_SECTOR_SIZE;
+ size = acb->nb_sectors * BDRV_SECTOR_SIZE;
#if !defined(LIBISCSI_FEATURE_IOVECTOR)
data.size = MIN(size, acb->qiov->size);
@@ -270,48 +277,76 @@ iscsi_aio_writev(BlockDriverState *bs, int64_t sector_num,
if (acb->task == NULL) {
error_report("iSCSI: Failed to allocate task for scsi WRITE16 "
"command. %s", iscsi_get_error(iscsi));
- qemu_aio_release(acb);
- return NULL;
+ return -1;
}
memset(acb->task, 0, sizeof(struct scsi_task));
acb->task->xfer_dir = SCSI_XFER_WRITE;
acb->task->cdb_size = 16;
acb->task->cdb[0] = 0x8a;
- lba = sector_qemu2lun(sector_num, iscsilun);
+ lba = sector_qemu2lun(acb->sector_num, acb->iscsilun);
*(uint32_t *)&acb->task->cdb[2] = htonl(lba >> 32);
*(uint32_t *)&acb->task->cdb[6] = htonl(lba & 0xffffffff);
- num_sectors = size / iscsilun->block_size;
+ num_sectors = size / acb->iscsilun->block_size;
*(uint32_t *)&acb->task->cdb[10] = htonl(num_sectors);
acb->task->expxferlen = size;
#if defined(LIBISCSI_FEATURE_IOVECTOR)
- ret = iscsi_scsi_command_async(iscsi, iscsilun->lun, acb->task,
+ ret = iscsi_scsi_command_async(iscsi, acb->iscsilun->lun, acb->task,
iscsi_aio_write16_cb,
NULL,
acb);
#else
- ret = iscsi_scsi_command_async(iscsi, iscsilun->lun, acb->task,
+ ret = iscsi_scsi_command_async(iscsi, acb->iscsilun->lun, acb->task,
iscsi_aio_write16_cb,
&data,
acb);
#endif
if (ret != 0) {
- scsi_free_scsi_task(acb->task);
g_free(acb->buf);
- qemu_aio_release(acb);
- return NULL;
+ return -1;
}
#if defined(LIBISCSI_FEATURE_IOVECTOR)
scsi_task_set_iov_out(acb->task, (struct scsi_iovec*) acb->qiov->iov, acb->qiov->niov);
#endif
- iscsi_set_events(iscsilun);
+ return 0;
+}
+
+static BlockDriverAIOCB *
+iscsi_aio_writev(BlockDriverState *bs, int64_t sector_num,
+ QEMUIOVector *qiov, int nb_sectors,
+ BlockDriverCompletionFunc *cb,
+ void *opaque)
+{
+ IscsiLun *iscsilun = bs->opaque;
+ IscsiAIOCB *acb;
+ acb = qemu_aio_get(&iscsi_aiocb_info, bs, cb, opaque);
+ trace_iscsi_aio_writev(iscsilun->iscsi, sector_num, nb_sectors, opaque, acb);
+
+ acb->iscsilun = iscsilun;
+ acb->qiov = qiov;
+ acb->nb_sectors = nb_sectors;
+ acb->sector_num = sector_num;
+ acb->retries = ISCSI_CMD_RETRIES;
+
+ if (iscsi_aio_writev_acb(acb) != 0) {
+ if (acb->task) {
+ scsi_free_scsi_task(acb->task);
+ }
+ qemu_aio_release(acb);
+ return NULL;
+ }
+
+ iscsi_set_events(iscsilun);
return &acb->common;
}
+static int
+iscsi_aio_readv_acb(IscsiAIOCB *acb);
+
static void
iscsi_aio_read16_cb(struct iscsi_context *iscsi, int status,
void *command_data, void *opaque)
@@ -326,6 +361,18 @@ iscsi_aio_read16_cb(struct iscsi_context *iscsi, int status,
acb->status = 0;
if (status != 0) {
+ if (status == SCSI_STATUS_CHECK_CONDITION
+ && acb->task->sense.key == SCSI_SENSE_UNIT_ATTENTION
+ && acb->retries-- > 0) {
+ if (acb->task != NULL) {
+ scsi_free_scsi_task(acb->task);
+ acb->task = NULL;
+ }
+ if (iscsi_aio_readv_acb(acb) == 0) {
+ iscsi_set_events(acb->iscsilun);
+ return;
+ }
+ }
error_report("Failed to read16 data from iSCSI lun. %s",
iscsi_get_error(iscsi));
acb->status = -EIO;
@@ -334,35 +381,20 @@ iscsi_aio_read16_cb(struct iscsi_context *iscsi, int status,
iscsi_schedule_bh(acb);
}
-static BlockDriverAIOCB *
-iscsi_aio_readv(BlockDriverState *bs, int64_t sector_num,
- QEMUIOVector *qiov, int nb_sectors,
- BlockDriverCompletionFunc *cb,
- void *opaque)
+static int
+iscsi_aio_readv_acb(IscsiAIOCB *acb)
{
- IscsiLun *iscsilun = bs->opaque;
- struct iscsi_context *iscsi = iscsilun->iscsi;
- IscsiAIOCB *acb;
- size_t qemu_read_size;
+ struct iscsi_context *iscsi = acb->iscsilun->iscsi;
+ uint64_t lba;
+ uint32_t num_sectors;
+ int ret;
#if !defined(LIBISCSI_FEATURE_IOVECTOR)
int i;
#endif
- int ret;
- uint64_t lba;
- uint32_t num_sectors;
-
- qemu_read_size = BDRV_SECTOR_SIZE * (size_t)nb_sectors;
-
- acb = qemu_aio_get(&iscsi_aiocb_info, bs, cb, opaque);
- trace_iscsi_aio_readv(iscsi, sector_num, nb_sectors, opaque, acb);
-
- acb->iscsilun = iscsilun;
- acb->qiov = qiov;
acb->canceled = 0;
acb->bh = NULL;
acb->status = -EINPROGRESS;
- acb->read_size = qemu_read_size;
acb->buf = NULL;
/* If LUN blocksize is bigger than BDRV_BLOCK_SIZE a read from QEMU
@@ -370,30 +402,29 @@ iscsi_aio_readv(BlockDriverState *bs, int64_t sector_num,
* data.
*/
acb->read_offset = 0;
- if (iscsilun->block_size > BDRV_SECTOR_SIZE) {
- uint64_t bdrv_offset = BDRV_SECTOR_SIZE * sector_num;
+ if (acb->iscsilun->block_size > BDRV_SECTOR_SIZE) {
+ uint64_t bdrv_offset = BDRV_SECTOR_SIZE * acb->sector_num;
- acb->read_offset = bdrv_offset % iscsilun->block_size;
+ acb->read_offset = bdrv_offset % acb->iscsilun->block_size;
}
- num_sectors = (qemu_read_size + iscsilun->block_size
+ num_sectors = (acb->read_size + acb->iscsilun->block_size
+ acb->read_offset - 1)
- / iscsilun->block_size;
+ / acb->iscsilun->block_size;
acb->task = malloc(sizeof(struct scsi_task));
if (acb->task == NULL) {
error_report("iSCSI: Failed to allocate task for scsi READ16 "
"command. %s", iscsi_get_error(iscsi));
- qemu_aio_release(acb);
- return NULL;
+ return -1;
}
memset(acb->task, 0, sizeof(struct scsi_task));
acb->task->xfer_dir = SCSI_XFER_READ;
- lba = sector_qemu2lun(sector_num, iscsilun);
- acb->task->expxferlen = qemu_read_size;
+ lba = sector_qemu2lun(acb->sector_num, acb->iscsilun);
+ acb->task->expxferlen = acb->read_size;
- switch (iscsilun->type) {
+ switch (acb->iscsilun->type) {
case TYPE_DISK:
acb->task->cdb_size = 16;
acb->task->cdb[0] = 0x88;
@@ -409,14 +440,12 @@ iscsi_aio_readv(BlockDriverState *bs, int64_t sector_num,
break;
}
- ret = iscsi_scsi_command_async(iscsi, iscsilun->lun, acb->task,
+ ret = iscsi_scsi_command_async(iscsi, acb->iscsilun->lun, acb->task,
iscsi_aio_read16_cb,
NULL,
acb);
if (ret != 0) {
- scsi_free_scsi_task(acb->task);
- qemu_aio_release(acb);
- return NULL;
+ return -1;
}
#if defined(LIBISCSI_FEATURE_IOVECTOR)
@@ -428,12 +457,42 @@ iscsi_aio_readv(BlockDriverState *bs, int64_t sector_num,
acb->qiov->iov[i].iov_base);
}
#endif
+ return 0;
+}
- iscsi_set_events(iscsilun);
+static BlockDriverAIOCB *
+iscsi_aio_readv(BlockDriverState *bs, int64_t sector_num,
+ QEMUIOVector *qiov, int nb_sectors,
+ BlockDriverCompletionFunc *cb,
+ void *opaque)
+{
+ IscsiLun *iscsilun = bs->opaque;
+ IscsiAIOCB *acb;
+ acb = qemu_aio_get(&iscsi_aiocb_info, bs, cb, opaque);
+ trace_iscsi_aio_readv(iscsilun->iscsi, sector_num, nb_sectors, opaque, acb);
+
+ acb->nb_sectors = nb_sectors;
+ acb->sector_num = sector_num;
+ acb->iscsilun = iscsilun;
+ acb->qiov = qiov;
+ acb->read_size = BDRV_SECTOR_SIZE * (size_t)acb->nb_sectors;
+ acb->retries = ISCSI_CMD_RETRIES;
+
+ if (iscsi_aio_readv_acb(acb) != 0) {
+ if (acb->task) {
+ scsi_free_scsi_task(acb->task);
+ }
+ qemu_aio_release(acb);
+ return NULL;
+ }
+
+ iscsi_set_events(iscsilun);
return &acb->common;
}
+static int
+iscsi_aio_flush_acb(IscsiAIOCB *acb);
static void
iscsi_synccache10_cb(struct iscsi_context *iscsi, int status,
@@ -446,7 +505,19 @@ iscsi_synccache10_cb(struct iscsi_context *iscsi, int status,
}
acb->status = 0;
- if (status < 0) {
+ if (status != 0) {
+ if (status == SCSI_STATUS_CHECK_CONDITION
+ && acb->task->sense.key == SCSI_SENSE_UNIT_ATTENTION
+ && acb->retries-- > 0) {
+ if (acb->task != NULL) {
+ scsi_free_scsi_task(acb->task);
+ acb->task = NULL;
+ }
+ if (iscsi_aio_flush_acb(acb) == 0) {
+ iscsi_set_events(acb->iscsilun);
+ return;
+ }
+ }
error_report("Failed to sync10 data on iSCSI lun. %s",
iscsi_get_error(iscsi));
acb->status = -EIO;
@@ -455,29 +526,43 @@ iscsi_synccache10_cb(struct iscsi_context *iscsi, int status,
iscsi_schedule_bh(acb);
}
-static BlockDriverAIOCB *
-iscsi_aio_flush(BlockDriverState *bs,
- BlockDriverCompletionFunc *cb, void *opaque)
+static int
+iscsi_aio_flush_acb(IscsiAIOCB *acb)
{
- IscsiLun *iscsilun = bs->opaque;
- struct iscsi_context *iscsi = iscsilun->iscsi;
- IscsiAIOCB *acb;
-
- acb = qemu_aio_get(&iscsi_aiocb_info, bs, cb, opaque);
+ struct iscsi_context *iscsi = acb->iscsilun->iscsi;
- acb->iscsilun = iscsilun;
acb->canceled = 0;
acb->bh = NULL;
acb->status = -EINPROGRESS;
acb->buf = NULL;
- acb->task = iscsi_synchronizecache10_task(iscsi, iscsilun->lun,
+ acb->task = iscsi_synchronizecache10_task(iscsi, acb->iscsilun->lun,
0, 0, 0, 0,
iscsi_synccache10_cb,
acb);
if (acb->task == NULL) {
error_report("iSCSI: Failed to send synchronizecache10 command. %s",
iscsi_get_error(iscsi));
+ return -1;
+ }
+
+ return 0;
+}
+
+static BlockDriverAIOCB *
+iscsi_aio_flush(BlockDriverState *bs,
+ BlockDriverCompletionFunc *cb, void *opaque)
+{
+ IscsiLun *iscsilun = bs->opaque;
+
+ IscsiAIOCB *acb;
+
+ acb = qemu_aio_get(&iscsi_aiocb_info, bs, cb, opaque);
+
+ acb->iscsilun = iscsilun;
+ acb->retries = ISCSI_CMD_RETRIES;
+
+ if (iscsi_aio_flush_acb(acb) != 0) {
qemu_aio_release(acb);
return NULL;
}
@@ -487,6 +572,8 @@ iscsi_aio_flush(BlockDriverState *bs,
return &acb->common;
}
+static int iscsi_aio_discard_acb(IscsiAIOCB *acb);
+
static void
iscsi_unmap_cb(struct iscsi_context *iscsi, int status,
void *command_data, void *opaque)
@@ -498,7 +585,19 @@ iscsi_unmap_cb(struct iscsi_context *iscsi, int status,
}
acb->status = 0;
- if (status < 0) {
+ if (status != 0) {
+ if (status == SCSI_STATUS_CHECK_CONDITION
+ && acb->task->sense.key == SCSI_SENSE_UNIT_ATTENTION
+ && acb->retries-- > 0) {
+ if (acb->task != NULL) {
+ scsi_free_scsi_task(acb->task);
+ acb->task = NULL;
+ }
+ if (iscsi_aio_discard_acb(acb) == 0) {
+ iscsi_set_events(acb->iscsilun);
+ return;
+ }
+ }
error_report("Failed to unmap data on iSCSI lun. %s",
iscsi_get_error(iscsi));
acb->status = -EIO;
@@ -507,34 +606,50 @@ iscsi_unmap_cb(struct iscsi_context *iscsi, int status,
iscsi_schedule_bh(acb);
}
-static BlockDriverAIOCB *
-iscsi_aio_discard(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- IscsiLun *iscsilun = bs->opaque;
- struct iscsi_context *iscsi = iscsilun->iscsi;
- IscsiAIOCB *acb;
+static int iscsi_aio_discard_acb(IscsiAIOCB *acb) {
+ struct iscsi_context *iscsi = acb->iscsilun->iscsi;
struct unmap_list list[1];
- acb = qemu_aio_get(&iscsi_aiocb_info, bs, cb, opaque);
-
- acb->iscsilun = iscsilun;
acb->canceled = 0;
acb->bh = NULL;
acb->status = -EINPROGRESS;
acb->buf = NULL;
- list[0].lba = sector_qemu2lun(sector_num, iscsilun);
- list[0].num = nb_sectors * BDRV_SECTOR_SIZE / iscsilun->block_size;
+ list[0].lba = sector_qemu2lun(acb->sector_num, acb->iscsilun);
+ list[0].num = acb->nb_sectors * BDRV_SECTOR_SIZE / acb->iscsilun->block_size;
- acb->task = iscsi_unmap_task(iscsi, iscsilun->lun,
+ acb->task = iscsi_unmap_task(iscsi, acb->iscsilun->lun,
0, 0, &list[0], 1,
iscsi_unmap_cb,
acb);
if (acb->task == NULL) {
error_report("iSCSI: Failed to send unmap command. %s",
iscsi_get_error(iscsi));
+ return -1;
+ }
+
+ return 0;
+}
+
+static BlockDriverAIOCB *
+iscsi_aio_discard(BlockDriverState *bs,
+ int64_t sector_num, int nb_sectors,
+ BlockDriverCompletionFunc *cb, void *opaque)
+{
+ IscsiLun *iscsilun = bs->opaque;
+ IscsiAIOCB *acb;
+
+ acb = qemu_aio_get(&iscsi_aiocb_info, bs, cb, opaque);
+
+ acb->iscsilun = iscsilun;
+ acb->nb_sectors = nb_sectors;
+ acb->sector_num = sector_num;
+ acb->retries = ISCSI_CMD_RETRIES;
+
+ if (iscsi_aio_discard_acb(acb) != 0) {
+ if (acb->task) {
+ scsi_free_scsi_task(acb->task);
+ }
qemu_aio_release(acb);
return NULL;
}
@@ -823,6 +938,71 @@ static void iscsi_nop_timed_event(void *opaque)
}
#endif
+static int iscsi_readcapacity_sync(IscsiLun *iscsilun)
+{
+ struct scsi_task *task = NULL;
+ struct scsi_readcapacity10 *rc10 = NULL;
+ struct scsi_readcapacity16 *rc16 = NULL;
+ int ret = 0;
+ int retries = ISCSI_CMD_RETRIES;
+
+try_again:
+ switch (iscsilun->type) {
+ case TYPE_DISK:
+ task = iscsi_readcapacity16_sync(iscsilun->iscsi, iscsilun->lun);
+ if (task == NULL || task->status != SCSI_STATUS_GOOD) {
+ if (task != NULL && task->status == SCSI_STATUS_CHECK_CONDITION
+ && task->sense.key == SCSI_SENSE_UNIT_ATTENTION
+ && retries-- > 0) {
+ scsi_free_scsi_task(task);
+ goto try_again;
+ }
+ error_report("iSCSI: failed to send readcapacity16 command.");
+ ret = -EINVAL;
+ goto out;
+ }
+ rc16 = scsi_datain_unmarshall(task);
+ if (rc16 == NULL) {
+ error_report("iSCSI: Failed to unmarshall readcapacity16 data.");
+ ret = -EINVAL;
+ goto out;
+ }
+ iscsilun->block_size = rc16->block_length;
+ iscsilun->num_blocks = rc16->returned_lba + 1;
+ break;
+ case TYPE_ROM:
+ task = iscsi_readcapacity10_sync(iscsilun->iscsi, iscsilun->lun, 0, 0);
+ if (task == NULL || task->status != SCSI_STATUS_GOOD) {
+ error_report("iSCSI: failed to send readcapacity10 command.");
+ ret = -EINVAL;
+ goto out;
+ }
+ rc10 = scsi_datain_unmarshall(task);
+ if (rc10 == NULL) {
+ error_report("iSCSI: Failed to unmarshall readcapacity10 data.");
+ ret = -EINVAL;
+ goto out;
+ }
+ iscsilun->block_size = rc10->block_size;
+ if (rc10->lba == 0) {
+ /* blank disk loaded */
+ iscsilun->num_blocks = 0;
+ } else {
+ iscsilun->num_blocks = rc10->lba + 1;
+ }
+ break;
+ default:
+ break;
+ }
+
+out:
+ if (task) {
+ scsi_free_scsi_task(task);
+ }
+
+ return ret;
+}
+
/*
* We support iscsi url's on the form
* iscsi://[<username>%<password>@]<host>[:<port>]/<targetname>/<lun>
@@ -834,8 +1014,6 @@ static int iscsi_open(BlockDriverState *bs, const char *filename, int flags)
struct iscsi_url *iscsi_url = NULL;
struct scsi_task *task = NULL;
struct scsi_inquiry_standard *inq = NULL;
- struct scsi_readcapacity10 *rc10 = NULL;
- struct scsi_readcapacity16 *rc16 = NULL;
char *initiator_name = NULL;
int ret;
@@ -925,50 +1103,9 @@ static int iscsi_open(BlockDriverState *bs, const char *filename, int flags)
iscsilun->type = inq->periperal_device_type;
- scsi_free_scsi_task(task);
-
- switch (iscsilun->type) {
- case TYPE_DISK:
- task = iscsi_readcapacity16_sync(iscsi, iscsilun->lun);
- if (task == NULL || task->status != SCSI_STATUS_GOOD) {
- error_report("iSCSI: failed to send readcapacity16 command.");
- ret = -EINVAL;
- goto out;
- }
- rc16 = scsi_datain_unmarshall(task);
- if (rc16 == NULL) {
- error_report("iSCSI: Failed to unmarshall readcapacity16 data.");
- ret = -EINVAL;
- goto out;
- }
- iscsilun->block_size = rc16->block_length;
- iscsilun->num_blocks = rc16->returned_lba + 1;
- break;
- case TYPE_ROM:
- task = iscsi_readcapacity10_sync(iscsi, iscsilun->lun, 0, 0);
- if (task == NULL || task->status != SCSI_STATUS_GOOD) {
- error_report("iSCSI: failed to send readcapacity10 command.");
- ret = -EINVAL;
- goto out;
- }
- rc10 = scsi_datain_unmarshall(task);
- if (rc10 == NULL) {
- error_report("iSCSI: Failed to unmarshall readcapacity10 data.");
- ret = -EINVAL;
- goto out;
- }
- iscsilun->block_size = rc10->block_size;
- if (rc10->lba == 0) {
- /* blank disk loaded */
- iscsilun->num_blocks = 0;
- } else {
- iscsilun->num_blocks = rc10->lba + 1;
- }
- break;
- default:
- break;
+ if ((ret = iscsi_readcapacity_sync(iscsilun)) != 0) {
+ goto out;
}
-
bs->total_sectors = iscsilun->num_blocks *
iscsilun->block_size / BDRV_SECTOR_SIZE ;
@@ -981,8 +1118,6 @@ static int iscsi_open(BlockDriverState *bs, const char *filename, int flags)
bs->sg = 1;
}
- ret = 0;
-
#if defined(LIBISCSI_FEATURE_NOP_COUNTER)
/* Set up a timer for sending out iSCSI NOPs */
iscsilun->nop_timer = qemu_new_timer_ms(rt_clock, iscsi_nop_timed_event, iscsilun);
@@ -1023,6 +1158,26 @@ static void iscsi_close(BlockDriverState *bs)
memset(iscsilun, 0, sizeof(IscsiLun));
}
+static int iscsi_truncate(BlockDriverState *bs, int64_t offset)
+{
+ IscsiLun *iscsilun = bs->opaque;
+ int ret = 0;
+
+ if (iscsilun->type != TYPE_DISK) {
+ return -ENOTSUP;
+ }
+
+ if ((ret = iscsi_readcapacity_sync(iscsilun)) != 0) {
+ return ret;
+ }
+
+ if (offset > iscsi_getlength(bs)) {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static int iscsi_has_zero_init(BlockDriverState *bs)
{
return 0;
@@ -1093,6 +1248,7 @@ static BlockDriver bdrv_iscsi = {
.create_options = iscsi_create_options,
.bdrv_getlength = iscsi_getlength,
+ .bdrv_truncate = iscsi_truncate,
.bdrv_aio_readv = iscsi_aio_readv,
.bdrv_aio_writev = iscsi_aio_writev,
diff --git a/block/sheepdog.c b/block/sheepdog.c
index d466b232d7..c711c28613 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -13,6 +13,7 @@
*/
#include "qemu-common.h"
+#include "qemu/uri.h"
#include "qemu/error-report.h"
#include "qemu/sockets.h"
#include "block/block_int.h"
@@ -21,7 +22,7 @@
#define SD_PROTO_VER 0x01
#define SD_DEFAULT_ADDR "localhost"
-#define SD_DEFAULT_PORT "7000"
+#define SD_DEFAULT_PORT 7000
#define SD_OP_CREATE_AND_WRITE_OBJ 0x01
#define SD_OP_READ_OBJ 0x02
@@ -297,8 +298,8 @@ typedef struct BDRVSheepdogState {
bool is_snapshot;
uint32_t cache_flags;
- char *addr;
- char *port;
+ char *host_spec;
+ bool is_unix;
int fd;
CoMutex lock;
@@ -446,56 +447,29 @@ static SheepdogAIOCB *sd_aio_setup(BlockDriverState *bs, QEMUIOVector *qiov,
return acb;
}
-static int connect_to_sdog(const char *addr, const char *port)
+static int connect_to_sdog(BDRVSheepdogState *s)
{
- char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
- int fd, ret;
- struct addrinfo hints, *res, *res0;
-
- if (!addr) {
- addr = SD_DEFAULT_ADDR;
- port = SD_DEFAULT_PORT;
- }
-
- memset(&hints, 0, sizeof(hints));
- hints.ai_socktype = SOCK_STREAM;
-
- ret = getaddrinfo(addr, port, &hints, &res0);
- if (ret) {
- error_report("unable to get address info %s, %s",
- addr, strerror(errno));
- return -errno;
- }
-
- for (res = res0; res; res = res->ai_next) {
- ret = getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf),
- sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV);
- if (ret) {
- continue;
- }
+ int fd;
+ Error *err = NULL;
- fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
- if (fd < 0) {
- continue;
- }
+ if (s->is_unix) {
+ fd = unix_connect(s->host_spec, &err);
+ } else {
+ fd = inet_connect(s->host_spec, &err);
- reconnect:
- ret = connect(fd, res->ai_addr, res->ai_addrlen);
- if (ret < 0) {
- if (errno == EINTR) {
- goto reconnect;
+ if (err == NULL) {
+ int ret = socket_set_nodelay(fd);
+ if (ret < 0) {
+ error_report("%s", strerror(errno));
}
- close(fd);
- break;
}
+ }
- dprintf("connected to %s:%s\n", addr, port);
- goto success;
+ if (err != NULL) {
+ qerror_report_err(err);
+ error_free(err);
}
- fd = -errno;
- error_report("failed connect to %s:%s", addr, port);
-success:
- freeaddrinfo(res0);
+
return fd;
}
@@ -787,15 +761,6 @@ static int aio_flush_request(void *opaque)
!QLIST_EMPTY(&s->pending_aio_head);
}
-static int set_nodelay(int fd)
-{
- int ret, opt;
-
- opt = 1;
- ret = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&opt, sizeof(opt));
- return ret;
-}
-
/*
* Return a socket discriptor to read/write objects.
*
@@ -804,29 +769,88 @@ static int set_nodelay(int fd)
*/
static int get_sheep_fd(BDRVSheepdogState *s)
{
- int ret, fd;
+ int fd;
- fd = connect_to_sdog(s->addr, s->port);
+ fd = connect_to_sdog(s);
if (fd < 0) {
- error_report("%s", strerror(errno));
return fd;
}
socket_set_nonblock(fd);
- ret = set_nodelay(fd);
- if (ret) {
- error_report("%s", strerror(errno));
- closesocket(fd);
- return -errno;
- }
-
qemu_aio_set_fd_handler(fd, co_read_response, NULL, aio_flush_request, s);
return fd;
}
+static int sd_parse_uri(BDRVSheepdogState *s, const char *filename,
+ char *vdi, uint32_t *snapid, char *tag)
+{
+ URI *uri;
+ QueryParams *qp = NULL;
+ int ret = 0;
+
+ uri = uri_parse(filename);
+ if (!uri) {
+ return -EINVAL;
+ }
+
+ /* transport */
+ if (!strcmp(uri->scheme, "sheepdog")) {
+ s->is_unix = false;
+ } else if (!strcmp(uri->scheme, "sheepdog+tcp")) {
+ s->is_unix = false;
+ } else if (!strcmp(uri->scheme, "sheepdog+unix")) {
+ s->is_unix = true;
+ } else {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (uri->path == NULL || !strcmp(uri->path, "/")) {
+ ret = -EINVAL;
+ goto out;
+ }
+ pstrcpy(vdi, SD_MAX_VDI_LEN, uri->path + 1);
+
+ qp = query_params_parse(uri->query);
+ if (qp->n > 1 || (s->is_unix && !qp->n) || (!s->is_unix && qp->n)) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (s->is_unix) {
+ /* sheepdog+unix:///vdiname?socket=path */
+ if (uri->server || uri->port || strcmp(qp->p[0].name, "socket")) {
+ ret = -EINVAL;
+ goto out;
+ }
+ s->host_spec = g_strdup(qp->p[0].value);
+ } else {
+ /* sheepdog[+tcp]://[host:port]/vdiname */
+ s->host_spec = g_strdup_printf("%s:%d", uri->server ?: SD_DEFAULT_ADDR,
+ uri->port ?: SD_DEFAULT_PORT);
+ }
+
+ /* snapshot tag */
+ if (uri->fragment) {
+ *snapid = strtoul(uri->fragment, NULL, 10);
+ if (*snapid == 0) {
+ pstrcpy(tag, SD_MAX_VDI_TAG_LEN, uri->fragment);
+ }
+ } else {
+ *snapid = CURRENT_VDI_ID; /* search current vdi */
+ }
+
+out:
+ if (qp) {
+ query_params_free(qp);
+ }
+ uri_free(uri);
+ return ret;
+}
+
/*
- * Parse a filename
+ * Parse a filename (old syntax)
*
* filename must be one of the following formats:
* 1. [vdiname]
@@ -845,9 +869,11 @@ static int get_sheep_fd(BDRVSheepdogState *s)
static int parse_vdiname(BDRVSheepdogState *s, const char *filename,
char *vdi, uint32_t *snapid, char *tag)
{
- char *p, *q;
- int nr_sep;
+ char *p, *q, *uri;
+ const char *host_spec, *vdi_spec;
+ int nr_sep, ret;
+ strstart(filename, "sheepdog:", (const char **)&filename);
p = q = g_strdup(filename);
/* count the number of separators */
@@ -860,38 +886,32 @@ static int parse_vdiname(BDRVSheepdogState *s, const char *filename,
}
p = q;
- /* use the first two tokens as hostname and port number. */
+ /* use the first two tokens as host_spec. */
if (nr_sep >= 2) {
- s->addr = p;
+ host_spec = p;
p = strchr(p, ':');
- *p++ = '\0';
-
- s->port = p;
+ p++;
p = strchr(p, ':');
*p++ = '\0';
} else {
- s->addr = NULL;
- s->port = 0;
+ host_spec = "";
}
- pstrcpy(vdi, SD_MAX_VDI_LEN, p);
+ vdi_spec = p;
- p = strchr(vdi, ':');
+ p = strchr(vdi_spec, ':');
if (p) {
- *p++ = '\0';
- *snapid = strtoul(p, NULL, 10);
- if (*snapid == 0) {
- pstrcpy(tag, SD_MAX_VDI_TAG_LEN, p);
- }
- } else {
- *snapid = CURRENT_VDI_ID; /* search current vdi */
+ *p++ = '#';
}
- if (s->addr == NULL) {
- g_free(q);
- }
+ uri = g_strdup_printf("sheepdog://%s/%s", host_spec, vdi_spec);
- return 0;
+ ret = sd_parse_uri(s, uri, vdi, snapid, tag);
+
+ g_free(q);
+ g_free(uri);
+
+ return ret;
}
static int find_vdi_name(BDRVSheepdogState *s, char *filename, uint32_t snapid,
@@ -903,7 +923,7 @@ static int find_vdi_name(BDRVSheepdogState *s, char *filename, uint32_t snapid,
unsigned int wlen, rlen = 0;
char buf[SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN];
- fd = connect_to_sdog(s->addr, s->port);
+ fd = connect_to_sdog(s);
if (fd < 0) {
return fd;
}
@@ -1106,16 +1126,19 @@ static int sd_open(BlockDriverState *bs, const char *filename, int flags)
uint32_t snapid;
char *buf = NULL;
- strstart(filename, "sheepdog:", (const char **)&filename);
-
QLIST_INIT(&s->inflight_aio_head);
QLIST_INIT(&s->pending_aio_head);
s->fd = -1;
memset(vdi, 0, sizeof(vdi));
memset(tag, 0, sizeof(tag));
- if (parse_vdiname(s, filename, vdi, &snapid, tag) < 0) {
- ret = -EINVAL;
+
+ if (strstr(filename, "://")) {
+ ret = sd_parse_uri(s, filename, vdi, &snapid, tag);
+ } else {
+ ret = parse_vdiname(s, filename, vdi, &snapid, tag);
+ }
+ if (ret < 0) {
goto out;
}
s->fd = get_sheep_fd(s);
@@ -1143,9 +1166,8 @@ static int sd_open(BlockDriverState *bs, const char *filename, int flags)
s->is_snapshot = true;
}
- fd = connect_to_sdog(s->addr, s->port);
+ fd = connect_to_sdog(s);
if (fd < 0) {
- error_report("failed to connect");
ret = fd;
goto out;
}
@@ -1178,9 +1200,8 @@ out:
return ret;
}
-static int do_sd_create(char *filename, int64_t vdi_size,
- uint32_t base_vid, uint32_t *vdi_id, int snapshot,
- const char *addr, const char *port)
+static int do_sd_create(BDRVSheepdogState *s, char *filename, int64_t vdi_size,
+ uint32_t base_vid, uint32_t *vdi_id, int snapshot)
{
SheepdogVdiReq hdr;
SheepdogVdiRsp *rsp = (SheepdogVdiRsp *)&hdr;
@@ -1188,7 +1209,7 @@ static int do_sd_create(char *filename, int64_t vdi_size,
unsigned int wlen, rlen = 0;
char buf[SD_MAX_VDI_LEN];
- fd = connect_to_sdog(addr, port);
+ fd = connect_to_sdog(s);
if (fd < 0) {
return fd;
}
@@ -1284,17 +1305,17 @@ static int sd_create(const char *filename, QEMUOptionParameter *options)
char vdi[SD_MAX_VDI_LEN], tag[SD_MAX_VDI_TAG_LEN];
uint32_t snapid;
bool prealloc = false;
- const char *vdiname;
s = g_malloc0(sizeof(BDRVSheepdogState));
- strstart(filename, "sheepdog:", &vdiname);
-
memset(vdi, 0, sizeof(vdi));
memset(tag, 0, sizeof(tag));
- if (parse_vdiname(s, vdiname, vdi, &snapid, tag) < 0) {
- error_report("invalid filename");
- ret = -EINVAL;
+ if (strstr(filename, "://")) {
+ ret = sd_parse_uri(s, filename, vdi, &snapid, tag);
+ } else {
+ ret = parse_vdiname(s, filename, vdi, &snapid, tag);
+ }
+ if (ret < 0) {
goto out;
}
@@ -1355,7 +1376,7 @@ static int sd_create(const char *filename, QEMUOptionParameter *options)
bdrv_delete(bs);
}
- ret = do_sd_create(vdi, vdi_size, base_vid, &vid, 0, s->addr, s->port);
+ ret = do_sd_create(s, vdi, vdi_size, base_vid, &vid, 0);
if (!prealloc || ret) {
goto out;
}
@@ -1376,7 +1397,7 @@ static void sd_close(BlockDriverState *bs)
dprintf("%s\n", s->name);
- fd = connect_to_sdog(s->addr, s->port);
+ fd = connect_to_sdog(s);
if (fd < 0) {
return;
}
@@ -1400,7 +1421,7 @@ static void sd_close(BlockDriverState *bs)
qemu_aio_set_fd_handler(s->fd, NULL, NULL, NULL, NULL);
closesocket(s->fd);
- g_free(s->addr);
+ g_free(s->host_spec);
}
static int64_t sd_getlength(BlockDriverState *bs)
@@ -1424,7 +1445,7 @@ static int sd_truncate(BlockDriverState *bs, int64_t offset)
return -EINVAL;
}
- fd = connect_to_sdog(s->addr, s->port);
+ fd = connect_to_sdog(s);
if (fd < 0) {
return fd;
}
@@ -1500,17 +1521,15 @@ static int sd_create_branch(BDRVSheepdogState *s)
buf = g_malloc(SD_INODE_SIZE);
- ret = do_sd_create(s->name, s->inode.vdi_size, s->inode.vdi_id, &vid, 1,
- s->addr, s->port);
+ ret = do_sd_create(s, s->name, s->inode.vdi_size, s->inode.vdi_id, &vid, 1);
if (ret) {
goto out;
}
dprintf("%" PRIx32 " is created.\n", vid);
- fd = connect_to_sdog(s->addr, s->port);
+ fd = connect_to_sdog(s);
if (fd < 0) {
- error_report("failed to connect");
ret = fd;
goto out;
}
@@ -1769,7 +1788,7 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
datalen = SD_INODE_SIZE - sizeof(s->inode.data_vdi_id);
/* refresh inode. */
- fd = connect_to_sdog(s->addr, s->port);
+ fd = connect_to_sdog(s);
if (fd < 0) {
ret = fd;
goto cleanup;
@@ -1782,8 +1801,8 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
goto cleanup;
}
- ret = do_sd_create(s->name, s->inode.vdi_size, s->inode.vdi_id, &new_vid, 1,
- s->addr, s->port);
+ ret = do_sd_create(s, s->name, s->inode.vdi_size, s->inode.vdi_id, &new_vid,
+ 1);
if (ret < 0) {
error_report("failed to create inode for snapshot. %s",
strerror(errno));
@@ -1838,9 +1857,8 @@ static int sd_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
goto out;
}
- fd = connect_to_sdog(s->addr, s->port);
+ fd = connect_to_sdog(s);
if (fd < 0) {
- error_report("failed to connect");
ret = fd;
goto out;
}
@@ -1902,7 +1920,7 @@ static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)
vdi_inuse = g_malloc(max);
- fd = connect_to_sdog(s->addr, s->port);
+ fd = connect_to_sdog(s);
if (fd < 0) {
ret = fd;
goto out;
@@ -1929,9 +1947,8 @@ static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)
hval = fnv_64a_buf(s->name, strlen(s->name), FNV1A_64_INIT);
start_nr = hval & (SD_NR_VDIS - 1);
- fd = connect_to_sdog(s->addr, s->port);
+ fd = connect_to_sdog(s);
if (fd < 0) {
- error_report("failed to connect");
ret = fd;
goto out;
}
@@ -1988,7 +2005,7 @@ static int do_load_save_vmstate(BDRVSheepdogState *s, uint8_t *data,
uint32_t vdi_index;
uint64_t offset;
- fd = connect_to_sdog(s->addr, s->port);
+ fd = connect_to_sdog(s);
if (fd < 0) {
return fd;
}
@@ -2063,7 +2080,7 @@ static QEMUOptionParameter sd_create_options[] = {
{ NULL }
};
-BlockDriver bdrv_sheepdog = {
+static BlockDriver bdrv_sheepdog = {
.format_name = "sheepdog",
.protocol_name = "sheepdog",
.instance_size = sizeof(BDRVSheepdogState),
@@ -2088,8 +2105,60 @@ BlockDriver bdrv_sheepdog = {
.create_options = sd_create_options,
};
+static BlockDriver bdrv_sheepdog_tcp = {
+ .format_name = "sheepdog",
+ .protocol_name = "sheepdog+tcp",
+ .instance_size = sizeof(BDRVSheepdogState),
+ .bdrv_file_open = sd_open,
+ .bdrv_close = sd_close,
+ .bdrv_create = sd_create,
+ .bdrv_getlength = sd_getlength,
+ .bdrv_truncate = sd_truncate,
+
+ .bdrv_co_readv = sd_co_readv,
+ .bdrv_co_writev = sd_co_writev,
+ .bdrv_co_flush_to_disk = sd_co_flush_to_disk,
+
+ .bdrv_snapshot_create = sd_snapshot_create,
+ .bdrv_snapshot_goto = sd_snapshot_goto,
+ .bdrv_snapshot_delete = sd_snapshot_delete,
+ .bdrv_snapshot_list = sd_snapshot_list,
+
+ .bdrv_save_vmstate = sd_save_vmstate,
+ .bdrv_load_vmstate = sd_load_vmstate,
+
+ .create_options = sd_create_options,
+};
+
+static BlockDriver bdrv_sheepdog_unix = {
+ .format_name = "sheepdog",
+ .protocol_name = "sheepdog+unix",
+ .instance_size = sizeof(BDRVSheepdogState),
+ .bdrv_file_open = sd_open,
+ .bdrv_close = sd_close,
+ .bdrv_create = sd_create,
+ .bdrv_getlength = sd_getlength,
+ .bdrv_truncate = sd_truncate,
+
+ .bdrv_co_readv = sd_co_readv,
+ .bdrv_co_writev = sd_co_writev,
+ .bdrv_co_flush_to_disk = sd_co_flush_to_disk,
+
+ .bdrv_snapshot_create = sd_snapshot_create,
+ .bdrv_snapshot_goto = sd_snapshot_goto,
+ .bdrv_snapshot_delete = sd_snapshot_delete,
+ .bdrv_snapshot_list = sd_snapshot_list,
+
+ .bdrv_save_vmstate = sd_save_vmstate,
+ .bdrv_load_vmstate = sd_load_vmstate,
+
+ .create_options = sd_create_options,
+};
+
static void bdrv_sheepdog_init(void)
{
bdrv_register(&bdrv_sheepdog);
+ bdrv_register(&bdrv_sheepdog_tcp);
+ bdrv_register(&bdrv_sheepdog_unix);
}
block_init(bdrv_sheepdog_init);
diff --git a/configure b/configure
index ae3d9c5378..84317c6826 100755
--- a/configure
+++ b/configure
@@ -986,6 +986,10 @@ microblaze-linux-user \
microblazeel-linux-user \
mips-linux-user \
mipsel-linux-user \
+mips64-linux-user \
+mips64el-linux-user \
+mipsn32-linux-user \
+mipsn32el-linux-user \
or32-linux-user \
ppc-linux-user \
ppc64-linux-user \
@@ -2800,7 +2804,13 @@ if test "$libiscsi" != "no" ; then
#include <iscsi/iscsi.h>
int main(void) { iscsi_unmap_sync(NULL,0,0,0,NULL,0); return 0; }
EOF
- if compile_prog "" "-liscsi" ; then
+ if $pkg_config --atleast-version=1.7.0 libiscsi --modversion >/dev/null 2>&1; then
+ libiscsi="yes"
+ libiscsi_cflags=$($pkg_config --cflags libiscsi 2>/dev/null)
+ libiscsi_libs=$($pkg_config --libs libiscsi 2>/dev/null)
+ CFLAGS="$CFLAGS $libiscsi_cflags"
+ LIBS="$LIBS $libiscsi_libs"
+ elif compile_prog "" "-liscsi" ; then
libiscsi="yes"
LIBS="$LIBS -liscsi"
else
@@ -2868,7 +2878,7 @@ EOF
spice_cflags=$($pkg_config --cflags spice-protocol spice-server 2>/dev/null)
spice_libs=$($pkg_config --libs spice-protocol spice-server 2>/dev/null)
if $pkg_config --atleast-version=0.12.0 spice-server >/dev/null 2>&1 && \
- $pkg_config --atleast-version=0.12.2 spice-protocol > /dev/null 2>&1 && \
+ $pkg_config --atleast-version=0.12.3 spice-protocol > /dev/null 2>&1 && \
compile_prog "$spice_cflags" "$spice_libs" ; then
spice="yes"
libs_softmmu="$libs_softmmu $spice_libs"
@@ -4007,9 +4017,10 @@ case "$target_arch2" in
target_nptl="yes"
;;
mipsn32|mipsn32el)
- TARGET_ARCH=mipsn32
+ TARGET_ARCH=mips64
TARGET_BASE_ARCH=mips
echo "TARGET_ABI_MIPSN32=y" >> $config_target_mak
+ echo "TARGET_ABI32=y" >> $config_target_mak
;;
mips64|mips64el)
TARGET_ARCH=mips64
@@ -4124,7 +4135,7 @@ case "$target_arch2" in
echo "CONFIG_NO_XEN=y" >> $config_target_mak
esac
case "$target_arch2" in
- i386|x86_64|ppcemb|ppc|ppc64|s390x)
+ arm|i386|x86_64|ppcemb|ppc|ppc64|s390x)
# Make sure the target and host cpus are compatible
if test "$kvm" = "yes" -a "$target_softmmu" = "yes" -a \
\( "$target_arch2" = "$cpu" -o \
@@ -4356,6 +4367,7 @@ FILES="$FILES tests/tcg/lm32/Makefile po/Makefile"
FILES="$FILES pc-bios/optionrom/Makefile pc-bios/keymaps"
FILES="$FILES pc-bios/spapr-rtas/Makefile"
FILES="$FILES roms/seabios/Makefile roms/vgabios/Makefile"
+FILES="$FILES pc-bios/qemu-icon.bmp"
for bios_file in \
$source_path/pc-bios/*.bin \
$source_path/pc-bios/*.aml \
diff --git a/cpu-exec.c b/cpu-exec.c
index afbe4977ab..9092145d0b 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -51,13 +51,34 @@ void cpu_resume_from_signal(CPUArchState *env, void *puc)
}
#endif
+/* Execute a TB, and fix up the CPU state afterwards if necessary */
+static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, uint8_t *tb_ptr)
+{
+ CPUArchState *env = cpu->env_ptr;
+ tcg_target_ulong next_tb = tcg_qemu_tb_exec(env, tb_ptr);
+ if ((next_tb & TB_EXIT_MASK) > TB_EXIT_IDX1) {
+ /* We didn't start executing this TB (eg because the instruction
+ * counter hit zero); we must restore the guest PC to the address
+ * of the start of the TB.
+ */
+ TranslationBlock *tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
+ cpu_pc_from_tb(env, tb);
+ }
+ if ((next_tb & TB_EXIT_MASK) == TB_EXIT_REQUESTED) {
+ /* We were asked to stop executing TBs (probably a pending
+ * interrupt. We've now stopped, so clear the flag.
+ */
+ cpu->tcg_exit_req = 0;
+ }
+ return next_tb;
+}
+
/* Execute the code without caching the generated code. An interpreter
could be used if available. */
static void cpu_exec_nocache(CPUArchState *env, int max_cycles,
TranslationBlock *orig_tb)
{
CPUState *cpu = ENV_GET_CPU(env);
- tcg_target_ulong next_tb;
TranslationBlock *tb;
/* Should never happen.
@@ -69,14 +90,8 @@ static void cpu_exec_nocache(CPUArchState *env, int max_cycles,
max_cycles);
cpu->current_tb = tb;
/* execute the generated code */
- next_tb = tcg_qemu_tb_exec(env, tb->tc_ptr);
+ cpu_tb_exec(cpu, tb->tc_ptr);
cpu->current_tb = NULL;
-
- if ((next_tb & 3) == 2) {
- /* Restore PC. This may happen if async event occurs before
- the TB starts executing. */
- cpu_pc_from_tb(env, tb);
- }
tb_phys_invalidate(tb, -1);
tb_free(tb);
}
@@ -584,7 +599,8 @@ int cpu_exec(CPUArchState *env)
spans two pages, we cannot safely do a direct
jump. */
if (next_tb != 0 && tb->page_addr[1] == -1) {
- tb_add_jump((TranslationBlock *)(next_tb & ~3), next_tb & 3, tb);
+ tb_add_jump((TranslationBlock *)(next_tb & ~TB_EXIT_MASK),
+ next_tb & TB_EXIT_MASK, tb);
}
spin_unlock(&tcg_ctx.tb_ctx.tb_lock);
@@ -597,13 +613,24 @@ int cpu_exec(CPUArchState *env)
if (likely(!cpu->exit_request)) {
tc_ptr = tb->tc_ptr;
/* execute the generated code */
- next_tb = tcg_qemu_tb_exec(env, tc_ptr);
- if ((next_tb & 3) == 2) {
+ next_tb = cpu_tb_exec(cpu, tc_ptr);
+ switch (next_tb & TB_EXIT_MASK) {
+ case TB_EXIT_REQUESTED:
+ /* Something asked us to stop executing
+ * chained TBs; just continue round the main
+ * loop. Whatever requested the exit will also
+ * have set something else (eg exit_request or
+ * interrupt_request) which we will handle
+ * next time around the loop.
+ */
+ tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
+ next_tb = 0;
+ break;
+ case TB_EXIT_ICOUNT_EXPIRED:
+ {
/* Instruction counter expired. */
int insns_left;
- tb = (TranslationBlock *)(next_tb & ~3);
- /* Restore PC. */
- cpu_pc_from_tb(env, tb);
+ tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
insns_left = env->icount_decr.u32;
if (env->icount_extra && insns_left >= 0) {
/* Refill decrementer and continue execution. */
@@ -624,6 +651,10 @@ int cpu_exec(CPUArchState *env)
next_tb = 0;
cpu_loop_exit(env);
}
+ break;
+ }
+ default:
+ break;
}
}
cpu->current_tb = NULL;
diff --git a/exec.c b/exec.c
index a41bcb8694..46a283071a 100644
--- a/exec.c
+++ b/exec.c
@@ -495,7 +495,7 @@ void cpu_exit(CPUArchState *env)
CPUState *cpu = ENV_GET_CPU(env);
cpu->exit_request = 1;
- cpu_unlink_tb(cpu);
+ cpu->tcg_exit_req = 1;
}
void cpu_abort(CPUArchState *env, const char *fmt, ...)
diff --git a/gdbstub.c b/gdbstub.c
index 32dfea9ed0..e414ad9157 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2841,7 +2841,7 @@ static void gdb_accept(void)
GDBState *s;
struct sockaddr_in sockaddr;
socklen_t len;
- int val, fd;
+ int fd;
for(;;) {
len = sizeof(sockaddr);
@@ -2858,8 +2858,7 @@ static void gdb_accept(void)
}
/* set short latency */
- val = 1;
- setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
+ socket_set_nodelay(fd);
s = g_malloc0(sizeof(GDBState));
s->c_cpu = first_cpu;
diff --git a/hmp-commands.hx b/hmp-commands.hx
index cef7708e3a..69c707d332 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1169,7 +1169,7 @@ ETEXI
{
.name = "netdev_add",
.args_type = "netdev:O",
- .params = "[user|tap|socket],id=str[,prop=value][,...]",
+ .params = "[user|tap|socket|hubport],id=str[,prop=value][,...]",
.help = "add host network device",
.mhandler.cmd = hmp_netdev_add,
},
diff --git a/hw/a15mpcore.c b/hw/a15mpcore.c
index d973d53f0a..648656d5b4 100644
--- a/hw/a15mpcore.c
+++ b/hw/a15mpcore.c
@@ -19,6 +19,7 @@
*/
#include "hw/sysbus.h"
+#include "sysemu/kvm.h"
/* A15MP private memory region. */
@@ -40,8 +41,13 @@ static int a15mp_priv_init(SysBusDevice *dev)
{
A15MPPrivState *s = FROM_SYSBUS(A15MPPrivState, dev);
SysBusDevice *busdev;
+ const char *gictype = "arm_gic";
- s->gic = qdev_create(NULL, "arm_gic");
+ if (kvm_irqchip_in_kernel()) {
+ gictype = "kvm-arm-gic";
+ }
+
+ s->gic = qdev_create(NULL, gictype);
qdev_prop_set_uint32(s->gic, "num-cpu", s->num_cpu);
qdev_prop_set_uint32(s->gic, "num-irq", s->num_irq);
qdev_prop_set_uint32(s->gic, "revision", 2);
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index aebbc866e2..2d9c69dfce 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -23,6 +23,8 @@ obj-y += bitbang_i2c.o marvell_88w8618_audio.o
obj-y += framebuffer.o
obj-y += strongarm.o
obj-y += imx_serial.o imx_ccm.o imx_timer.o imx_avic.o
+obj-$(CONFIG_FDT) += ../device_tree.o
+obj-$(CONFIG_KVM) += kvm/arm_gic.o
obj-y := $(addprefix ../,$(obj-y))
diff --git a/hw/arm/pic_cpu.c b/hw/arm/pic_cpu.c
index a7ad893cc2..82236006d2 100644
--- a/hw/arm/pic_cpu.c
+++ b/hw/arm/pic_cpu.c
@@ -9,6 +9,7 @@
#include "hw/hw.h"
#include "hw/arm-misc.h"
+#include "sysemu/kvm.h"
/* Input 0 is IRQ and input 1 is FIQ. */
static void arm_pic_cpu_handler(void *opaque, int irq, int level)
@@ -34,7 +35,32 @@ static void arm_pic_cpu_handler(void *opaque, int irq, int level)
}
}
+static void kvm_arm_pic_cpu_handler(void *opaque, int irq, int level)
+{
+#ifdef CONFIG_KVM
+ ARMCPU *cpu = opaque;
+ CPUState *cs = CPU(cpu);
+ int kvm_irq = KVM_ARM_IRQ_TYPE_CPU << KVM_ARM_IRQ_TYPE_SHIFT;
+
+ switch (irq) {
+ case ARM_PIC_CPU_IRQ:
+ kvm_irq |= KVM_ARM_IRQ_CPU_IRQ;
+ break;
+ case ARM_PIC_CPU_FIQ:
+ kvm_irq |= KVM_ARM_IRQ_CPU_FIQ;
+ break;
+ default:
+ hw_error("kvm_arm_pic_cpu_handler: Bad interrupt line %d\n", irq);
+ }
+ kvm_irq |= cs->cpu_index << KVM_ARM_IRQ_VCPU_SHIFT;
+ kvm_set_irq(kvm_state, kvm_irq, level ? 1 : 0);
+#endif
+}
+
qemu_irq *arm_pic_init_cpu(ARMCPU *cpu)
{
+ if (kvm_enabled()) {
+ return qemu_allocate_irqs(kvm_arm_pic_cpu_handler, cpu, 2);
+ }
return qemu_allocate_irqs(arm_pic_cpu_handler, cpu, 2);
}
diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index 6b30e0bf42..bcb072bbcf 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -659,14 +659,18 @@ void gic_init_irqs_and_distributor(GICState *s, int num_irq)
memory_region_init_io(&s->iomem, &gic_dist_ops, s, "gic_dist", 0x1000);
}
-static int arm_gic_init(SysBusDevice *dev)
+static void arm_gic_realize(DeviceState *dev, Error **errp)
{
- /* Device instance init function for the GIC sysbus device */
+ /* Device instance realize function for the GIC sysbus device */
int i;
- GICState *s = FROM_SYSBUS(GICState, dev);
+ GICState *s = ARM_GIC(dev);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
ARMGICClass *agc = ARM_GIC_GET_CLASS(s);
- agc->parent_init(dev);
+ agc->parent_realize(dev, errp);
+ if (error_is_set(errp)) {
+ return;
+ }
gic_init_irqs_and_distributor(s, s->num_irq);
@@ -686,22 +690,21 @@ static int arm_gic_init(SysBusDevice *dev)
"gic_cpu", 0x100);
}
/* Distributor */
- sysbus_init_mmio(dev, &s->iomem);
+ sysbus_init_mmio(sbd, &s->iomem);
/* cpu interfaces (one for "current cpu" plus one per cpu) */
for (i = 0; i <= NUM_CPU(s); i++) {
- sysbus_init_mmio(dev, &s->cpuiomem[i]);
+ sysbus_init_mmio(sbd, &s->cpuiomem[i]);
}
- return 0;
}
static void arm_gic_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
ARMGICClass *agc = ARM_GIC_CLASS(klass);
- agc->parent_init = sbc->init;
- sbc->init = arm_gic_init;
+
dc->no_user = 1;
+ agc->parent_realize = dc->realize;
+ dc->realize = arm_gic_realize;
}
static const TypeInfo arm_gic_info = {
diff --git a/hw/arm_gic_common.c b/hw/arm_gic_common.c
index 745b4b2a0a..f2dc8bf555 100644
--- a/hw/arm_gic_common.c
+++ b/hw/arm_gic_common.c
@@ -23,9 +23,14 @@
static void gic_save(QEMUFile *f, void *opaque)
{
GICState *s = (GICState *)opaque;
+ ARMGICCommonClass *c = ARM_GIC_COMMON_GET_CLASS(s);
int i;
int j;
+ if (c->pre_save) {
+ c->pre_save(s);
+ }
+
qemu_put_be32(f, s->enabled);
for (i = 0; i < s->num_cpu; i++) {
qemu_put_be32(f, s->cpu_enabled[i]);
@@ -57,6 +62,7 @@ static void gic_save(QEMUFile *f, void *opaque)
static int gic_load(QEMUFile *f, void *opaque, int version_id)
{
GICState *s = (GICState *)opaque;
+ ARMGICCommonClass *c = ARM_GIC_COMMON_GET_CLASS(s);
int i;
int j;
@@ -91,34 +97,42 @@ static int gic_load(QEMUFile *f, void *opaque, int version_id)
s->irq_state[i].trigger = qemu_get_byte(f);
}
+ if (c->post_load) {
+ c->post_load(s);
+ }
+
return 0;
}
-static int arm_gic_common_init(SysBusDevice *dev)
+static void arm_gic_common_realize(DeviceState *dev, Error **errp)
{
- GICState *s = FROM_SYSBUS(GICState, dev);
+ GICState *s = ARM_GIC_COMMON(dev);
int num_irq = s->num_irq;
if (s->num_cpu > NCPU) {
- hw_error("requested %u CPUs exceeds GIC maximum %d\n",
- s->num_cpu, NCPU);
+ error_setg(errp, "requested %u CPUs exceeds GIC maximum %d",
+ s->num_cpu, NCPU);
+ return;
}
s->num_irq += GIC_BASE_IRQ;
if (s->num_irq > GIC_MAXIRQ) {
- hw_error("requested %u interrupt lines exceeds GIC maximum %d\n",
- num_irq, GIC_MAXIRQ);
+ error_setg(errp,
+ "requested %u interrupt lines exceeds GIC maximum %d",
+ num_irq, GIC_MAXIRQ);
+ return;
}
/* ITLinesNumber is represented as (N / 32) - 1 (see
* gic_dist_readb) so this is an implementation imposed
* restriction, not an architectural one:
*/
if (s->num_irq < 32 || (s->num_irq % 32)) {
- hw_error("%d interrupt lines unsupported: not divisible by 32\n",
- num_irq);
+ error_setg(errp,
+ "%d interrupt lines unsupported: not divisible by 32",
+ num_irq);
+ return;
}
register_savevm(NULL, "arm_gic", -1, 3, gic_save, gic_load, s);
- return 0;
}
static void arm_gic_common_reset(DeviceState *dev)
@@ -163,12 +177,12 @@ static Property arm_gic_common_properties[] = {
static void arm_gic_common_class_init(ObjectClass *klass, void *data)
{
- SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
+
dc->reset = arm_gic_common_reset;
+ dc->realize = arm_gic_common_realize;
dc->props = arm_gic_common_properties;
dc->no_user = 1;
- sc->init = arm_gic_common_init;
}
static const TypeInfo arm_gic_common_type = {
diff --git a/hw/arm_gic_internal.h b/hw/arm_gic_internal.h
index b10ac5e9f6..3e1928b7eb 100644
--- a/hw/arm_gic_internal.h
+++ b/hw/arm_gic_internal.h
@@ -118,6 +118,8 @@ void gic_init_irqs_and_distributor(GICState *s, int num_irq);
typedef struct ARMGICCommonClass {
SysBusDeviceClass parent_class;
+ void (*pre_save)(GICState *s);
+ void (*post_load)(GICState *s);
} ARMGICCommonClass;
#define TYPE_ARM_GIC "arm_gic"
@@ -130,7 +132,7 @@ typedef struct ARMGICCommonClass {
typedef struct ARMGICClass {
ARMGICCommonClass parent_class;
- int (*parent_init)(SysBusDevice *dev);
+ DeviceRealize parent_realize;
} ARMGICClass;
#endif /* !QEMU_ARM_GIC_INTERNAL_H */
diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
index 4d3042348b..d198cfd96e 100644
--- a/hw/armv7m_nvic.c
+++ b/hw/armv7m_nvic.c
@@ -41,7 +41,7 @@ typedef struct NVICClass {
/*< private >*/
ARMGICClass parent_class;
/*< public >*/
- int (*parent_init)(SysBusDevice *dev);
+ DeviceRealize parent_realize;
void (*parent_reset)(DeviceState *dev);
} NVICClass;
@@ -465,7 +465,7 @@ static void armv7m_nvic_reset(DeviceState *dev)
systick_reset(s);
}
-static int armv7m_nvic_init(SysBusDevice *dev)
+static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
{
nvic_state *s = NVIC(dev);
NVICClass *nc = NVIC_GET_CLASS(s);
@@ -475,7 +475,10 @@ static int armv7m_nvic_init(SysBusDevice *dev)
/* Tell the common code we're an NVIC */
s->gic.revision = 0xffffffff;
s->num_irq = s->gic.num_irq;
- nc->parent_init(dev);
+ nc->parent_realize(dev, errp);
+ if (error_is_set(errp)) {
+ return;
+ }
gic_init_irqs_and_distributor(&s->gic, s->num_irq);
/* The NVIC and system controller register area looks like this:
* 0..0xff : system control registers, including systick
@@ -503,7 +506,6 @@ static int armv7m_nvic_init(SysBusDevice *dev)
*/
memory_region_add_subregion(get_system_memory(), 0xe000e000, &s->container);
s->systick.timer = qemu_new_timer_ns(vm_clock, systick_timer_tick, s);
- return 0;
}
static void armv7m_nvic_instance_init(Object *obj)
@@ -526,13 +528,12 @@ static void armv7m_nvic_class_init(ObjectClass *klass, void *data)
{
NVICClass *nc = NVIC_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
nc->parent_reset = dc->reset;
- nc->parent_init = sdc->init;
- sdc->init = armv7m_nvic_init;
+ nc->parent_realize = dc->realize;
dc->vmsd = &vmstate_nvic;
dc->reset = armv7m_nvic_reset;
+ dc->realize = armv7m_nvic_realize;
}
static const TypeInfo armv7m_nvic_info = {
diff --git a/hw/dataplane/Makefile.objs b/hw/dataplane/Makefile.objs
index 3e47d0537e..701111ccb9 100644
--- a/hw/dataplane/Makefile.objs
+++ b/hw/dataplane/Makefile.objs
@@ -1 +1 @@
-obj-$(CONFIG_VIRTIO_BLK_DATA_PLANE) += hostmem.o vring.o event-poll.o ioq.o virtio-blk.o
+obj-$(CONFIG_VIRTIO_BLK_DATA_PLANE) += hostmem.o vring.o ioq.o virtio-blk.o
diff --git a/hw/dataplane/event-poll.c b/hw/dataplane/event-poll.c
deleted file mode 100644
index b98acf9aec..0000000000
--- a/hw/dataplane/event-poll.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Event loop with file descriptor polling
- *
- * Copyright 2012 IBM, Corp.
- * Copyright 2012 Red Hat, Inc. and/or its affiliates
- *
- * Authors:
- * Stefan Hajnoczi <stefanha@redhat.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-#include <sys/epoll.h>
-#include "event-poll.h"
-
-/* Add an event notifier and its callback for polling */
-void event_poll_add(EventPoll *poll, EventHandler *handler,
- EventNotifier *notifier, EventCallback *callback)
-{
- struct epoll_event event = {
- .events = EPOLLIN,
- .data.ptr = handler,
- };
- handler->notifier = notifier;
- handler->callback = callback;
- if (epoll_ctl(poll->epoll_fd, EPOLL_CTL_ADD,
- event_notifier_get_fd(notifier), &event) != 0) {
- fprintf(stderr, "failed to add event handler to epoll: %m\n");
- exit(1);
- }
-}
-
-/* Event callback for stopping event_poll() */
-static void handle_stop(EventHandler *handler)
-{
- /* Do nothing */
-}
-
-void event_poll_init(EventPoll *poll)
-{
- /* Create epoll file descriptor */
- poll->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
- if (poll->epoll_fd < 0) {
- fprintf(stderr, "epoll_create1 failed: %m\n");
- exit(1);
- }
-
- /* Set up stop notifier */
- if (event_notifier_init(&poll->stop_notifier, 0) < 0) {
- fprintf(stderr, "failed to init stop notifier\n");
- exit(1);
- }
- event_poll_add(poll, &poll->stop_handler,
- &poll->stop_notifier, handle_stop);
-}
-
-void event_poll_cleanup(EventPoll *poll)
-{
- event_notifier_cleanup(&poll->stop_notifier);
- close(poll->epoll_fd);
- poll->epoll_fd = -1;
-}
-
-/* Block until the next event and invoke its callback */
-void event_poll(EventPoll *poll)
-{
- EventHandler *handler;
- struct epoll_event event;
- int nevents;
-
- /* Wait for the next event. Only do one event per call to keep the
- * function simple, this could be changed later. */
- do {
- nevents = epoll_wait(poll->epoll_fd, &event, 1, -1);
- } while (nevents < 0 && errno == EINTR);
- if (unlikely(nevents != 1)) {
- fprintf(stderr, "epoll_wait failed: %m\n");
- exit(1); /* should never happen */
- }
-
- /* Find out which event handler has become active */
- handler = event.data.ptr;
-
- /* Clear the eventfd */
- event_notifier_test_and_clear(handler->notifier);
-
- /* Handle the event */
- handler->callback(handler);
-}
-
-/* Stop event_poll()
- *
- * This function can be used from another thread.
- */
-void event_poll_notify(EventPoll *poll)
-{
- event_notifier_set(&poll->stop_notifier);
-}
diff --git a/hw/dataplane/event-poll.h b/hw/dataplane/event-poll.h
deleted file mode 100644
index 3e8d3ec7d5..0000000000
--- a/hw/dataplane/event-poll.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Event loop with file descriptor polling
- *
- * Copyright 2012 IBM, Corp.
- * Copyright 2012 Red Hat, Inc. and/or its affiliates
- *
- * Authors:
- * Stefan Hajnoczi <stefanha@redhat.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-#ifndef EVENT_POLL_H
-#define EVENT_POLL_H
-
-#include "qemu/event_notifier.h"
-
-typedef struct EventHandler EventHandler;
-typedef void EventCallback(EventHandler *handler);
-struct EventHandler {
- EventNotifier *notifier; /* eventfd */
- EventCallback *callback; /* callback function */
-};
-
-typedef struct {
- int epoll_fd; /* epoll(2) file descriptor */
- EventNotifier stop_notifier; /* stop poll notifier */
- EventHandler stop_handler; /* stop poll handler */
-} EventPoll;
-
-void event_poll_add(EventPoll *poll, EventHandler *handler,
- EventNotifier *notifier, EventCallback *callback);
-void event_poll_init(EventPoll *poll);
-void event_poll_cleanup(EventPoll *poll);
-void event_poll(EventPoll *poll);
-void event_poll_notify(EventPoll *poll);
-
-#endif /* EVENT_POLL_H */
diff --git a/hw/dataplane/virtio-blk.c b/hw/dataplane/virtio-blk.c
index 8319c94b76..dfe5f9b9cd 100644
--- a/hw/dataplane/virtio-blk.c
+++ b/hw/dataplane/virtio-blk.c
@@ -14,7 +14,6 @@
#include "trace.h"
#include "qemu/iov.h"
-#include "event-poll.h"
#include "qemu/thread.h"
#include "qemu/error-report.h"
#include "vring.h"
@@ -22,7 +21,8 @@
#include "migration/migration.h"
#include "block/block.h"
#include "hw/virtio-blk.h"
-#include "virtio-blk.h"
+#include "hw/dataplane/virtio-blk.h"
+#include "block/aio.h"
enum {
SEG_MAX = 126, /* maximum number of I/O segments */
@@ -53,9 +53,14 @@ struct VirtIOBlockDataPlane {
Vring vring; /* virtqueue vring */
EventNotifier *guest_notifier; /* irq */
- EventPoll event_poll; /* event poller */
- EventHandler io_handler; /* Linux AIO completion handler */
- EventHandler notify_handler; /* virtqueue notify handler */
+ /* Note that these EventNotifiers are assigned by value. This is
+ * fine as long as you do not call event_notifier_cleanup on them
+ * (because you don't own the file descriptor or handle; you just
+ * use it).
+ */
+ AioContext *ctx;
+ EventNotifier io_notifier; /* Linux AIO completion */
+ EventNotifier host_notifier; /* doorbell */
IOQueue ioqueue; /* Linux AIO queue (should really be per
dataplane thread) */
@@ -258,10 +263,10 @@ static int process_request(IOQueue *ioq, struct iovec iov[],
}
}
-static void handle_notify(EventHandler *handler)
+static void handle_notify(EventNotifier *e)
{
- VirtIOBlockDataPlane *s = container_of(handler, VirtIOBlockDataPlane,
- notify_handler);
+ VirtIOBlockDataPlane *s = container_of(e, VirtIOBlockDataPlane,
+ host_notifier);
/* There is one array of iovecs into which all new requests are extracted
* from the vring. Requests are read from the vring and the translated
@@ -288,6 +293,7 @@ static void handle_notify(EventHandler *handler)
unsigned int out_num = 0, in_num = 0;
unsigned int num_queued;
+ event_notifier_test_and_clear(&s->host_notifier);
for (;;) {
/* Disable guest->host notifies to avoid unnecessary vmexits */
vring_disable_notification(s->vdev, &s->vring);
@@ -336,11 +342,12 @@ static void handle_notify(EventHandler *handler)
}
}
-static void handle_io(EventHandler *handler)
+static void handle_io(EventNotifier *e)
{
- VirtIOBlockDataPlane *s = container_of(handler, VirtIOBlockDataPlane,
- io_handler);
+ VirtIOBlockDataPlane *s = container_of(e, VirtIOBlockDataPlane,
+ io_notifier);
+ event_notifier_test_and_clear(&s->io_notifier);
if (ioq_run_completion(&s->ioqueue, complete_request, s) > 0) {
notify_guest(s);
}
@@ -350,7 +357,7 @@ static void handle_io(EventHandler *handler)
* requests.
*/
if (unlikely(vring_more_avail(&s->vring))) {
- handle_notify(&s->notify_handler);
+ handle_notify(&s->host_notifier);
}
}
@@ -359,7 +366,7 @@ static void *data_plane_thread(void *opaque)
VirtIOBlockDataPlane *s = opaque;
do {
- event_poll(&s->event_poll);
+ aio_poll(s->ctx, true);
} while (!s->stopping || s->num_reqs > 0);
return NULL;
}
@@ -447,7 +454,7 @@ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
return;
}
- event_poll_init(&s->event_poll);
+ s->ctx = aio_context_new();
/* Set up guest notifier (irq) */
if (s->vdev->binding->set_guest_notifiers(s->vdev->binding_opaque, 1,
@@ -464,17 +471,16 @@ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
fprintf(stderr, "virtio-blk failed to set host notifier\n");
exit(1);
}
- event_poll_add(&s->event_poll, &s->notify_handler,
- virtio_queue_get_host_notifier(vq),
- handle_notify);
+ s->host_notifier = *virtio_queue_get_host_notifier(vq);
+ aio_set_event_notifier(s->ctx, &s->host_notifier, handle_notify, NULL);
/* Set up ioqueue */
ioq_init(&s->ioqueue, s->fd, REQ_MAX);
for (i = 0; i < ARRAY_SIZE(s->requests); i++) {
ioq_put_iocb(&s->ioqueue, &s->requests[i].iocb);
}
- event_poll_add(&s->event_poll, &s->io_handler,
- ioq_get_notifier(&s->ioqueue), handle_io);
+ s->io_notifier = *ioq_get_notifier(&s->ioqueue);
+ aio_set_event_notifier(s->ctx, &s->io_notifier, handle_io, NULL);
s->started = true;
trace_virtio_blk_data_plane_start(s);
@@ -500,15 +506,17 @@ void virtio_blk_data_plane_stop(VirtIOBlockDataPlane *s)
qemu_bh_delete(s->start_bh);
s->start_bh = NULL;
} else {
- event_poll_notify(&s->event_poll);
+ aio_notify(s->ctx);
qemu_thread_join(&s->thread);
}
+ aio_set_event_notifier(s->ctx, &s->io_notifier, NULL, NULL);
ioq_cleanup(&s->ioqueue);
+ aio_set_event_notifier(s->ctx, &s->host_notifier, NULL, NULL);
s->vdev->binding->set_host_notifier(s->vdev->binding_opaque, 0, false);
- event_poll_cleanup(&s->event_poll);
+ aio_context_unref(s->ctx);
/* Clean up guest notifier (irq) */
s->vdev->binding->set_guest_notifiers(s->vdev->binding_opaque, 1, false);
diff --git a/hw/e1000.c b/hw/e1000.c
index ed37061563..80b6ee3c1a 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -131,6 +131,11 @@ typedef struct E1000State_st {
} eecd_state;
QEMUTimer *autoneg_timer;
+
+/* Compatibility flags for migration to/from qemu 1.3.0 and older */
+#define E1000_FLAG_AUTONEG_BIT 0
+#define E1000_FLAG_AUTONEG (1 << E1000_FLAG_AUTONEG_BIT)
+ uint32_t compat_flags;
} E1000State;
#define defreg(x) x = (E1000_##x>>2)
@@ -165,6 +170,14 @@ e1000_link_up(E1000State *s)
static void
set_phy_ctrl(E1000State *s, int index, uint16_t val)
{
+ /*
+ * QEMU 1.3 does not support link auto-negotiation emulation, so if we
+ * migrate during auto negotiation, after migration the link will be
+ * down.
+ */
+ if (!(s->compat_flags & E1000_FLAG_AUTONEG)) {
+ return;
+ }
if ((val & MII_CR_AUTO_NEG_EN) && (val & MII_CR_RESTART_AUTO_NEG)) {
e1000_link_down(s);
s->phy_reg[PHY_STATUS] &= ~MII_SR_AUTONEG_COMPLETE;
@@ -1120,6 +1133,11 @@ static void e1000_pre_save(void *opaque)
{
E1000State *s = opaque;
NetClientState *nc = qemu_get_queue(s->nic);
+
+ if (!(s->compat_flags & E1000_FLAG_AUTONEG)) {
+ return;
+ }
+
/*
* If link is down and auto-negotiation is ongoing, complete
* auto-negotiation immediately. This allows is to look at
@@ -1141,6 +1159,11 @@ static int e1000_post_load(void *opaque, int version_id)
* to link status bit in mac_reg[STATUS].
* Alternatively, restart link negotiation if it was in progress. */
nc->link_down = (s->mac_reg[STATUS] & E1000_STATUS_LU) == 0;
+
+ if (!(s->compat_flags & E1000_FLAG_AUTONEG)) {
+ return 0;
+ }
+
if (s->phy_reg[PHY_CTRL] & MII_CR_AUTO_NEG_EN &&
s->phy_reg[PHY_CTRL] & MII_CR_RESTART_AUTO_NEG &&
!(s->phy_reg[PHY_STATUS] & MII_SR_AUTONEG_COMPLETE)) {
@@ -1343,6 +1366,8 @@ static void qdev_e1000_reset(DeviceState *dev)
static Property e1000_properties[] = {
DEFINE_NIC_PROPERTIES(E1000State, conf),
+ DEFINE_PROP_BIT("autonegotiation", E1000State,
+ compat_flags, E1000_FLAG_AUTONEG_BIT, true),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 73a8656df8..0ee3b3b806 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -330,6 +330,10 @@ static QEMUMachine pc_i440fx_machine_v1_4 = {
.driver = "virtio-net-pci", \
.property = "mq", \
.value = "off", \
+ }, {\
+ .driver = "e1000",\
+ .property = "autonegotiation",\
+ .value = "off",\
}
static QEMUMachine pc_machine_v1_3 = {
diff --git a/hw/ich9.h b/hw/ich9.h
index 59c25e9aa0..e7d2df7280 100644
--- a/hw/ich9.h
+++ b/hw/ich9.h
@@ -49,6 +49,15 @@ typedef struct ICH9LPCState {
/* 10.1 Chipset Configuration registers(Memory Space)
which is pointed by RCBA */
uint8_t chip_config[ICH9_CC_SIZE];
+
+ /*
+ * 13.7.5 RST_CNT---Reset Control Register (LPC I/F---D31:F0)
+ *
+ * register contents and IO memory region
+ */
+ uint8_t rst_cnt;
+ MemoryRegion rst_cnt_mem;
+
/* isa bus */
ISABus *isa_bus;
MemoryRegion rbca_mem;
@@ -103,6 +112,8 @@ typedef struct ICH9LPCState {
#define ICH9_D2P_A2_REVISION 0x92
+/* D31:F0 LPC Processor Interface */
+#define ICH9_RST_CNT_IOPORT 0xCF9
/* D31:F1 LPC controller */
#define ICH9_A2_LPC "ICH9 A2 LPC"
diff --git a/hw/kvm/arm_gic.c b/hw/kvm/arm_gic.c
new file mode 100644
index 0000000000..22b40b4f84
--- /dev/null
+++ b/hw/kvm/arm_gic.c
@@ -0,0 +1,167 @@
+/*
+ * ARM Generic Interrupt Controller using KVM in-kernel support
+ *
+ * Copyright (c) 2012 Linaro Limited
+ * Written by Peter Maydell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "hw/sysbus.h"
+#include "sysemu/kvm.h"
+#include "kvm_arm.h"
+#include "hw/arm_gic_internal.h"
+
+#define TYPE_KVM_ARM_GIC "kvm-arm-gic"
+#define KVM_ARM_GIC(obj) \
+ OBJECT_CHECK(GICState, (obj), TYPE_KVM_ARM_GIC)
+#define KVM_ARM_GIC_CLASS(klass) \
+ OBJECT_CLASS_CHECK(KVMARMGICClass, (klass), TYPE_KVM_ARM_GIC)
+#define KVM_ARM_GIC_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(KVMARMGICClass, (obj), TYPE_KVM_ARM_GIC)
+
+typedef struct KVMARMGICClass {
+ ARMGICCommonClass parent_class;
+ DeviceRealize parent_realize;
+ void (*parent_reset)(DeviceState *dev);
+} KVMARMGICClass;
+
+static void kvm_arm_gic_set_irq(void *opaque, int irq, int level)
+{
+ /* Meaning of the 'irq' parameter:
+ * [0..N-1] : external interrupts
+ * [N..N+31] : PPI (internal) interrupts for CPU 0
+ * [N+32..N+63] : PPI (internal interrupts for CPU 1
+ * ...
+ * Convert this to the kernel's desired encoding, which
+ * has separate fields in the irq number for type,
+ * CPU number and interrupt number.
+ */
+ GICState *s = (GICState *)opaque;
+ int kvm_irq, irqtype, cpu;
+
+ if (irq < (s->num_irq - GIC_INTERNAL)) {
+ /* External interrupt. The kernel numbers these like the GIC
+ * hardware, with external interrupt IDs starting after the
+ * internal ones.
+ */
+ irqtype = KVM_ARM_IRQ_TYPE_SPI;
+ cpu = 0;
+ irq += GIC_INTERNAL;
+ } else {
+ /* Internal interrupt: decode into (cpu, interrupt id) */
+ irqtype = KVM_ARM_IRQ_TYPE_PPI;
+ irq -= (s->num_irq - GIC_INTERNAL);
+ cpu = irq / GIC_INTERNAL;
+ irq %= GIC_INTERNAL;
+ }
+ kvm_irq = (irqtype << KVM_ARM_IRQ_TYPE_SHIFT)
+ | (cpu << KVM_ARM_IRQ_VCPU_SHIFT) | irq;
+
+ kvm_set_irq(kvm_state, kvm_irq, !!level);
+}
+
+static void kvm_arm_gic_put(GICState *s)
+{
+ /* TODO: there isn't currently a kernel interface to set the GIC state */
+}
+
+static void kvm_arm_gic_get(GICState *s)
+{
+ /* TODO: there isn't currently a kernel interface to get the GIC state */
+}
+
+static void kvm_arm_gic_reset(DeviceState *dev)
+{
+ GICState *s = ARM_GIC_COMMON(dev);
+ KVMARMGICClass *kgc = KVM_ARM_GIC_GET_CLASS(s);
+
+ kgc->parent_reset(dev);
+ kvm_arm_gic_put(s);
+}
+
+static void kvm_arm_gic_realize(DeviceState *dev, Error **errp)
+{
+ int i;
+ GICState *s = KVM_ARM_GIC(dev);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+ KVMARMGICClass *kgc = KVM_ARM_GIC_GET_CLASS(s);
+
+ kgc->parent_realize(dev, errp);
+ if (error_is_set(errp)) {
+ return;
+ }
+
+ i = s->num_irq - GIC_INTERNAL;
+ /* For the GIC, also expose incoming GPIO lines for PPIs for each CPU.
+ * GPIO array layout is thus:
+ * [0..N-1] SPIs
+ * [N..N+31] PPIs for CPU 0
+ * [N+32..N+63] PPIs for CPU 1
+ * ...
+ */
+ i += (GIC_INTERNAL * s->num_cpu);
+ qdev_init_gpio_in(dev, kvm_arm_gic_set_irq, i);
+ /* We never use our outbound IRQ lines but provide them so that
+ * we maintain the same interface as the non-KVM GIC.
+ */
+ for (i = 0; i < s->num_cpu; i++) {
+ sysbus_init_irq(sbd, &s->parent_irq[i]);
+ }
+ /* Distributor */
+ memory_region_init_reservation(&s->iomem, "kvm-gic_dist", 0x1000);
+ sysbus_init_mmio(sbd, &s->iomem);
+ kvm_arm_register_device(&s->iomem,
+ (KVM_ARM_DEVICE_VGIC_V2 << KVM_ARM_DEVICE_ID_SHIFT)
+ | KVM_VGIC_V2_ADDR_TYPE_DIST);
+ /* CPU interface for current core. Unlike arm_gic, we don't
+ * provide the "interface for core #N" memory regions, because
+ * cores with a VGIC don't have those.
+ */
+ memory_region_init_reservation(&s->cpuiomem[0], "kvm-gic_cpu", 0x1000);
+ sysbus_init_mmio(sbd, &s->cpuiomem[0]);
+ kvm_arm_register_device(&s->cpuiomem[0],
+ (KVM_ARM_DEVICE_VGIC_V2 << KVM_ARM_DEVICE_ID_SHIFT)
+ | KVM_VGIC_V2_ADDR_TYPE_CPU);
+}
+
+static void kvm_arm_gic_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ ARMGICCommonClass *agcc = ARM_GIC_COMMON_CLASS(klass);
+ KVMARMGICClass *kgc = KVM_ARM_GIC_CLASS(klass);
+
+ agcc->pre_save = kvm_arm_gic_get;
+ agcc->post_load = kvm_arm_gic_put;
+ kgc->parent_realize = dc->realize;
+ kgc->parent_reset = dc->reset;
+ dc->realize = kvm_arm_gic_realize;
+ dc->reset = kvm_arm_gic_reset;
+ dc->no_user = 1;
+}
+
+static const TypeInfo kvm_arm_gic_info = {
+ .name = TYPE_KVM_ARM_GIC,
+ .parent = TYPE_ARM_GIC_COMMON,
+ .instance_size = sizeof(GICState),
+ .class_init = kvm_arm_gic_class_init,
+ .class_size = sizeof(KVMARMGICClass),
+};
+
+static void kvm_arm_gic_register_types(void)
+{
+ type_register_static(&kvm_arm_gic_info);
+}
+
+type_init(kvm_arm_gic_register_types)
diff --git a/hw/lpc_ich9.c b/hw/lpc_ich9.c
index e55d66a7a4..0ca0a59ef7 100644
--- a/hw/lpc_ich9.c
+++ b/hw/lpc_ich9.c
@@ -466,6 +466,7 @@ static void ich9_lpc_reset(DeviceState *qdev)
ich9_lpc_rcba_update(lpc, rbca_old);
lpc->sci_level = 0;
+ lpc->rst_cnt = 0;
}
static const MemoryRegionOps rbca_mmio_ops = {
@@ -498,6 +499,32 @@ static void ich9_lpc_machine_ready(Notifier *n, void *opaque)
}
}
+/* reset control */
+static void ich9_rst_cnt_write(void *opaque, hwaddr addr, uint64_t val,
+ unsigned len)
+{
+ ICH9LPCState *lpc = opaque;
+
+ if (val & 4) {
+ qemu_system_reset_request();
+ return;
+ }
+ lpc->rst_cnt = val & 0xA; /* keep FULL_RST (bit 3) and SYS_RST (bit 1) */
+}
+
+static uint64_t ich9_rst_cnt_read(void *opaque, hwaddr addr, unsigned len)
+{
+ ICH9LPCState *lpc = opaque;
+
+ return lpc->rst_cnt;
+}
+
+static const MemoryRegionOps ich9_rst_cnt_ops = {
+ .read = ich9_rst_cnt_read,
+ .write = ich9_rst_cnt_write,
+ .endianness = DEVICE_LITTLE_ENDIAN
+};
+
static int ich9_lpc_initfn(PCIDevice *d)
{
ICH9LPCState *lpc = ICH9_LPC_DEVICE(d);
@@ -519,9 +546,32 @@ static int ich9_lpc_initfn(PCIDevice *d)
lpc->machine_ready.notify = ich9_lpc_machine_ready;
qemu_add_machine_init_done_notifier(&lpc->machine_ready);
+ memory_region_init_io(&lpc->rst_cnt_mem, &ich9_rst_cnt_ops, lpc,
+ "lpc-reset-control", 1);
+ memory_region_add_subregion_overlap(pci_address_space_io(d),
+ ICH9_RST_CNT_IOPORT, &lpc->rst_cnt_mem,
+ 1);
+
return 0;
}
+static bool ich9_rst_cnt_needed(void *opaque)
+{
+ ICH9LPCState *lpc = opaque;
+
+ return (lpc->rst_cnt != 0);
+}
+
+static const VMStateDescription vmstate_ich9_rst_cnt = {
+ .name = "ICH9LPC/rst_cnt",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT8(rst_cnt, ICH9LPCState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static const VMStateDescription vmstate_ich9_lpc = {
.name = "ICH9LPC",
.version_id = 1,
@@ -535,6 +585,13 @@ static const VMStateDescription vmstate_ich9_lpc = {
VMSTATE_UINT8_ARRAY(chip_config, ICH9LPCState, ICH9_CC_SIZE),
VMSTATE_UINT32(sci_level, ICH9LPCState),
VMSTATE_END_OF_LIST()
+ },
+ .subsections = (VMStateSubsection[]) {
+ {
+ .vmsd = &vmstate_ich9_rst_cnt,
+ .needed = ich9_rst_cnt_needed
+ },
+ { 0 }
}
};
diff --git a/hw/macio.c b/hw/macio.c
index 792fa390e6..e91143e331 100644
--- a/hw/macio.c
+++ b/hw/macio.c
@@ -188,7 +188,7 @@ static int macio_newworld_initfn(PCIDevice *d)
sysbus_dev = SYS_BUS_DEVICE(&ns->ide[1]);
sysbus_connect_irq(sysbus_dev, 0, ns->irqs[3]);
sysbus_connect_irq(sysbus_dev, 1, ns->irqs[4]);
- macio_ide_register_dma(&ns->ide[0], s->dbdma, 0x1a);
+ macio_ide_register_dma(&ns->ide[1], s->dbdma, 0x1a);
ret = qdev_init(DEVICE(&ns->ide[1]));
if (ret < 0) {
return ret;
diff --git a/hw/milkymist-hw.h b/hw/milkymist-hw.h
index d49f96b5d4..ced1c5f54e 100644
--- a/hw/milkymist-hw.h
+++ b/hw/milkymist-hw.h
@@ -170,22 +170,6 @@ static inline DeviceState *milkymist_ac97_create(hwaddr base,
return dev;
}
-static inline DeviceState *milkymist_minimac_create(hwaddr base,
- qemu_irq rx_irq, qemu_irq tx_irq)
-{
- DeviceState *dev;
-
- qemu_check_nic_model(&nd_table[0], "minimac");
- dev = qdev_create(NULL, "milkymist-minimac");
- qdev_set_nic_properties(dev, &nd_table[0]);
- qdev_init_nofail(dev);
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, rx_irq);
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 1, tx_irq);
-
- return dev;
-}
-
static inline DeviceState *milkymist_minimac2_create(hwaddr base,
hwaddr buffers_base, qemu_irq rx_irq, qemu_irq tx_irq)
{
diff --git a/hw/nand.c b/hw/nand.c
index 4176272993..de3e502596 100644
--- a/hw/nand.c
+++ b/hw/nand.c
@@ -46,7 +46,7 @@
# define NAND_IOSTATUS_PLANE1 (1 << 2)
# define NAND_IOSTATUS_PLANE2 (1 << 3)
# define NAND_IOSTATUS_PLANE3 (1 << 4)
-# define NAND_IOSTATUS_BUSY (1 << 6)
+# define NAND_IOSTATUS_READY (1 << 6)
# define NAND_IOSTATUS_UNPROTCT (1 << 7)
# define MAX_PAGE 0x800
@@ -231,6 +231,7 @@ static void nand_reset(DeviceState *dev)
s->iolen = 0;
s->offset = 0;
s->status &= NAND_IOSTATUS_UNPROTCT;
+ s->status |= NAND_IOSTATUS_READY;
}
static inline void nand_pushio_byte(NANDFlashState *s, uint8_t value)
diff --git a/hw/pc.h b/hw/pc.h
index 03a0277852..dbbd8cde9e 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -216,6 +216,11 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t);
.driver = "virtio-blk-pci",\
.property = "discard_granularity",\
.value = stringify(0),\
+ },{\
+ .driver = "virtio-serial-pci",\
+ .property = "vectors",\
+ /* DEV_NVECTORS_UNSPECIFIED as a uint32_t string */\
+ .value = stringify(0xFFFFFFFF),\
}
#endif
diff --git a/hw/pci/pci_host.h b/hw/pci/pci_host.h
index 1845d4dfd5..236cd0f75c 100644
--- a/hw/pci/pci_host.h
+++ b/hw/pci/pci_host.h
@@ -40,7 +40,6 @@ struct PCIHostState {
MemoryRegion conf_mem;
MemoryRegion data_mem;
MemoryRegion mmcfg;
- MemoryRegion *address_space;
uint32_t config_reg;
PCIBus *bus;
};
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index ac33db5cde..e10bc1c6a0 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -244,7 +244,6 @@ static PCIBus *i440fx_common_init(const char *device_name,
dev = qdev_create(NULL, "i440FX-pcihost");
s = PCI_HOST_BRIDGE(dev);
- s->address_space = address_space_mem;
b = pci_bus_new(dev, NULL, pci_address_space,
address_space_io, 0);
s->bus = b;
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index e06dded003..292091180d 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -567,7 +567,6 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
dev = qdev_create(NULL, "raven-pcihost");
pcihost = PCI_HOST_BRIDGE(dev);
- pcihost->address_space = get_system_memory();
object_property_add_child(qdev_get_machine(), "raven", OBJECT(dev), NULL);
qdev_init_nofail(dev);
pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci.0");
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 163d7a1a48..08787c2a9b 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -1508,6 +1508,10 @@ void scsi_req_unref(SCSIRequest *req)
will start the next chunk or complete the command. */
void scsi_req_continue(SCSIRequest *req)
{
+ if (req->io_canceled) {
+ trace_scsi_req_continue_canceled(req->dev->id, req->lun, req->tag);
+ return;
+ }
trace_scsi_req_continue(req->dev->id, req->lun, req->tag);
if (req->cmd.mode == SCSI_XFER_TO_DEV) {
req->ops->write_data(req);
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 1e128182db..c5c7bf3dfa 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -178,6 +178,9 @@ static void scsi_aio_complete(void *opaque, int ret)
assert(r->req.aiocb != NULL);
r->req.aiocb = NULL;
bdrv_acct_done(s->qdev.conf.bs, &r->acct);
+ if (r->req.io_canceled) {
+ goto done;
+ }
if (ret < 0) {
if (scsi_handle_rw_error(r, -ret)) {
@@ -223,6 +226,10 @@ static void scsi_write_do_fua(SCSIDiskReq *r)
{
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
+ if (r->req.io_canceled) {
+ goto done;
+ }
+
if (scsi_is_cmd_fua(&r->req.cmd)) {
bdrv_acct_start(s->qdev.conf.bs, &r->acct, 0, BDRV_ACCT_FLUSH);
r->req.aiocb = bdrv_aio_flush(s->qdev.conf.bs, scsi_aio_complete, r);
@@ -230,6 +237,8 @@ static void scsi_write_do_fua(SCSIDiskReq *r)
}
scsi_req_complete(&r->req, GOOD);
+
+done:
if (!r->req.io_canceled) {
scsi_req_unref(&r->req);
}
@@ -243,6 +252,9 @@ static void scsi_dma_complete(void *opaque, int ret)
assert(r->req.aiocb != NULL);
r->req.aiocb = NULL;
bdrv_acct_done(s->qdev.conf.bs, &r->acct);
+ if (r->req.io_canceled) {
+ goto done;
+ }
if (ret < 0) {
if (scsi_handle_rw_error(r, -ret)) {
@@ -274,6 +286,9 @@ static void scsi_read_complete(void * opaque, int ret)
assert(r->req.aiocb != NULL);
r->req.aiocb = NULL;
bdrv_acct_done(s->qdev.conf.bs, &r->acct);
+ if (r->req.io_canceled) {
+ goto done;
+ }
if (ret < 0) {
if (scsi_handle_rw_error(r, -ret)) {
@@ -305,6 +320,9 @@ static void scsi_do_read(void *opaque, int ret)
r->req.aiocb = NULL;
bdrv_acct_done(s->qdev.conf.bs, &r->acct);
}
+ if (r->req.io_canceled) {
+ goto done;
+ }
if (ret < 0) {
if (scsi_handle_rw_error(r, -ret)) {
@@ -312,10 +330,6 @@ static void scsi_do_read(void *opaque, int ret)
}
}
- if (r->req.io_canceled) {
- return;
- }
-
/* The request is used as the AIO opaque value, so add a ref. */
scsi_req_ref(&r->req);
@@ -423,6 +437,9 @@ static void scsi_write_complete(void * opaque, int ret)
r->req.aiocb = NULL;
bdrv_acct_done(s->qdev.conf.bs, &r->acct);
}
+ if (r->req.io_canceled) {
+ goto done;
+ }
if (ret < 0) {
if (scsi_handle_rw_error(r, -ret)) {
@@ -1478,13 +1495,17 @@ static void scsi_unmap_complete(void *opaque, int ret)
uint32_t nb_sectors;
r->req.aiocb = NULL;
+ if (r->req.io_canceled) {
+ goto done;
+ }
+
if (ret < 0) {
if (scsi_handle_rw_error(r, -ret)) {
goto done;
}
}
- if (data->count > 0 && !r->req.io_canceled) {
+ if (data->count > 0) {
sector_num = ldq_be_p(&data->inbuf[0]);
nb_sectors = ldl_be_p(&data->inbuf[8]) & 0xffffffffULL;
if (!check_lba_range(s, sector_num, nb_sectors)) {
@@ -1501,10 +1522,9 @@ static void scsi_unmap_complete(void *opaque, int ret)
return;
}
+ scsi_req_complete(&r->req, GOOD);
+
done:
- if (data->count == 0) {
- scsi_req_complete(&r->req, GOOD);
- }
if (!r->req.io_canceled) {
scsi_req_unref(&r->req);
}
diff --git a/hw/serial.c b/hw/serial.c
index 6a83543125..48a5eb62b9 100644
--- a/hw/serial.c
+++ b/hw/serial.c
@@ -256,16 +256,17 @@ static void serial_update_msl(SerialState *s)
qemu_mod_timer(s->modem_status_poll, qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() / 100);
}
-static void serial_xmit(void *opaque)
+static gboolean serial_xmit(GIOChannel *chan, GIOCondition cond, void *opaque)
{
SerialState *s = opaque;
- uint64_t new_xmit_ts = qemu_get_clock_ns(vm_clock);
if (s->tsr_retry <= 0) {
if (s->fcr & UART_FCR_FE) {
s->tsr = fifo_get(s,XMIT_FIFO);
if (!s->xmit_fifo.count)
s->lsr |= UART_LSR_THRE;
+ } else if ((s->lsr & UART_LSR_THRE)) {
+ return FALSE;
} else {
s->tsr = s->thr;
s->lsr |= UART_LSR_THRE;
@@ -277,30 +278,25 @@ static void serial_xmit(void *opaque)
/* in loopback mode, say that we just received a char */
serial_receive1(s, &s->tsr, 1);
} else if (qemu_chr_fe_write(s->chr, &s->tsr, 1) != 1) {
- if ((s->tsr_retry > 0) && (s->tsr_retry <= MAX_XMIT_RETRY)) {
+ if (s->tsr_retry >= 0 && s->tsr_retry < MAX_XMIT_RETRY &&
+ qemu_chr_fe_add_watch(s->chr, G_IO_OUT, serial_xmit, s) > 0) {
s->tsr_retry++;
- qemu_mod_timer(s->transmit_timer, new_xmit_ts + s->char_transmit_time);
- return;
- } else if (s->poll_msl < 0) {
- /* If we exceed MAX_XMIT_RETRY and the backend is not a real serial port, then
- drop any further failed writes instantly, until we get one that goes through.
- This is to prevent guests that log to unconnected pipes or pty's from stalling. */
- s->tsr_retry = -1;
+ return FALSE;
}
- }
- else {
+ s->tsr_retry = 0;
+ } else {
s->tsr_retry = 0;
}
s->last_xmit_ts = qemu_get_clock_ns(vm_clock);
- if (!(s->lsr & UART_LSR_THRE))
- qemu_mod_timer(s->transmit_timer, s->last_xmit_ts + s->char_transmit_time);
if (s->lsr & UART_LSR_THRE) {
s->lsr |= UART_LSR_TEMT;
s->thr_ipending = 1;
serial_update_irq(s);
}
+
+ return FALSE;
}
@@ -330,7 +326,7 @@ static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val,
s->lsr &= ~UART_LSR_THRE;
serial_update_irq(s);
}
- serial_xmit(s);
+ serial_xmit(NULL, G_IO_OUT, s);
}
break;
case 1:
@@ -684,8 +680,6 @@ void serial_init_core(SerialState *s)
s->modem_status_poll = qemu_new_timer_ns(vm_clock, (QEMUTimerCB *) serial_update_msl, s);
s->fifo_timeout_timer = qemu_new_timer_ns(vm_clock, (QEMUTimerCB *) fifo_timeout_int, s);
- s->transmit_timer = qemu_new_timer_ns(vm_clock, (QEMUTimerCB *) serial_xmit, s);
-
qemu_register_reset(serial_reset, s);
qemu_chr_add_handlers(s->chr, serial_can_receive1, serial_receive1,
diff --git a/hw/serial.h b/hw/serial.h
index 814b8c666f..e884499607 100644
--- a/hw/serial.h
+++ b/hw/serial.h
@@ -72,8 +72,6 @@ struct SerialState {
struct QEMUTimer *fifo_timeout_timer;
int timeout_ipending; /* timeout interrupt pending state */
- struct QEMUTimer *transmit_timer;
-
uint64_t char_transmit_time; /* time to transmit a char in ticks */
int poll_msl;
diff --git a/hw/sysbus.c b/hw/sysbus.c
index 74bb4b81de..702fc728f4 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -48,7 +48,8 @@ void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq)
}
}
-void sysbus_mmio_map(SysBusDevice *dev, int n, hwaddr addr)
+static void sysbus_mmio_map_common(SysBusDevice *dev, int n, hwaddr addr,
+ bool may_overlap, unsigned priority)
{
assert(n >= 0 && n < dev->num_mmio);
@@ -61,11 +62,29 @@ void sysbus_mmio_map(SysBusDevice *dev, int n, hwaddr addr)
memory_region_del_subregion(get_system_memory(), dev->mmio[n].memory);
}
dev->mmio[n].addr = addr;
- memory_region_add_subregion(get_system_memory(),
- addr,
- dev->mmio[n].memory);
+ if (may_overlap) {
+ memory_region_add_subregion_overlap(get_system_memory(),
+ addr,
+ dev->mmio[n].memory,
+ priority);
+ }
+ else {
+ memory_region_add_subregion(get_system_memory(),
+ addr,
+ dev->mmio[n].memory);
+ }
}
+void sysbus_mmio_map(SysBusDevice *dev, int n, hwaddr addr)
+{
+ sysbus_mmio_map_common(dev, n, addr, false, 0);
+}
+
+void sysbus_mmio_map_overlap(SysBusDevice *dev, int n, hwaddr addr,
+ unsigned priority)
+{
+ sysbus_mmio_map_common(dev, n, addr, true, priority);
+}
/* Request an IRQ source. The actual IRQ object may be populated later. */
void sysbus_init_irq(SysBusDevice *dev, qemu_irq *p)
diff --git a/hw/sysbus.h b/hw/sysbus.h
index 17de506339..5d90a52af5 100644
--- a/hw/sysbus.h
+++ b/hw/sysbus.h
@@ -56,6 +56,8 @@ void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size);
void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq);
void sysbus_mmio_map(SysBusDevice *dev, int n, hwaddr addr);
+void sysbus_mmio_map_overlap(SysBusDevice *dev, int n, hwaddr addr,
+ unsigned priority);
void sysbus_add_memory(SysBusDevice *dev, hwaddr addr,
MemoryRegion *mem);
void sysbus_add_memory_overlap(SysBusDevice *dev, hwaddr addr,
diff --git a/hw/vhost.c b/hw/vhost.c
index 2d25d7e300..4d6aee3ecd 100644
--- a/hw/vhost.c
+++ b/hw/vhost.c
@@ -53,10 +53,14 @@ static void vhost_dev_sync_region(struct vhost_dev *dev,
log = __sync_fetch_and_and(from, 0);
while ((bit = sizeof(log) > sizeof(int) ?
ffsll(log) : ffs(log))) {
- ram_addr_t ram_addr;
+ hwaddr page_addr;
+ hwaddr section_offset;
+ hwaddr mr_offset;
bit -= 1;
- ram_addr = section->offset_within_region + bit * VHOST_LOG_PAGE;
- memory_region_set_dirty(section->mr, ram_addr, VHOST_LOG_PAGE);
+ page_addr = addr + bit * VHOST_LOG_PAGE;
+ section_offset = page_addr - section->offset_within_address_space;
+ mr_offset = section_offset + section->offset_within_region;
+ memory_region_set_dirty(section->mr, mr_offset, VHOST_LOG_PAGE);
log &= ~(0x1ull << bit);
}
addr += VHOST_LOG_CHUNK;
@@ -65,14 +69,21 @@ static void vhost_dev_sync_region(struct vhost_dev *dev,
static int vhost_sync_dirty_bitmap(struct vhost_dev *dev,
MemoryRegionSection *section,
- hwaddr start_addr,
- hwaddr end_addr)
+ hwaddr first,
+ hwaddr last)
{
int i;
+ hwaddr start_addr;
+ hwaddr end_addr;
if (!dev->log_enabled || !dev->started) {
return 0;
}
+ start_addr = section->offset_within_address_space;
+ end_addr = range_get_last(start_addr, section->size);
+ start_addr = MAX(first, start_addr);
+ end_addr = MIN(last, end_addr);
+
for (i = 0; i < dev->mem->nregions; ++i) {
struct vhost_memory_region *reg = dev->mem->regions + i;
vhost_dev_sync_region(dev, section, start_addr, end_addr,
@@ -93,10 +104,18 @@ static void vhost_log_sync(MemoryListener *listener,
{
struct vhost_dev *dev = container_of(listener, struct vhost_dev,
memory_listener);
- hwaddr start_addr = section->offset_within_address_space;
- hwaddr end_addr = start_addr + section->size;
+ vhost_sync_dirty_bitmap(dev, section, 0x0, ~0x0ULL);
+}
- vhost_sync_dirty_bitmap(dev, section, start_addr, end_addr);
+static void vhost_log_sync_range(struct vhost_dev *dev,
+ hwaddr first, hwaddr last)
+{
+ int i;
+ /* FIXME: this is N^2 in number of sections */
+ for (i = 0; i < dev->n_mem_sections; ++i) {
+ MemoryRegionSection *section = &dev->mem_sections[i];
+ vhost_sync_dirty_bitmap(dev, section, first, last);
+ }
}
/* Assign/unassign. Keep an unsorted array of non-overlapping
@@ -268,16 +287,15 @@ static inline void vhost_dev_log_resize(struct vhost_dev* dev, uint64_t size)
{
vhost_log_chunk_t *log;
uint64_t log_base;
- int r, i;
+ int r;
log = g_malloc0(size * sizeof *log);
log_base = (uint64_t)(unsigned long)log;
r = ioctl(dev->control, VHOST_SET_LOG_BASE, &log_base);
assert(r >= 0);
- for (i = 0; i < dev->n_mem_sections; ++i) {
- /* Sync only the range covered by the old log */
- vhost_sync_dirty_bitmap(dev, &dev->mem_sections[i], 0,
- dev->log_size * VHOST_LOG_CHUNK - 1);
+ /* Sync only the range covered by the old log */
+ if (dev->log_size) {
+ vhost_log_sync_range(dev, 0, dev->log_size * VHOST_LOG_CHUNK - 1);
}
if (dev->log) {
g_free(dev->log);
@@ -1014,10 +1032,7 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev)
hdev->vqs + i,
hdev->vq_index + i);
}
- for (i = 0; i < hdev->n_mem_sections; ++i) {
- vhost_sync_dirty_bitmap(hdev, &hdev->mem_sections[i],
- 0, (hwaddr)~0x0ull);
- }
+ vhost_log_sync_range(hdev, 0, ~0x0ull);
hdev->started = false;
g_free(hdev->log);
diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index 248a966357..6b69236655 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -36,6 +36,7 @@ typedef struct VirtIOBlock
VirtIOBlkConf *blk;
unsigned short sector_mask;
DeviceState *qdev;
+ VMChangeStateEntry *change;
#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
VirtIOBlockDataPlane *dataplane;
#endif
@@ -681,7 +682,7 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, VirtIOBlkConf *blk)
}
#endif
- qemu_add_vm_change_state_handler(virtio_blk_dma_restart_cb, s);
+ s->change = qemu_add_vm_change_state_handler(virtio_blk_dma_restart_cb, s);
s->qdev = dev;
register_savevm(dev, "virtio-blk", virtio_blk_id++, 2,
virtio_blk_save, virtio_blk_load, s);
@@ -702,6 +703,7 @@ void virtio_blk_exit(VirtIODevice *vdev)
virtio_blk_data_plane_destroy(s->dataplane);
s->dataplane = NULL;
#endif
+ qemu_del_vm_change_state_handler(s->change);
unregister_savevm(s->qdev, "virtio-blk", s);
blockdev_mark_auto_del(s->bs);
virtio_cleanup(vdev);
diff --git a/hw/virtio-console.c b/hw/virtio-console.c
index b10f5f08d4..e2d1c58d9d 100644
--- a/hw/virtio-console.c
+++ b/hw/virtio-console.c
@@ -20,6 +20,18 @@ typedef struct VirtConsole {
CharDriverState *chr;
} VirtConsole;
+/*
+ * Callback function that's called from chardevs when backend becomes
+ * writable.
+ */
+static gboolean chr_write_unblocked(GIOChannel *chan, GIOCondition cond,
+ void *opaque)
+{
+ VirtConsole *vcon = opaque;
+
+ virtio_serial_throttle_port(&vcon->port, false);
+ return FALSE;
+}
/* Callback function that's called when the guest sends us data */
static ssize_t flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len)
@@ -35,19 +47,21 @@ static ssize_t flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len)
ret = qemu_chr_fe_write(vcon->chr, buf, len);
trace_virtio_console_flush_buf(port->id, len, ret);
- if (ret < 0) {
+ if (ret <= 0) {
+ VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_GET_CLASS(port);
+
/*
* Ideally we'd get a better error code than just -1, but
* that's what the chardev interface gives us right now. If
* we had a finer-grained message, like -EPIPE, we could close
- * this connection. Absent such error messages, the most we
- * can do is to return 0 here.
- *
- * This will prevent stray -1 values to go to
- * virtio-serial-bus.c and cause abort()s in
- * do_flush_queued_data().
+ * this connection.
*/
ret = 0;
+ if (!k->is_console) {
+ virtio_serial_throttle_port(port, true);
+ qemu_chr_fe_add_watch(vcon->chr, G_IO_OUT, chr_write_unblocked,
+ vcon);
+ }
}
return ret;
}
diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 0ad96eefd6..8c9d8713f3 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -44,7 +44,7 @@ typedef struct VirtIONet
VirtIODevice vdev;
uint8_t mac[ETH_ALEN];
uint16_t status;
- VirtIONetQueue vqs[MAX_QUEUE_NUM];
+ VirtIONetQueue *vqs;
VirtQueue *ctrl_vq;
NICState *nic;
uint32_t tx_timeout;
@@ -1326,8 +1326,9 @@ VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf,
n->vdev.set_status = virtio_net_set_status;
n->vdev.guest_notifier_mask = virtio_net_guest_notifier_mask;
n->vdev.guest_notifier_pending = virtio_net_guest_notifier_pending;
+ n->max_queues = MAX(conf->queues, 1);
+ n->vqs = g_malloc0(sizeof(VirtIONetQueue) * n->max_queues);
n->vqs[0].rx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_rx);
- n->max_queues = conf->queues;
n->curr_queues = 1;
n->vqs[0].n = n;
n->tx_timeout = net->txtimer;
@@ -1412,6 +1413,7 @@ void virtio_net_exit(VirtIODevice *vdev)
}
}
+ g_free(n->vqs);
qemu_del_nic(n->nic);
virtio_cleanup(&n->vdev);
}
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index ba4d7d5424..39c1966cfc 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -975,6 +975,9 @@ static int virtio_serial_init_pci(PCIDevice *pci_dev)
if (!vdev) {
return -1;
}
+
+ /* backwards-compatibility with machines that were created with
+ DEV_NVECTORS_UNSPECIFIED */
vdev->nvectors = proxy->nvectors == DEV_NVECTORS_UNSPECIFIED
? proxy->serial.max_virtserial_ports + 1
: proxy->nvectors;
@@ -1155,7 +1158,7 @@ static const TypeInfo virtio_net_info = {
static Property virtio_serial_properties[] = {
DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
- DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, DEV_NVECTORS_UNSPECIFIED),
+ DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
DEFINE_PROP_UINT32("max_ports", VirtIOPCIProxy, serial.max_virtserial_ports, 31),
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index ada1d0100b..7d0515f551 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -172,24 +172,7 @@ static void do_flush_queued_data(VirtIOSerialPort *port, VirtQueue *vq,
port->elem.out_sg[i].iov_base
+ port->iov_offset,
buf_size);
- if (ret < 0 && ret != -EAGAIN) {
- /* We don't handle any other type of errors here */
- abort();
- }
- if (ret == -EAGAIN || (ret >= 0 && ret < buf_size)) {
- /*
- * this is a temporary check until chardevs can signal to
- * frontends that they are writable again. This prevents
- * the console from going into throttled mode (forever)
- * if virtio-console is connected to a pty without a
- * listener. Otherwise the guest spins forever.
- * We can revert this if
- * 1: chardevs can notify frondends
- * 2: the guest driver does not spin in these cases
- */
- if (!vsc->is_console) {
- virtio_serial_throttle_port(port, true);
- }
+ if (port->throttled) {
port->iov_idx = i;
if (ret > 0) {
port->iov_offset += ret;
diff --git a/include/char/baum.h b/include/char/baum.h
deleted file mode 100644
index 763588422a..0000000000
--- a/include/char/baum.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * QEMU Baum
- *
- * Copyright (c) 2008 Samuel Thibault
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifndef HW_BAUM_H
-#define HW_BAUM_H 1
-
-/* char device */
-CharDriverState *chr_baum_init(QemuOpts *opts);
-
-#endif
diff --git a/include/char/char.h b/include/char/char.h
index c91ce3c98a..2e24270895 100644
--- a/include/char/char.h
+++ b/include/char/char.h
@@ -56,6 +56,7 @@ typedef void IOEventHandler(void *opaque, int event);
struct CharDriverState {
void (*init)(struct CharDriverState *s);
int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len);
+ GSource *(*chr_add_watch)(struct CharDriverState *s, GIOCondition cond);
void (*chr_update_read_handler)(struct CharDriverState *s);
int (*chr_ioctl)(struct CharDriverState *s, int cmd, void *arg);
int (*get_msgfd)(struct CharDriverState *s);
@@ -70,7 +71,7 @@ struct CharDriverState {
void (*chr_guest_open)(struct CharDriverState *chr);
void (*chr_guest_close)(struct CharDriverState *chr);
void *opaque;
- QEMUTimer *open_timer;
+ int idle_tag;
char *label;
char *filename;
int opened;
@@ -152,6 +153,9 @@ void qemu_chr_fe_close(struct CharDriverState *chr);
void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
GCC_FMT_ATTR(2, 3);
+guint qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond,
+ GIOFunc func, void *user_data);
+
/**
* @qemu_chr_fe_write:
*
@@ -240,6 +244,8 @@ CharDriverState *qemu_chr_find(const char *name);
QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename);
+void register_char_driver(const char *name, CharDriverState *(*open)(QemuOpts *));
+
/* add an eventfd to the qemu devices that are polled */
CharDriverState *qemu_chr_open_eventfd(int eventfd);
diff --git a/include/char/msmouse.h b/include/char/msmouse.h
deleted file mode 100644
index 8cff3a71c3..0000000000
--- a/include/char/msmouse.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef HW_MSMOUSE_H
-#define HW_MSMOUSE_H 1
-
-/* msmouse.c */
-CharDriverState *qemu_chr_open_msmouse(QemuOpts *opts);
-
-#endif
diff --git a/include/exec/gen-icount.h b/include/exec/gen-icount.h
index 8043b3ba26..4e3b17b083 100644
--- a/include/exec/gen-icount.h
+++ b/include/exec/gen-icount.h
@@ -7,10 +7,19 @@
static TCGArg *icount_arg;
static int icount_label;
+static int exitreq_label;
-static inline void gen_icount_start(void)
+static inline void gen_tb_start(void)
{
TCGv_i32 count;
+ TCGv_i32 flag;
+
+ exitreq_label = gen_new_label();
+ flag = tcg_temp_local_new_i32();
+ tcg_gen_ld_i32(flag, cpu_env,
+ offsetof(CPUState, tcg_exit_req) - ENV_OFFSET);
+ tcg_gen_brcondi_i32(TCG_COND_NE, flag, 0, exitreq_label);
+ tcg_temp_free_i32(flag);
if (!use_icount)
return;
@@ -27,12 +36,15 @@ static inline void gen_icount_start(void)
tcg_temp_free_i32(count);
}
-static void gen_icount_end(TranslationBlock *tb, int num_insns)
+static void gen_tb_end(TranslationBlock *tb, int num_insns)
{
+ gen_set_label(exitreq_label);
+ tcg_gen_exit_tb((tcg_target_long)tb + TB_EXIT_REQUESTED);
+
if (use_icount) {
*icount_arg = num_insns;
gen_set_label(icount_label);
- tcg_gen_exit_tb((tcg_target_long)tb + 2);
+ tcg_gen_exit_tb((tcg_target_long)tb + TB_EXIT_ICOUNT_EXPIRED);
}
}
diff --git a/include/net/net.h b/include/net/net.h
index 43a045e052..cb049a16a3 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -72,7 +72,7 @@ struct NetClientState {
};
typedef struct NICState {
- NetClientState ncs[MAX_QUEUE_NUM];
+ NetClientState *ncs;
NICConf *conf;
void *opaque;
bool peer_deleted;
diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h
index 803ae1798c..6125bf7bdf 100644
--- a/include/qemu/sockets.h
+++ b/include/qemu/sockets.h
@@ -34,6 +34,7 @@ int inet_aton(const char *cp, struct in_addr *ia);
int qemu_socket(int domain, int type, int protocol);
int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
int socket_set_cork(int fd, int v);
+int socket_set_nodelay(int fd);
void socket_set_block(int fd);
void socket_set_nonblock(int fd);
int send_all(int fd, const void *buf, int len1);
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index ee1a7c878a..ab2657c558 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -71,6 +71,8 @@ struct kvm_run;
* @created: Indicates whether the CPU thread has been successfully created.
* @stop: Indicates a pending stop request.
* @stopped: Indicates the CPU has been artificially stopped.
+ * @tcg_exit_req: Set to force TCG to stop executing linked TBs for this
+ * CPU and return to its top level loop.
* @env_ptr: Pointer to subclass-specific CPUArchState field.
* @current_tb: Currently executing TB.
* @kvm_fd: vCPU file descriptor for KVM.
@@ -100,6 +102,7 @@ struct CPUState {
bool stop;
bool stopped;
volatile sig_atomic_t exit_request;
+ volatile sig_atomic_t tcg_exit_req;
void *env_ptr; /* CPUArchState */
struct TranslationBlock *current_tb;
diff --git a/linux-headers/asm-arm/kvm.h b/linux-headers/asm-arm/kvm.h
new file mode 100644
index 0000000000..023bfeb367
--- /dev/null
+++ b/linux-headers/asm-arm/kvm.h
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Author: Christoffer Dall <c.dall@virtualopensystems.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __ARM_KVM_H__
+#define __ARM_KVM_H__
+
+#include <linux/types.h>
+#include <asm/ptrace.h>
+
+#define __KVM_HAVE_GUEST_DEBUG
+#define __KVM_HAVE_IRQ_LINE
+
+#define KVM_REG_SIZE(id) \
+ (1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT))
+
+/* Valid for svc_regs, abt_regs, und_regs, irq_regs in struct kvm_regs */
+#define KVM_ARM_SVC_sp svc_regs[0]
+#define KVM_ARM_SVC_lr svc_regs[1]
+#define KVM_ARM_SVC_spsr svc_regs[2]
+#define KVM_ARM_ABT_sp abt_regs[0]
+#define KVM_ARM_ABT_lr abt_regs[1]
+#define KVM_ARM_ABT_spsr abt_regs[2]
+#define KVM_ARM_UND_sp und_regs[0]
+#define KVM_ARM_UND_lr und_regs[1]
+#define KVM_ARM_UND_spsr und_regs[2]
+#define KVM_ARM_IRQ_sp irq_regs[0]
+#define KVM_ARM_IRQ_lr irq_regs[1]
+#define KVM_ARM_IRQ_spsr irq_regs[2]
+
+/* Valid only for fiq_regs in struct kvm_regs */
+#define KVM_ARM_FIQ_r8 fiq_regs[0]
+#define KVM_ARM_FIQ_r9 fiq_regs[1]
+#define KVM_ARM_FIQ_r10 fiq_regs[2]
+#define KVM_ARM_FIQ_fp fiq_regs[3]
+#define KVM_ARM_FIQ_ip fiq_regs[4]
+#define KVM_ARM_FIQ_sp fiq_regs[5]
+#define KVM_ARM_FIQ_lr fiq_regs[6]
+#define KVM_ARM_FIQ_spsr fiq_regs[7]
+
+struct kvm_regs {
+ struct pt_regs usr_regs;/* R0_usr - R14_usr, PC, CPSR */
+ __u32 svc_regs[3]; /* SP_svc, LR_svc, SPSR_svc */
+ __u32 abt_regs[3]; /* SP_abt, LR_abt, SPSR_abt */
+ __u32 und_regs[3]; /* SP_und, LR_und, SPSR_und */
+ __u32 irq_regs[3]; /* SP_irq, LR_irq, SPSR_irq */
+ __u32 fiq_regs[8]; /* R8_fiq - R14_fiq, SPSR_fiq */
+};
+
+/* Supported Processor Types */
+#define KVM_ARM_TARGET_CORTEX_A15 0
+#define KVM_ARM_NUM_TARGETS 1
+
+/* KVM_ARM_SET_DEVICE_ADDR ioctl id encoding */
+#define KVM_ARM_DEVICE_TYPE_SHIFT 0
+#define KVM_ARM_DEVICE_TYPE_MASK (0xffff << KVM_ARM_DEVICE_TYPE_SHIFT)
+#define KVM_ARM_DEVICE_ID_SHIFT 16
+#define KVM_ARM_DEVICE_ID_MASK (0xffff << KVM_ARM_DEVICE_ID_SHIFT)
+
+/* Supported device IDs */
+#define KVM_ARM_DEVICE_VGIC_V2 0
+
+/* Supported VGIC address types */
+#define KVM_VGIC_V2_ADDR_TYPE_DIST 0
+#define KVM_VGIC_V2_ADDR_TYPE_CPU 1
+
+#define KVM_VGIC_V2_DIST_SIZE 0x1000
+#define KVM_VGIC_V2_CPU_SIZE 0x2000
+
+#define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
+
+struct kvm_vcpu_init {
+ __u32 target;
+ __u32 features[7];
+};
+
+struct kvm_sregs {
+};
+
+struct kvm_fpu {
+};
+
+struct kvm_guest_debug_arch {
+};
+
+struct kvm_debug_exit_arch {
+};
+
+struct kvm_sync_regs {
+};
+
+struct kvm_arch_memory_slot {
+};
+
+/* If you need to interpret the index values, here is the key: */
+#define KVM_REG_ARM_COPROC_MASK 0x000000000FFF0000
+#define KVM_REG_ARM_COPROC_SHIFT 16
+#define KVM_REG_ARM_32_OPC2_MASK 0x0000000000000007
+#define KVM_REG_ARM_32_OPC2_SHIFT 0
+#define KVM_REG_ARM_OPC1_MASK 0x0000000000000078
+#define KVM_REG_ARM_OPC1_SHIFT 3
+#define KVM_REG_ARM_CRM_MASK 0x0000000000000780
+#define KVM_REG_ARM_CRM_SHIFT 7
+#define KVM_REG_ARM_32_CRN_MASK 0x0000000000007800
+#define KVM_REG_ARM_32_CRN_SHIFT 11
+
+/* Normal registers are mapped as coprocessor 16. */
+#define KVM_REG_ARM_CORE (0x0010 << KVM_REG_ARM_COPROC_SHIFT)
+#define KVM_REG_ARM_CORE_REG(name) (offsetof(struct kvm_regs, name) / 4)
+
+/* Some registers need more space to represent values. */
+#define KVM_REG_ARM_DEMUX (0x0011 << KVM_REG_ARM_COPROC_SHIFT)
+#define KVM_REG_ARM_DEMUX_ID_MASK 0x000000000000FF00
+#define KVM_REG_ARM_DEMUX_ID_SHIFT 8
+#define KVM_REG_ARM_DEMUX_ID_CCSIDR (0x00 << KVM_REG_ARM_DEMUX_ID_SHIFT)
+#define KVM_REG_ARM_DEMUX_VAL_MASK 0x00000000000000FF
+#define KVM_REG_ARM_DEMUX_VAL_SHIFT 0
+
+/* VFP registers: we could overload CP10 like ARM does, but that's ugly. */
+#define KVM_REG_ARM_VFP (0x0012 << KVM_REG_ARM_COPROC_SHIFT)
+#define KVM_REG_ARM_VFP_MASK 0x000000000000FFFF
+#define KVM_REG_ARM_VFP_BASE_REG 0x0
+#define KVM_REG_ARM_VFP_FPSID 0x1000
+#define KVM_REG_ARM_VFP_FPSCR 0x1001
+#define KVM_REG_ARM_VFP_MVFR1 0x1006
+#define KVM_REG_ARM_VFP_MVFR0 0x1007
+#define KVM_REG_ARM_VFP_FPEXC 0x1008
+#define KVM_REG_ARM_VFP_FPINST 0x1009
+#define KVM_REG_ARM_VFP_FPINST2 0x100A
+
+
+/* KVM_IRQ_LINE irq field index values */
+#define KVM_ARM_IRQ_TYPE_SHIFT 24
+#define KVM_ARM_IRQ_TYPE_MASK 0xff
+#define KVM_ARM_IRQ_VCPU_SHIFT 16
+#define KVM_ARM_IRQ_VCPU_MASK 0xff
+#define KVM_ARM_IRQ_NUM_SHIFT 0
+#define KVM_ARM_IRQ_NUM_MASK 0xffff
+
+/* irq_type field */
+#define KVM_ARM_IRQ_TYPE_CPU 0
+#define KVM_ARM_IRQ_TYPE_SPI 1
+#define KVM_ARM_IRQ_TYPE_PPI 2
+
+/* out-of-kernel GIC cpu interrupt injection irq_number field */
+#define KVM_ARM_IRQ_CPU_IRQ 0
+#define KVM_ARM_IRQ_CPU_FIQ 1
+
+/* Highest supported SPI, from VGIC_NR_IRQS */
+#define KVM_ARM_IRQ_GIC_MAX 127
+
+/* PSCI interface */
+#define KVM_PSCI_FN_BASE 0x95c1ba5e
+#define KVM_PSCI_FN(n) (KVM_PSCI_FN_BASE + (n))
+
+#define KVM_PSCI_FN_CPU_SUSPEND KVM_PSCI_FN(0)
+#define KVM_PSCI_FN_CPU_OFF KVM_PSCI_FN(1)
+#define KVM_PSCI_FN_CPU_ON KVM_PSCI_FN(2)
+#define KVM_PSCI_FN_MIGRATE KVM_PSCI_FN(3)
+
+#define KVM_PSCI_RET_SUCCESS 0
+#define KVM_PSCI_RET_NI ((unsigned long)-1)
+#define KVM_PSCI_RET_INVAL ((unsigned long)-2)
+#define KVM_PSCI_RET_DENIED ((unsigned long)-3)
+
+#endif /* __ARM_KVM_H__ */
diff --git a/linux-headers/asm-arm/kvm_para.h b/linux-headers/asm-arm/kvm_para.h
new file mode 100644
index 0000000000..14fab8f0b9
--- /dev/null
+++ b/linux-headers/asm-arm/kvm_para.h
@@ -0,0 +1 @@
+#include <asm-generic/kvm_para.h>
diff --git a/linux-headers/asm-generic/kvm_para.h b/linux-headers/asm-generic/kvm_para.h
new file mode 100644
index 0000000000..486f0af73c
--- /dev/null
+++ b/linux-headers/asm-generic/kvm_para.h
@@ -0,0 +1,4 @@
+/*
+ * There isn't anything here, but the file must not be empty or patch
+ * will delete it.
+ */
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index 5af935761c..caca979c49 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -115,6 +115,7 @@ struct kvm_irq_level {
* ACPI gsi notion of irq.
* For IA-64 (APIC model) IOAPIC0: irq 0-23; IOAPIC1: irq 24-47..
* For X86 (standard AT mode) PIC0/1: irq 0-15. IOAPIC0: 0-23..
+ * For ARM: See Documentation/virtual/kvm/api.txt
*/
union {
__u32 irq;
@@ -662,6 +663,8 @@ struct kvm_ppc_smmu_info {
#define KVM_CAP_PPC_HTAB_FD 84
#define KVM_CAP_S390_CSS_SUPPORT 85
#define KVM_CAP_PPC_EPR 86
+#define KVM_CAP_ARM_PSCI 87
+#define KVM_CAP_ARM_SET_DEVICE_ADDR 88
#ifdef KVM_CAP_IRQ_ROUTING
@@ -791,6 +794,11 @@ struct kvm_dirty_tlb {
#define KVM_REG_SIZE_U512 0x0060000000000000ULL
#define KVM_REG_SIZE_U1024 0x0070000000000000ULL
+struct kvm_reg_list {
+ __u64 n; /* number of regs */
+ __u64 reg[0];
+};
+
struct kvm_one_reg {
__u64 id;
__u64 addr;
@@ -804,6 +812,11 @@ struct kvm_msi {
__u8 pad[16];
};
+struct kvm_arm_device_addr {
+ __u64 id;
+ __u64 addr;
+};
+
/*
* ioctls for VM fds
*/
@@ -889,6 +902,8 @@ struct kvm_s390_ucas_mapping {
#define KVM_ALLOCATE_RMA _IOR(KVMIO, 0xa9, struct kvm_allocate_rma)
/* Available with KVM_CAP_PPC_HTAB_FD */
#define KVM_PPC_GET_HTAB_FD _IOW(KVMIO, 0xaa, struct kvm_get_htab_fd)
+/* Available with KVM_CAP_ARM_SET_DEVICE_ADDR */
+#define KVM_ARM_SET_DEVICE_ADDR _IOW(KVMIO, 0xab, struct kvm_arm_device_addr)
/*
* ioctls for vcpu fds
@@ -959,6 +974,8 @@ struct kvm_s390_ucas_mapping {
#define KVM_SET_ONE_REG _IOW(KVMIO, 0xac, struct kvm_one_reg)
/* VM is being stopped by host */
#define KVM_KVMCLOCK_CTRL _IO(KVMIO, 0xad)
+#define KVM_ARM_VCPU_INIT _IOW(KVMIO, 0xae, struct kvm_vcpu_init)
+#define KVM_GET_REG_LIST _IOWR(KVMIO, 0xb0, struct kvm_reg_list)
#define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0)
#define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1)
diff --git a/linux-user/main.c b/linux-user/main.c
index 29845f9c81..d8b0cd65fa 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -1787,8 +1787,8 @@ void cpu_loop(CPUPPCState *env)
#ifdef TARGET_MIPS
-#define MIPS_SYS(name, args) args,
-
+# ifdef TARGET_ABI_MIPSO32
+# define MIPS_SYS(name, args) args,
static const uint8_t mips_syscall_args[] = {
MIPS_SYS(sys_syscall , 8) /* 4000 */
MIPS_SYS(sys_exit , 1)
@@ -2134,8 +2134,8 @@ static const uint8_t mips_syscall_args[] = {
MIPS_SYS(sys_clock_adjtime, 2)
MIPS_SYS(sys_syncfs, 1)
};
-
-#undef MIPS_SYS
+# undef MIPS_SYS
+# endif /* O32 */
static int do_store_exclusive(CPUMIPSState *env)
{
@@ -2186,12 +2186,42 @@ static int do_store_exclusive(CPUMIPSState *env)
return segv;
}
+/* Break codes */
+enum {
+ BRK_OVERFLOW = 6,
+ BRK_DIVZERO = 7
+};
+
+static int do_break(CPUMIPSState *env, target_siginfo_t *info,
+ unsigned int code)
+{
+ int ret = -1;
+
+ switch (code) {
+ case BRK_OVERFLOW:
+ case BRK_DIVZERO:
+ info->si_signo = TARGET_SIGFPE;
+ info->si_errno = 0;
+ info->si_code = (code == BRK_OVERFLOW) ? FPE_INTOVF : FPE_INTDIV;
+ queue_signal(env, info->si_signo, &*info);
+ ret = 0;
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
void cpu_loop(CPUMIPSState *env)
{
CPUState *cs = CPU(mips_env_get_cpu(env));
target_siginfo_t info;
- int trapnr, ret;
+ int trapnr;
+ abi_long ret;
+# ifdef TARGET_ABI_MIPSO32
unsigned int syscall_num;
+# endif
for(;;) {
cpu_exec_start(cs);
@@ -2199,8 +2229,9 @@ void cpu_loop(CPUMIPSState *env)
cpu_exec_end(cs);
switch(trapnr) {
case EXCP_SYSCALL:
- syscall_num = env->active_tc.gpr[2] - 4000;
env->active_tc.PC += 4;
+# ifdef TARGET_ABI_MIPSO32
+ syscall_num = env->active_tc.gpr[2] - 4000;
if (syscall_num >= sizeof(mips_syscall_args)) {
ret = -TARGET_ENOSYS;
} else {
@@ -2239,12 +2270,19 @@ void cpu_loop(CPUMIPSState *env)
arg5, arg6, arg7, arg8);
}
done_syscall:
+# else
+ ret = do_syscall(env, env->active_tc.gpr[2],
+ env->active_tc.gpr[4], env->active_tc.gpr[5],
+ env->active_tc.gpr[6], env->active_tc.gpr[7],
+ env->active_tc.gpr[8], env->active_tc.gpr[9],
+ env->active_tc.gpr[10], env->active_tc.gpr[11]);
+# endif /* O32 */
if (ret == -TARGET_QEMU_ESIGRETURN) {
/* Returning from a successful sigreturn syscall.
Avoid clobbering register state. */
break;
}
- if ((unsigned int)ret >= (unsigned int)(-1133)) {
+ if ((abi_ulong)ret >= (abi_ulong)-1133) {
env->active_tc.gpr[7] = 1; /* error flag */
ret = -ret;
} else {
@@ -2302,8 +2340,55 @@ done_syscall:
info.si_code = TARGET_ILL_ILLOPC;
queue_signal(env, info.si_signo, &info);
break;
+ /* The code below was inspired by the MIPS Linux kernel trap
+ * handling code in arch/mips/kernel/traps.c.
+ */
+ case EXCP_BREAK:
+ {
+ abi_ulong trap_instr;
+ unsigned int code;
+
+ ret = get_user_ual(trap_instr, env->active_tc.PC);
+ if (ret != 0) {
+ goto error;
+ }
+
+ /* As described in the original Linux kernel code, the
+ * below checks on 'code' are to work around an old
+ * assembly bug.
+ */
+ code = ((trap_instr >> 6) & ((1 << 20) - 1));
+ if (code >= (1 << 10)) {
+ code >>= 10;
+ }
+
+ if (do_break(env, &info, code) != 0) {
+ goto error;
+ }
+ }
+ break;
+ case EXCP_TRAP:
+ {
+ abi_ulong trap_instr;
+ unsigned int code = 0;
+
+ ret = get_user_ual(trap_instr, env->active_tc.PC);
+ if (ret != 0) {
+ goto error;
+ }
+
+ /* The immediate versions don't provide a code. */
+ if (!(trap_instr & 0xFC000000)) {
+ code = ((trap_instr >> 6) & ((1 << 10) - 1));
+ }
+
+ if (do_break(env, &info, code) != 0) {
+ goto error;
+ }
+ }
+ break;
default:
- // error:
+error:
fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
trapnr);
cpu_dump_state(env, stderr, fprintf, 0);
diff --git a/linux-user/mips64/syscall.h b/linux-user/mips64/syscall.h
index e436ea57dc..cd707df32f 100644
--- a/linux-user/mips64/syscall.h
+++ b/linux-user/mips64/syscall.h
@@ -3,16 +3,16 @@
stack during a system call. */
struct target_pt_regs {
- /* Saved main processor registers. */
- abi_ulong regs[32];
+ /* Saved main processor registers. */
+ target_ulong regs[32];
- /* Saved special registers. */
- abi_ulong cp0_status;
- abi_ulong lo;
- abi_ulong hi;
- abi_ulong cp0_badvaddr;
- abi_ulong cp0_cause;
- abi_ulong cp0_epc;
+ /* Saved special registers. */
+ target_ulong cp0_status;
+ target_ulong lo;
+ target_ulong hi;
+ target_ulong cp0_badvaddr;
+ target_ulong cp0_cause;
+ target_ulong cp0_epc;
};
/* Target errno definitions taken from asm-mips/errno.h */
diff --git a/linux-user/mips64/syscall_nr.h b/linux-user/mips64/syscall_nr.h
index 36d27b5159..0f4a6b107b 100644
--- a/linux-user/mips64/syscall_nr.h
+++ b/linux-user/mips64/syscall_nr.h
@@ -1,306 +1,620 @@
+#ifdef TARGET_ABI32
+/*
+ * Linux N32 syscalls are in the range from 6000 to 6999.
+ */
+#define TARGET_NR_Linux 6000
+#define TARGET_NR_read (TARGET_NR_Linux + 0)
+#define TARGET_NR_write (TARGET_NR_Linux + 1)
+#define TARGET_NR_open (TARGET_NR_Linux + 2)
+#define TARGET_NR_close (TARGET_NR_Linux + 3)
+#define TARGET_NR_stat (TARGET_NR_Linux + 4)
+#define TARGET_NR_fstat (TARGET_NR_Linux + 5)
+#define TARGET_NR_lstat (TARGET_NR_Linux + 6)
+#define TARGET_NR_poll (TARGET_NR_Linux + 7)
+#define TARGET_NR_lseek (TARGET_NR_Linux + 8)
+#define TARGET_NR_mmap (TARGET_NR_Linux + 9)
+#define TARGET_NR_mprotect (TARGET_NR_Linux + 10)
+#define TARGET_NR_munmap (TARGET_NR_Linux + 11)
+#define TARGET_NR_brk (TARGET_NR_Linux + 12)
+#define TARGET_NR_rt_sigaction (TARGET_NR_Linux + 13)
+#define TARGET_NR_rt_sigprocmask (TARGET_NR_Linux + 14)
+#define TARGET_NR_ioctl (TARGET_NR_Linux + 15)
+#define TARGET_NR_pread64 (TARGET_NR_Linux + 16)
+#define TARGET_NR_pwrite64 (TARGET_NR_Linux + 17)
+#define TARGET_NR_readv (TARGET_NR_Linux + 18)
+#define TARGET_NR_writev (TARGET_NR_Linux + 19)
+#define TARGET_NR_access (TARGET_NR_Linux + 20)
+#define TARGET_NR_pipe (TARGET_NR_Linux + 21)
+#define TARGET_NR__newselect (TARGET_NR_Linux + 22)
+#define TARGET_NR_sched_yield (TARGET_NR_Linux + 23)
+#define TARGET_NR_mremap (TARGET_NR_Linux + 24)
+#define TARGET_NR_msync (TARGET_NR_Linux + 25)
+#define TARGET_NR_mincore (TARGET_NR_Linux + 26)
+#define TARGET_NR_madvise (TARGET_NR_Linux + 27)
+#define TARGET_NR_shmget (TARGET_NR_Linux + 28)
+#define TARGET_NR_shmat (TARGET_NR_Linux + 29)
+#define TARGET_NR_shmctl (TARGET_NR_Linux + 30)
+#define TARGET_NR_dup (TARGET_NR_Linux + 31)
+#define TARGET_NR_dup2 (TARGET_NR_Linux + 32)
+#define TARGET_NR_pause (TARGET_NR_Linux + 33)
+#define TARGET_NR_nanosleep (TARGET_NR_Linux + 34)
+#define TARGET_NR_getitimer (TARGET_NR_Linux + 35)
+#define TARGET_NR_setitimer (TARGET_NR_Linux + 36)
+#define TARGET_NR_alarm (TARGET_NR_Linux + 37)
+#define TARGET_NR_getpid (TARGET_NR_Linux + 38)
+#define TARGET_NR_sendfile (TARGET_NR_Linux + 39)
+#define TARGET_NR_socket (TARGET_NR_Linux + 40)
+#define TARGET_NR_connect (TARGET_NR_Linux + 41)
+#define TARGET_NR_accept (TARGET_NR_Linux + 42)
+#define TARGET_NR_sendto (TARGET_NR_Linux + 43)
+#define TARGET_NR_recvfrom (TARGET_NR_Linux + 44)
+#define TARGET_NR_sendmsg (TARGET_NR_Linux + 45)
+#define TARGET_NR_recvmsg (TARGET_NR_Linux + 46)
+#define TARGET_NR_shutdown (TARGET_NR_Linux + 47)
+#define TARGET_NR_bind (TARGET_NR_Linux + 48)
+#define TARGET_NR_listen (TARGET_NR_Linux + 49)
+#define TARGET_NR_getsockname (TARGET_NR_Linux + 50)
+#define TARGET_NR_getpeername (TARGET_NR_Linux + 51)
+#define TARGET_NR_socketpair (TARGET_NR_Linux + 52)
+#define TARGET_NR_setsockopt (TARGET_NR_Linux + 53)
+#define TARGET_NR_getsockopt (TARGET_NR_Linux + 54)
+#define TARGET_NR_clone (TARGET_NR_Linux + 55)
+#define TARGET_NR_fork (TARGET_NR_Linux + 56)
+#define TARGET_NR_execve (TARGET_NR_Linux + 57)
+#define TARGET_NR_exit (TARGET_NR_Linux + 58)
+#define TARGET_NR_wait4 (TARGET_NR_Linux + 59)
+#define TARGET_NR_kill (TARGET_NR_Linux + 60)
+#define TARGET_NR_uname (TARGET_NR_Linux + 61)
+#define TARGET_NR_semget (TARGET_NR_Linux + 62)
+#define TARGET_NR_semop (TARGET_NR_Linux + 63)
+#define TARGET_NR_semctl (TARGET_NR_Linux + 64)
+#define TARGET_NR_shmdt (TARGET_NR_Linux + 65)
+#define TARGET_NR_msgget (TARGET_NR_Linux + 66)
+#define TARGET_NR_msgsnd (TARGET_NR_Linux + 67)
+#define TARGET_NR_msgrcv (TARGET_NR_Linux + 68)
+#define TARGET_NR_msgctl (TARGET_NR_Linux + 69)
+#define TARGET_NR_fcntl (TARGET_NR_Linux + 70)
+#define TARGET_NR_flock (TARGET_NR_Linux + 71)
+#define TARGET_NR_fsync (TARGET_NR_Linux + 72)
+#define TARGET_NR_fdatasync (TARGET_NR_Linux + 73)
+#define TARGET_NR_truncate (TARGET_NR_Linux + 74)
+#define TARGET_NR_ftruncate (TARGET_NR_Linux + 75)
+#define TARGET_NR_getdents (TARGET_NR_Linux + 76)
+#define TARGET_NR_getcwd (TARGET_NR_Linux + 77)
+#define TARGET_NR_chdir (TARGET_NR_Linux + 78)
+#define TARGET_NR_fchdir (TARGET_NR_Linux + 79)
+#define TARGET_NR_rename (TARGET_NR_Linux + 80)
+#define TARGET_NR_mkdir (TARGET_NR_Linux + 81)
+#define TARGET_NR_rmdir (TARGET_NR_Linux + 82)
+#define TARGET_NR_creat (TARGET_NR_Linux + 83)
+#define TARGET_NR_link (TARGET_NR_Linux + 84)
+#define TARGET_NR_unlink (TARGET_NR_Linux + 85)
+#define TARGET_NR_symlink (TARGET_NR_Linux + 86)
+#define TARGET_NR_readlink (TARGET_NR_Linux + 87)
+#define TARGET_NR_chmod (TARGET_NR_Linux + 88)
+#define TARGET_NR_fchmod (TARGET_NR_Linux + 89)
+#define TARGET_NR_chown (TARGET_NR_Linux + 90)
+#define TARGET_NR_fchown (TARGET_NR_Linux + 91)
+#define TARGET_NR_lchown (TARGET_NR_Linux + 92)
+#define TARGET_NR_umask (TARGET_NR_Linux + 93)
+#define TARGET_NR_gettimeofday (TARGET_NR_Linux + 94)
+#define TARGET_NR_getrlimit (TARGET_NR_Linux + 95)
+#define TARGET_NR_getrusage (TARGET_NR_Linux + 96)
+#define TARGET_NR_sysinfo (TARGET_NR_Linux + 97)
+#define TARGET_NR_times (TARGET_NR_Linux + 98)
+#define TARGET_NR_ptrace (TARGET_NR_Linux + 99)
+#define TARGET_NR_getuid (TARGET_NR_Linux + 100)
+#define TARGET_NR_syslog (TARGET_NR_Linux + 101)
+#define TARGET_NR_getgid (TARGET_NR_Linux + 102)
+#define TARGET_NR_setuid (TARGET_NR_Linux + 103)
+#define TARGET_NR_setgid (TARGET_NR_Linux + 104)
+#define TARGET_NR_geteuid (TARGET_NR_Linux + 105)
+#define TARGET_NR_getegid (TARGET_NR_Linux + 106)
+#define TARGET_NR_setpgid (TARGET_NR_Linux + 107)
+#define TARGET_NR_getppid (TARGET_NR_Linux + 108)
+#define TARGET_NR_getpgrp (TARGET_NR_Linux + 109)
+#define TARGET_NR_setsid (TARGET_NR_Linux + 110)
+#define TARGET_NR_setreuid (TARGET_NR_Linux + 111)
+#define TARGET_NR_setregid (TARGET_NR_Linux + 112)
+#define TARGET_NR_getgroups (TARGET_NR_Linux + 113)
+#define TARGET_NR_setgroups (TARGET_NR_Linux + 114)
+#define TARGET_NR_setresuid (TARGET_NR_Linux + 115)
+#define TARGET_NR_getresuid (TARGET_NR_Linux + 116)
+#define TARGET_NR_setresgid (TARGET_NR_Linux + 117)
+#define TARGET_NR_getresgid (TARGET_NR_Linux + 118)
+#define TARGET_NR_getpgid (TARGET_NR_Linux + 119)
+#define TARGET_NR_setfsuid (TARGET_NR_Linux + 120)
+#define TARGET_NR_setfsgid (TARGET_NR_Linux + 121)
+#define TARGET_NR_getsid (TARGET_NR_Linux + 122)
+#define TARGET_NR_capget (TARGET_NR_Linux + 123)
+#define TARGET_NR_capset (TARGET_NR_Linux + 124)
+#define TARGET_NR_rt_sigpending (TARGET_NR_Linux + 125)
+#define TARGET_NR_rt_sigtimedwait (TARGET_NR_Linux + 126)
+#define TARGET_NR_rt_sigqueueinfo (TARGET_NR_Linux + 127)
+#define TARGET_NR_rt_sigsuspend (TARGET_NR_Linux + 128)
+#define TARGET_NR_sigaltstack (TARGET_NR_Linux + 129)
+#define TARGET_NR_utime (TARGET_NR_Linux + 130)
+#define TARGET_NR_mknod (TARGET_NR_Linux + 131)
+#define TARGET_NR_personality (TARGET_NR_Linux + 132)
+#define TARGET_NR_ustat (TARGET_NR_Linux + 133)
+#define TARGET_NR_statfs (TARGET_NR_Linux + 134)
+#define TARGET_NR_fstatfs (TARGET_NR_Linux + 135)
+#define TARGET_NR_sysfs (TARGET_NR_Linux + 136)
+#define TARGET_NR_getpriority (TARGET_NR_Linux + 137)
+#define TARGET_NR_setpriority (TARGET_NR_Linux + 138)
+#define TARGET_NR_sched_setparam (TARGET_NR_Linux + 139)
+#define TARGET_NR_sched_getparam (TARGET_NR_Linux + 140)
+#define TARGET_NR_sched_setscheduler (TARGET_NR_Linux + 141)
+#define TARGET_NR_sched_getscheduler (TARGET_NR_Linux + 142)
+#define TARGET_NR_sched_get_priority_max (TARGET_NR_Linux + 143)
+#define TARGET_NR_sched_get_priority_min (TARGET_NR_Linux + 144)
+#define TARGET_NR_sched_rr_get_interval (TARGET_NR_Linux + 145)
+#define TARGET_NR_mlock (TARGET_NR_Linux + 146)
+#define TARGET_NR_munlock (TARGET_NR_Linux + 147)
+#define TARGET_NR_mlockall (TARGET_NR_Linux + 148)
+#define TARGET_NR_munlockall (TARGET_NR_Linux + 149)
+#define TARGET_NR_vhangup (TARGET_NR_Linux + 150)
+#define TARGET_NR_pivot_root (TARGET_NR_Linux + 151)
+#define TARGET_NR__sysctl (TARGET_NR_Linux + 152)
+#define TARGET_NR_prctl (TARGET_NR_Linux + 153)
+#define TARGET_NR_adjtimex (TARGET_NR_Linux + 154)
+#define TARGET_NR_setrlimit (TARGET_NR_Linux + 155)
+#define TARGET_NR_chroot (TARGET_NR_Linux + 156)
+#define TARGET_NR_sync (TARGET_NR_Linux + 157)
+#define TARGET_NR_acct (TARGET_NR_Linux + 158)
+#define TARGET_NR_settimeofday (TARGET_NR_Linux + 159)
+#define TARGET_NR_mount (TARGET_NR_Linux + 160)
+#define TARGET_NR_umount2 (TARGET_NR_Linux + 161)
+#define TARGET_NR_swapon (TARGET_NR_Linux + 162)
+#define TARGET_NR_swapoff (TARGET_NR_Linux + 163)
+#define TARGET_NR_reboot (TARGET_NR_Linux + 164)
+#define TARGET_NR_sethostname (TARGET_NR_Linux + 165)
+#define TARGET_NR_setdomainname (TARGET_NR_Linux + 166)
+#define TARGET_NR_create_module (TARGET_NR_Linux + 167)
+#define TARGET_NR_init_module (TARGET_NR_Linux + 168)
+#define TARGET_NR_delete_module (TARGET_NR_Linux + 169)
+#define TARGET_NR_get_kernel_syms (TARGET_NR_Linux + 170)
+#define TARGET_NR_query_module (TARGET_NR_Linux + 171)
+#define TARGET_NR_quotactl (TARGET_NR_Linux + 172)
+#define TARGET_NR_nfsservctl (TARGET_NR_Linux + 173)
+#define TARGET_NR_getpmsg (TARGET_NR_Linux + 174)
+#define TARGET_NR_putpmsg (TARGET_NR_Linux + 175)
+#define TARGET_NR_afs_syscall (TARGET_NR_Linux + 176)
+#define TARGET_NR_reserved177 (TARGET_NR_Linux + 177)
+#define TARGET_NR_gettid (TARGET_NR_Linux + 178)
+#define TARGET_NR_readahead (TARGET_NR_Linux + 179)
+#define TARGET_NR_setxattr (TARGET_NR_Linux + 180)
+#define TARGET_NR_lsetxattr (TARGET_NR_Linux + 181)
+#define TARGET_NR_fsetxattr (TARGET_NR_Linux + 182)
+#define TARGET_NR_getxattr (TARGET_NR_Linux + 183)
+#define TARGET_NR_lgetxattr (TARGET_NR_Linux + 184)
+#define TARGET_NR_fgetxattr (TARGET_NR_Linux + 185)
+#define TARGET_NR_listxattr (TARGET_NR_Linux + 186)
+#define TARGET_NR_llistxattr (TARGET_NR_Linux + 187)
+#define TARGET_NR_flistxattr (TARGET_NR_Linux + 188)
+#define TARGET_NR_removexattr (TARGET_NR_Linux + 189)
+#define TARGET_NR_lremovexattr (TARGET_NR_Linux + 190)
+#define TARGET_NR_fremovexattr (TARGET_NR_Linux + 191)
+#define TARGET_NR_tkill (TARGET_NR_Linux + 192)
+#define TARGET_NR_reserved193 (TARGET_NR_Linux + 193)
+#define TARGET_NR_futex (TARGET_NR_Linux + 194)
+#define TARGET_NR_sched_setaffinity (TARGET_NR_Linux + 195)
+#define TARGET_NR_sched_getaffinity (TARGET_NR_Linux + 196)
+#define TARGET_NR_cacheflush (TARGET_NR_Linux + 197)
+#define TARGET_NR_cachectl (TARGET_NR_Linux + 198)
+#define TARGET_NR_sysmips (TARGET_NR_Linux + 199)
+#define TARGET_NR_io_setup (TARGET_NR_Linux + 200)
+#define TARGET_NR_io_destroy (TARGET_NR_Linux + 201)
+#define TARGET_NR_io_getevents (TARGET_NR_Linux + 202)
+#define TARGET_NR_io_submit (TARGET_NR_Linux + 203)
+#define TARGET_NR_io_cancel (TARGET_NR_Linux + 204)
+#define TARGET_NR_exit_group (TARGET_NR_Linux + 205)
+#define TARGET_NR_lookup_dcookie (TARGET_NR_Linux + 206)
+#define TARGET_NR_epoll_create (TARGET_NR_Linux + 207)
+#define TARGET_NR_epoll_ctl (TARGET_NR_Linux + 208)
+#define TARGET_NR_epoll_wait (TARGET_NR_Linux + 209)
+#define TARGET_NR_remap_file_pages (TARGET_NR_Linux + 210)
+#define TARGET_NR_rt_sigreturn (TARGET_NR_Linux + 211)
+#define TARGET_NR_fcntl64 (TARGET_NR_Linux + 212)
+#define TARGET_NR_set_tid_address (TARGET_NR_Linux + 213)
+#define TARGET_NR_restart_syscall (TARGET_NR_Linux + 214)
+#define TARGET_NR_semtimedop (TARGET_NR_Linux + 215)
+#define TARGET_NR_fadvise64 (TARGET_NR_Linux + 216)
+#define TARGET_NR_statfs64 (TARGET_NR_Linux + 217)
+#define TARGET_NR_fstatfs64 (TARGET_NR_Linux + 218)
+#define TARGET_NR_sendfile64 (TARGET_NR_Linux + 219)
+#define TARGET_NR_timer_create (TARGET_NR_Linux + 220)
+#define TARGET_NR_timer_settime (TARGET_NR_Linux + 221)
+#define TARGET_NR_timer_gettime (TARGET_NR_Linux + 222)
+#define TARGET_NR_timer_getoverrun (TARGET_NR_Linux + 223)
+#define TARGET_NR_timer_delete (TARGET_NR_Linux + 224)
+#define TARGET_NR_clock_settime (TARGET_NR_Linux + 225)
+#define TARGET_NR_clock_gettime (TARGET_NR_Linux + 226)
+#define TARGET_NR_clock_getres (TARGET_NR_Linux + 227)
+#define TARGET_NR_clock_nanosleep (TARGET_NR_Linux + 228)
+#define TARGET_NR_tgkill (TARGET_NR_Linux + 229)
+#define TARGET_NR_utimes (TARGET_NR_Linux + 230)
+#define TARGET_NR_mbind (TARGET_NR_Linux + 231)
+#define TARGET_NR_get_mempolicy (TARGET_NR_Linux + 232)
+#define TARGET_NR_set_mempolicy (TARGET_NR_Linux + 233)
+#define TARGET_NR_mq_open (TARGET_NR_Linux + 234)
+#define TARGET_NR_mq_unlink (TARGET_NR_Linux + 235)
+#define TARGET_NR_mq_timedsend (TARGET_NR_Linux + 236)
+#define TARGET_NR_mq_timedreceive (TARGET_NR_Linux + 237)
+#define TARGET_NR_mq_notify (TARGET_NR_Linux + 238)
+#define TARGET_NR_mq_getsetattr (TARGET_NR_Linux + 239)
+#define TARGET_NR_vserver (TARGET_NR_Linux + 240)
+#define TARGET_NR_waitid (TARGET_NR_Linux + 241)
+/* #define TARGET_NR_sys_setaltroot (TARGET_NR_Linux + 242) */
+#define TARGET_NR_add_key (TARGET_NR_Linux + 243)
+#define TARGET_NR_request_key (TARGET_NR_Linux + 244)
+#define TARGET_NR_keyctl (TARGET_NR_Linux + 245)
+#define TARGET_NR_set_thread_area (TARGET_NR_Linux + 246)
+#define TARGET_NR_inotify_init (TARGET_NR_Linux + 247)
+#define TARGET_NR_inotify_add_watch (TARGET_NR_Linux + 248)
+#define TARGET_NR_inotify_rm_watch (TARGET_NR_Linux + 249)
+#define TARGET_NR_migrate_pages (TARGET_NR_Linux + 250)
+#define TARGET_NR_openat (TARGET_NR_Linux + 251)
+#define TARGET_NR_mkdirat (TARGET_NR_Linux + 252)
+#define TARGET_NR_mknodat (TARGET_NR_Linux + 253)
+#define TARGET_NR_fchownat (TARGET_NR_Linux + 254)
+#define TARGET_NR_futimesat (TARGET_NR_Linux + 255)
+#define TARGET_NR_newfstatat (TARGET_NR_Linux + 256)
+#define TARGET_NR_unlinkat (TARGET_NR_Linux + 257)
+#define TARGET_NR_renameat (TARGET_NR_Linux + 258)
+#define TARGET_NR_linkat (TARGET_NR_Linux + 259)
+#define TARGET_NR_symlinkat (TARGET_NR_Linux + 260)
+#define TARGET_NR_readlinkat (TARGET_NR_Linux + 261)
+#define TARGET_NR_fchmodat (TARGET_NR_Linux + 262)
+#define TARGET_NR_faccessat (TARGET_NR_Linux + 263)
+#define TARGET_NR_pselect6 (TARGET_NR_Linux + 264)
+#define TARGET_NR_ppoll (TARGET_NR_Linux + 265)
+#define TARGET_NR_unshare (TARGET_NR_Linux + 266)
+#define TARGET_NR_splice (TARGET_NR_Linux + 267)
+#define TARGET_NR_sync_file_range (TARGET_NR_Linux + 268)
+#define TARGET_NR_tee (TARGET_NR_Linux + 269)
+#define TARGET_NR_vmsplice (TARGET_NR_Linux + 270)
+#define TARGET_NR_move_pages (TARGET_NR_Linux + 271)
+#define TARGET_NR_set_robust_list (TARGET_NR_Linux + 272)
+#define TARGET_NR_get_robust_list (TARGET_NR_Linux + 273)
+#define TARGET_NR_kexec_load (TARGET_NR_Linux + 274)
+#define TARGET_NR_getcpu (TARGET_NR_Linux + 275)
+#define TARGET_NR_epoll_pwait (TARGET_NR_Linux + 276)
+#define TARGET_NR_ioprio_set (TARGET_NR_Linux + 277)
+#define TARGET_NR_ioprio_get (TARGET_NR_Linux + 278)
+#define TARGET_NR_utimensat (TARGET_NR_Linux + 279)
+#define TARGET_NR_signalfd (TARGET_NR_Linux + 280)
+#define TARGET_NR_timerfd (TARGET_NR_Linux + 281)
+#define TARGET_NR_eventfd (TARGET_NR_Linux + 282)
+#define TARGET_NR_fallocate (TARGET_NR_Linux + 283)
+#define TARGET_NR_timerfd_create (TARGET_NR_Linux + 284)
+#define TARGET_NR_timerfd_gettime (TARGET_NR_Linux + 285)
+#define TARGET_NR_timerfd_settime (TARGET_NR_Linux + 286)
+#define TARGET_NR_signalfd4 (TARGET_NR_Linux + 287)
+#define TARGET_NR_eventfd2 (TARGET_NR_Linux + 288)
+#define TARGET_NR_epoll_create1 (TARGET_NR_Linux + 289)
+#define TARGET_NR_dup3 (TARGET_NR_Linux + 290)
+#define TARGET_NR_pipe2 (TARGET_NR_Linux + 291)
+#define TARGET_NR_inotify_init1 (TARGET_NR_Linux + 292)
+#define TARGET_NR_preadv (TARGET_NR_Linux + 293)
+#define TARGET_NR_pwritev (TARGET_NR_Linux + 294)
+#define TARGET_NR_rt_tgsigqueueinfo (TARGET_NR_Linux + 295)
+#define TARGET_NR_perf_event_open (TARGET_NR_Linux + 296)
+#define TARGET_NR_accept4 (TARGET_NR_Linux + 297)
+#define TARGET_NR_recvmmsg (TARGET_NR_Linux + 298)
+#define TARGET_NR_getdents64 (TARGET_NR_Linux + 299)
+#define TARGET_NR_fanotify_init (TARGET_NR_Linux + 300)
+#define TARGET_NR_fanotify_mark (TARGET_NR_Linux + 301)
+#define TARGET_NR_prlimit64 (TARGET_NR_Linux + 302)
+#define TARGET_NR_name_to_handle_at (TARGET_NR_Linux + 303)
+#define TARGET_NR_open_by_handle_at (TARGET_NR_Linux + 304)
+#define TARGET_NR_clock_adjtime (TARGET_NR_Linux + 305)
+#define TARGET_NR_syncfs (TARGET_NR_Linux + 306)
+#else
/*
* Linux 64-bit syscalls are in the range from 5000 to 5999.
*/
-#define TARGET_NR_Linux 5000
-#define TARGET_NR_read (TARGET_NR_Linux + 0)
-#define TARGET_NR_write (TARGET_NR_Linux + 1)
-#define TARGET_NR_open (TARGET_NR_Linux + 2)
-#define TARGET_NR_close (TARGET_NR_Linux + 3)
-#define TARGET_NR_stat (TARGET_NR_Linux + 4)
-#define TARGET_NR_fstat (TARGET_NR_Linux + 5)
-#define TARGET_NR_lstat (TARGET_NR_Linux + 6)
-#define TARGET_NR_poll (TARGET_NR_Linux + 7)
-#define TARGET_NR_lseek (TARGET_NR_Linux + 8)
-#define TARGET_NR_mmap (TARGET_NR_Linux + 9)
-#define TARGET_NR_mprotect (TARGET_NR_Linux + 10)
-#define TARGET_NR_munmap (TARGET_NR_Linux + 11)
-#define TARGET_NR_brk (TARGET_NR_Linux + 12)
-#define TARGET_NR_rt_sigaction (TARGET_NR_Linux + 13)
-#define TARGET_NR_rt_sigprocmask (TARGET_NR_Linux + 14)
-#define TARGET_NR_ioctl (TARGET_NR_Linux + 15)
-#define TARGET_NR_pread64 (TARGET_NR_Linux + 16)
-#define TARGET_NR_pwrite64 (TARGET_NR_Linux + 17)
-#define TARGET_NR_readv (TARGET_NR_Linux + 18)
-#define TARGET_NR_writev (TARGET_NR_Linux + 19)
-#define TARGET_NR_access (TARGET_NR_Linux + 20)
-#define TARGET_NR_pipe (TARGET_NR_Linux + 21)
-#define TARGET_NR__newselect (TARGET_NR_Linux + 22)
-#define TARGET_NR_sched_yield (TARGET_NR_Linux + 23)
-#define TARGET_NR_mremap (TARGET_NR_Linux + 24)
-#define TARGET_NR_msync (TARGET_NR_Linux + 25)
-#define TARGET_NR_mincore (TARGET_NR_Linux + 26)
-#define TARGET_NR_madvise (TARGET_NR_Linux + 27)
-#define TARGET_NR_shmget (TARGET_NR_Linux + 28)
-#define TARGET_NR_shmat (TARGET_NR_Linux + 29)
-#define TARGET_NR_shmctl (TARGET_NR_Linux + 30)
-#define TARGET_NR_dup (TARGET_NR_Linux + 31)
-#define TARGET_NR_dup2 (TARGET_NR_Linux + 32)
-#define TARGET_NR_pause (TARGET_NR_Linux + 33)
-#define TARGET_NR_nanosleep (TARGET_NR_Linux + 34)
-#define TARGET_NR_getitimer (TARGET_NR_Linux + 35)
-#define TARGET_NR_setitimer (TARGET_NR_Linux + 36)
-#define TARGET_NR_alarm (TARGET_NR_Linux + 37)
-#define TARGET_NR_getpid (TARGET_NR_Linux + 38)
-#define TARGET_NR_sendfile (TARGET_NR_Linux + 39)
-#define TARGET_NR_socket (TARGET_NR_Linux + 40)
-#define TARGET_NR_connect (TARGET_NR_Linux + 41)
-#define TARGET_NR_accept (TARGET_NR_Linux + 42)
-#define TARGET_NR_sendto (TARGET_NR_Linux + 43)
-#define TARGET_NR_recvfrom (TARGET_NR_Linux + 44)
-#define TARGET_NR_sendmsg (TARGET_NR_Linux + 45)
-#define TARGET_NR_recvmsg (TARGET_NR_Linux + 46)
-#define TARGET_NR_shutdown (TARGET_NR_Linux + 47)
-#define TARGET_NR_bind (TARGET_NR_Linux + 48)
-#define TARGET_NR_listen (TARGET_NR_Linux + 49)
-#define TARGET_NR_getsockname (TARGET_NR_Linux + 50)
-#define TARGET_NR_getpeername (TARGET_NR_Linux + 51)
-#define TARGET_NR_socketpair (TARGET_NR_Linux + 52)
-#define TARGET_NR_setsockopt (TARGET_NR_Linux + 53)
-#define TARGET_NR_getsockopt (TARGET_NR_Linux + 54)
-#define TARGET_NR_clone (TARGET_NR_Linux + 55)
-#define TARGET_NR_fork (TARGET_NR_Linux + 56)
-#define TARGET_NR_execve (TARGET_NR_Linux + 57)
-#define TARGET_NR_exit (TARGET_NR_Linux + 58)
-#define TARGET_NR_wait4 (TARGET_NR_Linux + 59)
-#define TARGET_NR_kill (TARGET_NR_Linux + 60)
-#define TARGET_NR_uname (TARGET_NR_Linux + 61)
-#define TARGET_NR_semget (TARGET_NR_Linux + 62)
-#define TARGET_NR_semop (TARGET_NR_Linux + 63)
-#define TARGET_NR_semctl (TARGET_NR_Linux + 64)
-#define TARGET_NR_shmdt (TARGET_NR_Linux + 65)
-#define TARGET_NR_msgget (TARGET_NR_Linux + 66)
-#define TARGET_NR_msgsnd (TARGET_NR_Linux + 67)
-#define TARGET_NR_msgrcv (TARGET_NR_Linux + 68)
-#define TARGET_NR_msgctl (TARGET_NR_Linux + 69)
-#define TARGET_NR_fcntl (TARGET_NR_Linux + 70)
-#define TARGET_NR_flock (TARGET_NR_Linux + 71)
-#define TARGET_NR_fsync (TARGET_NR_Linux + 72)
-#define TARGET_NR_fdatasync (TARGET_NR_Linux + 73)
-#define TARGET_NR_truncate (TARGET_NR_Linux + 74)
-#define TARGET_NR_ftruncate (TARGET_NR_Linux + 75)
-#define TARGET_NR_getdents (TARGET_NR_Linux + 76)
-#define TARGET_NR_getcwd (TARGET_NR_Linux + 77)
-#define TARGET_NR_chdir (TARGET_NR_Linux + 78)
-#define TARGET_NR_fchdir (TARGET_NR_Linux + 79)
-#define TARGET_NR_rename (TARGET_NR_Linux + 80)
-#define TARGET_NR_mkdir (TARGET_NR_Linux + 81)
-#define TARGET_NR_rmdir (TARGET_NR_Linux + 82)
-#define TARGET_NR_creat (TARGET_NR_Linux + 83)
-#define TARGET_NR_link (TARGET_NR_Linux + 84)
-#define TARGET_NR_unlink (TARGET_NR_Linux + 85)
-#define TARGET_NR_symlink (TARGET_NR_Linux + 86)
-#define TARGET_NR_readlink (TARGET_NR_Linux + 87)
-#define TARGET_NR_chmod (TARGET_NR_Linux + 88)
-#define TARGET_NR_fchmod (TARGET_NR_Linux + 89)
-#define TARGET_NR_chown (TARGET_NR_Linux + 90)
-#define TARGET_NR_fchown (TARGET_NR_Linux + 91)
-#define TARGET_NR_lchown (TARGET_NR_Linux + 92)
-#define TARGET_NR_umask (TARGET_NR_Linux + 93)
-#define TARGET_NR_gettimeofday (TARGET_NR_Linux + 94)
-#define TARGET_NR_getrlimit (TARGET_NR_Linux + 95)
-#define TARGET_NR_getrusage (TARGET_NR_Linux + 96)
-#define TARGET_NR_sysinfo (TARGET_NR_Linux + 97)
-#define TARGET_NR_times (TARGET_NR_Linux + 98)
-#define TARGET_NR_ptrace (TARGET_NR_Linux + 99)
-#define TARGET_NR_getuid (TARGET_NR_Linux + 100)
-#define TARGET_NR_syslog (TARGET_NR_Linux + 101)
-#define TARGET_NR_getgid (TARGET_NR_Linux + 102)
-#define TARGET_NR_setuid (TARGET_NR_Linux + 103)
-#define TARGET_NR_setgid (TARGET_NR_Linux + 104)
-#define TARGET_NR_geteuid (TARGET_NR_Linux + 105)
-#define TARGET_NR_getegid (TARGET_NR_Linux + 106)
-#define TARGET_NR_setpgid (TARGET_NR_Linux + 107)
-#define TARGET_NR_getppid (TARGET_NR_Linux + 108)
-#define TARGET_NR_getpgrp (TARGET_NR_Linux + 109)
-#define TARGET_NR_setsid (TARGET_NR_Linux + 110)
-#define TARGET_NR_setreuid (TARGET_NR_Linux + 111)
-#define TARGET_NR_setregid (TARGET_NR_Linux + 112)
-#define TARGET_NR_getgroups (TARGET_NR_Linux + 113)
-#define TARGET_NR_setgroups (TARGET_NR_Linux + 114)
-#define TARGET_NR_setresuid (TARGET_NR_Linux + 115)
-#define TARGET_NR_getresuid (TARGET_NR_Linux + 116)
-#define TARGET_NR_setresgid (TARGET_NR_Linux + 117)
-#define TARGET_NR_getresgid (TARGET_NR_Linux + 118)
-#define TARGET_NR_getpgid (TARGET_NR_Linux + 119)
-#define TARGET_NR_setfsuid (TARGET_NR_Linux + 120)
-#define TARGET_NR_setfsgid (TARGET_NR_Linux + 121)
-#define TARGET_NR_getsid (TARGET_NR_Linux + 122)
-#define TARGET_NR_capget (TARGET_NR_Linux + 123)
-#define TARGET_NR_capset (TARGET_NR_Linux + 124)
-#define TARGET_NR_rt_sigpending (TARGET_NR_Linux + 125)
-#define TARGET_NR_rt_sigtimedwait (TARGET_NR_Linux + 126)
-#define TARGET_NR_rt_sigqueueinfo (TARGET_NR_Linux + 127)
-#define TARGET_NR_rt_sigsuspend (TARGET_NR_Linux + 128)
-#define TARGET_NR_sigaltstack (TARGET_NR_Linux + 129)
-#define TARGET_NR_utime (TARGET_NR_Linux + 130)
-#define TARGET_NR_mknod (TARGET_NR_Linux + 131)
-#define TARGET_NR_personality (TARGET_NR_Linux + 132)
-#define TARGET_NR_ustat (TARGET_NR_Linux + 133)
-#define TARGET_NR_statfs (TARGET_NR_Linux + 134)
-#define TARGET_NR_fstatfs (TARGET_NR_Linux + 135)
-#define TARGET_NR_sysfs (TARGET_NR_Linux + 136)
-#define TARGET_NR_getpriority (TARGET_NR_Linux + 137)
-#define TARGET_NR_setpriority (TARGET_NR_Linux + 138)
-#define TARGET_NR_sched_setparam (TARGET_NR_Linux + 139)
-#define TARGET_NR_sched_getparam (TARGET_NR_Linux + 140)
-#define TARGET_NR_sched_setscheduler (TARGET_NR_Linux + 141)
-#define TARGET_NR_sched_getscheduler (TARGET_NR_Linux + 142)
-#define TARGET_NR_sched_get_priority_max (TARGET_NR_Linux + 143)
-#define TARGET_NR_sched_get_priority_min (TARGET_NR_Linux + 144)
-#define TARGET_NR_sched_rr_get_interval (TARGET_NR_Linux + 145)
-#define TARGET_NR_mlock (TARGET_NR_Linux + 146)
-#define TARGET_NR_munlock (TARGET_NR_Linux + 147)
-#define TARGET_NR_mlockall (TARGET_NR_Linux + 148)
-#define TARGET_NR_munlockall (TARGET_NR_Linux + 149)
-#define TARGET_NR_vhangup (TARGET_NR_Linux + 150)
-#define TARGET_NR_pivot_root (TARGET_NR_Linux + 151)
-#define TARGET_NR__sysctl (TARGET_NR_Linux + 152)
-#define TARGET_NR_prctl (TARGET_NR_Linux + 153)
-#define TARGET_NR_adjtimex (TARGET_NR_Linux + 154)
-#define TARGET_NR_setrlimit (TARGET_NR_Linux + 155)
-#define TARGET_NR_chroot (TARGET_NR_Linux + 156)
-#define TARGET_NR_sync (TARGET_NR_Linux + 157)
-#define TARGET_NR_acct (TARGET_NR_Linux + 158)
-#define TARGET_NR_settimeofday (TARGET_NR_Linux + 159)
-#define TARGET_NR_mount (TARGET_NR_Linux + 160)
-#define TARGET_NR_umount2 (TARGET_NR_Linux + 161)
-#define TARGET_NR_swapon (TARGET_NR_Linux + 162)
-#define TARGET_NR_swapoff (TARGET_NR_Linux + 163)
-#define TARGET_NR_reboot (TARGET_NR_Linux + 164)
-#define TARGET_NR_sethostname (TARGET_NR_Linux + 165)
-#define TARGET_NR_setdomainname (TARGET_NR_Linux + 166)
-#define TARGET_NR_create_module (TARGET_NR_Linux + 167)
-#define TARGET_NR_init_module (TARGET_NR_Linux + 168)
-#define TARGET_NR_delete_module (TARGET_NR_Linux + 169)
-#define TARGET_NR_get_kernel_syms (TARGET_NR_Linux + 170)
-#define TARGET_NR_query_module (TARGET_NR_Linux + 171)
-#define TARGET_NR_quotactl (TARGET_NR_Linux + 172)
-#define TARGET_NR_nfsservctl (TARGET_NR_Linux + 173)
-#define TARGET_NR_getpmsg (TARGET_NR_Linux + 174)
-#define TARGET_NR_putpmsg (TARGET_NR_Linux + 175)
-#define TARGET_NR_afs_syscall (TARGET_NR_Linux + 176)
-#define TARGET_NR_reserved177 (TARGET_NR_Linux + 177)
-#define TARGET_NR_gettid (TARGET_NR_Linux + 178)
-#define TARGET_NR_readahead (TARGET_NR_Linux + 179)
-#define TARGET_NR_setxattr (TARGET_NR_Linux + 180)
-#define TARGET_NR_lsetxattr (TARGET_NR_Linux + 181)
-#define TARGET_NR_fsetxattr (TARGET_NR_Linux + 182)
-#define TARGET_NR_getxattr (TARGET_NR_Linux + 183)
-#define TARGET_NR_lgetxattr (TARGET_NR_Linux + 184)
-#define TARGET_NR_fgetxattr (TARGET_NR_Linux + 185)
-#define TARGET_NR_listxattr (TARGET_NR_Linux + 186)
-#define TARGET_NR_llistxattr (TARGET_NR_Linux + 187)
-#define TARGET_NR_flistxattr (TARGET_NR_Linux + 188)
-#define TARGET_NR_removexattr (TARGET_NR_Linux + 189)
-#define TARGET_NR_lremovexattr (TARGET_NR_Linux + 190)
-#define TARGET_NR_fremovexattr (TARGET_NR_Linux + 191)
-#define TARGET_NR_tkill (TARGET_NR_Linux + 192)
-#define TARGET_NR_reserved193 (TARGET_NR_Linux + 193)
-#define TARGET_NR_futex (TARGET_NR_Linux + 194)
-#define TARGET_NR_sched_setaffinity (TARGET_NR_Linux + 195)
-#define TARGET_NR_sched_getaffinity (TARGET_NR_Linux + 196)
-#define TARGET_NR_cacheflush (TARGET_NR_Linux + 197)
-#define TARGET_NR_cachectl (TARGET_NR_Linux + 198)
-#define TARGET_NR_sysmips (TARGET_NR_Linux + 199)
-#define TARGET_NR_io_setup (TARGET_NR_Linux + 200)
-#define TARGET_NR_io_destroy (TARGET_NR_Linux + 201)
-#define TARGET_NR_io_getevents (TARGET_NR_Linux + 202)
-#define TARGET_NR_io_submit (TARGET_NR_Linux + 203)
-#define TARGET_NR_io_cancel (TARGET_NR_Linux + 204)
-#define TARGET_NR_exit_group (TARGET_NR_Linux + 205)
-#define TARGET_NR_lookup_dcookie (TARGET_NR_Linux + 206)
-#define TARGET_NR_epoll_create (TARGET_NR_Linux + 207)
-#define TARGET_NR_epoll_ctl (TARGET_NR_Linux + 208)
-#define TARGET_NR_epoll_wait (TARGET_NR_Linux + 209)
-#define TARGET_NR_remap_file_pages (TARGET_NR_Linux + 210)
-#define TARGET_NR_rt_sigreturn (TARGET_NR_Linux + 211)
-#define TARGET_NR_set_tid_address (TARGET_NR_Linux + 212)
-#define TARGET_NR_restart_syscall (TARGET_NR_Linux + 213)
-#define TARGET_NR_semtimedop (TARGET_NR_Linux + 214)
-#define TARGET_NR_fadvise64 (TARGET_NR_Linux + 215)
-#define TARGET_NR_timer_create (TARGET_NR_Linux + 216)
-#define TARGET_NR_timer_settime (TARGET_NR_Linux + 217)
-#define TARGET_NR_timer_gettime (TARGET_NR_Linux + 218)
-#define TARGET_NR_timer_getoverrun (TARGET_NR_Linux + 219)
-#define TARGET_NR_timer_delete (TARGET_NR_Linux + 220)
-#define TARGET_NR_clock_settime (TARGET_NR_Linux + 221)
-#define TARGET_NR_clock_gettime (TARGET_NR_Linux + 222)
-#define TARGET_NR_clock_getres (TARGET_NR_Linux + 223)
-#define TARGET_NR_clock_nanosleep (TARGET_NR_Linux + 224)
-#define TARGET_NR_tgkill (TARGET_NR_Linux + 225)
-#define TARGET_NR_utimes (TARGET_NR_Linux + 226)
-#define TARGET_NR_mbind (TARGET_NR_Linux + 227)
-#define TARGET_NR_get_mempolicy (TARGET_NR_Linux + 228)
-#define TARGET_NR_set_mempolicy (TARGET_NR_Linux + 229)
-#define TARGET_NR_mq_open (TARGET_NR_Linux + 230)
-#define TARGET_NR_mq_unlink (TARGET_NR_Linux + 231)
-#define TARGET_NR_mq_timedsend (TARGET_NR_Linux + 232)
-#define TARGET_NR_mq_timedreceive (TARGET_NR_Linux + 233)
-#define TARGET_NR_mq_notify (TARGET_NR_Linux + 234)
-#define TARGET_NR_mq_getsetattr (TARGET_NR_Linux + 235)
-#define TARGET_NR_vserver (TARGET_NR_Linux + 236)
-#define TARGET_NR_waitid (TARGET_NR_Linux + 237)
-/* #define TARGET_NR_sys_setaltroot (TARGET_NR_Linux + 238) */
-#define TARGET_NR_add_key (TARGET_NR_Linux + 239)
-#define TARGET_NR_request_key (TARGET_NR_Linux + 240)
-#define TARGET_NR_keyctl (TARGET_NR_Linux + 241)
-#define TARGET_NR_set_thread_area (TARGET_NR_Linux + 242)
-#define TARGET_NR_inotify_init (TARGET_NR_Linux + 243)
-#define TARGET_NR_inotify_add_watch (TARGET_NR_Linux + 244)
-#define TARGET_NR_inotify_rm_watch (TARGET_NR_Linux + 245)
-#define TARGET_NR_migrate_pages (TARGET_NR_Linux + 246)
-#define TARGET_NR_openat (TARGET_NR_Linux + 247)
-#define TARGET_NR_mkdirat (TARGET_NR_Linux + 248)
-#define TARGET_NR_mknodat (TARGET_NR_Linux + 249)
-#define TARGET_NR_fchownat (TARGET_NR_Linux + 250)
-#define TARGET_NR_futimesat (TARGET_NR_Linux + 251)
-#define TARGET_NR_newfstatat (TARGET_NR_Linux + 252)
-#define TARGET_NR_unlinkat (TARGET_NR_Linux + 253)
-#define TARGET_NR_renameat (TARGET_NR_Linux + 254)
-#define TARGET_NR_linkat (TARGET_NR_Linux + 255)
-#define TARGET_NR_symlinkat (TARGET_NR_Linux + 256)
-#define TARGET_NR_readlinkat (TARGET_NR_Linux + 257)
-#define TARGET_NR_fchmodat (TARGET_NR_Linux + 258)
-#define TARGET_NR_faccessat (TARGET_NR_Linux + 259)
-#define TARGET_NR_pselect6 (TARGET_NR_Linux + 260)
-#define TARGET_NR_ppoll (TARGET_NR_Linux + 261)
-#define TARGET_NR_unshare (TARGET_NR_Linux + 262)
-#define TARGET_NR_splice (TARGET_NR_Linux + 263)
-#define TARGET_NR_sync_file_range (TARGET_NR_Linux + 264)
-#define TARGET_NR_tee (TARGET_NR_Linux + 265)
-#define TARGET_NR_vmsplice (TARGET_NR_Linux + 266)
-#define TARGET_NR_move_pages (TARGET_NR_Linux + 267)
-#define TARGET_NR_set_robust_list (TARGET_NR_Linux + 268)
-#define TARGET_NR_get_robust_list (TARGET_NR_Linux + 269)
-#define TARGET_NR_kexec_load (TARGET_NR_Linux + 270)
-#define TARGET_NR_getcpu (TARGET_NR_Linux + 271)
-#define TARGET_NR_epoll_pwait (TARGET_NR_Linux + 272)
-#define TARGET_NR_ioprio_set (TARGET_NR_Linux + 273)
-#define TARGET_NR_ioprio_get (TARGET_NR_Linux + 274)
-#define TARGET_NR_utimensat (TARGET_NR_Linux + 275)
-#define TARGET_NR_signalfd (TARGET_NR_Linux + 276)
-#define TARGET_NR_timerfd (TARGET_NR_Linux + 277)
-#define TARGET_NR_eventfd (TARGET_NR_Linux + 278)
-#define TARGET_NR_fallocate (TARGET_NR_Linux + 279)
-#define TARGET_NR_timerfd_create (TARGET_NR_Linux + 280)
-#define TARGET_NR_timerfd_gettime (TARGET_NR_Linux + 281)
-#define TARGET_NR_timerfd_settime (TARGET_NR_Linux + 282)
-#define TARGET_NR_signalfd4 (TARGET_NR_Linux + 283)
-#define TARGET_NR_eventfd2 (TARGET_NR_Linux + 284)
-#define TARGET_NR_epoll_create1 (TARGET_NR_Linux + 285)
-#define TARGET_NR_dup3 (TARGET_NR_Linux + 286)
-#define TARGET_NR_pipe2 (TARGET_NR_Linux + 287)
-#define TARGET_NR_inotify_init1 (TARGET_NR_Linux + 288)
-#define TARGET_NR_preadv (TARGET_NR_Linux + 289)
-#define TARGET_NR_pwritev (TARGET_NR_Linux + 290)
-#define TARGET_NR_rt_tgsigqueueinfo (TARGET_NR_Linux + 291)
-#define TARGET_NR_perf_event_open (TARGET_NR_Linux + 292)
-#define TARGET_NR_accept4 (TARGET_NR_Linux + 293)
-#define TARGET_NR_recvmmsg (TARGET_NR_Linux + 294)
-#define TARGET_NR_fanotify_init (TARGET_NR_Linux + 295)
-#define TARGET_NR_fanotify_mark (TARGET_NR_Linux + 296)
-#define TARGET_NR_prlimit64 (TARGET_NR_Linux + 297)
-#define TARGET_NR_name_to_handle_at (TARGET_NR_Linux + 298)
-#define TARGET_NR_open_by_handle_at (TARGET_NR_Linux + 299)
-#define TARGET_NR_clock_adjtime (TARGET_NR_Linux + 300)
-#define TARGET_NR_syncfs (TARGET_NR_Linux + 301)
+#define TARGET_NR_Linux 5000
+#define TARGET_NR_read (TARGET_NR_Linux + 0)
+#define TARGET_NR_write (TARGET_NR_Linux + 1)
+#define TARGET_NR_open (TARGET_NR_Linux + 2)
+#define TARGET_NR_close (TARGET_NR_Linux + 3)
+#define TARGET_NR_stat (TARGET_NR_Linux + 4)
+#define TARGET_NR_fstat (TARGET_NR_Linux + 5)
+#define TARGET_NR_lstat (TARGET_NR_Linux + 6)
+#define TARGET_NR_poll (TARGET_NR_Linux + 7)
+#define TARGET_NR_lseek (TARGET_NR_Linux + 8)
+#define TARGET_NR_mmap (TARGET_NR_Linux + 9)
+#define TARGET_NR_mprotect (TARGET_NR_Linux + 10)
+#define TARGET_NR_munmap (TARGET_NR_Linux + 11)
+#define TARGET_NR_brk (TARGET_NR_Linux + 12)
+#define TARGET_NR_rt_sigaction (TARGET_NR_Linux + 13)
+#define TARGET_NR_rt_sigprocmask (TARGET_NR_Linux + 14)
+#define TARGET_NR_ioctl (TARGET_NR_Linux + 15)
+#define TARGET_NR_pread64 (TARGET_NR_Linux + 16)
+#define TARGET_NR_pwrite64 (TARGET_NR_Linux + 17)
+#define TARGET_NR_readv (TARGET_NR_Linux + 18)
+#define TARGET_NR_writev (TARGET_NR_Linux + 19)
+#define TARGET_NR_access (TARGET_NR_Linux + 20)
+#define TARGET_NR_pipe (TARGET_NR_Linux + 21)
+#define TARGET_NR__newselect (TARGET_NR_Linux + 22)
+#define TARGET_NR_sched_yield (TARGET_NR_Linux + 23)
+#define TARGET_NR_mremap (TARGET_NR_Linux + 24)
+#define TARGET_NR_msync (TARGET_NR_Linux + 25)
+#define TARGET_NR_mincore (TARGET_NR_Linux + 26)
+#define TARGET_NR_madvise (TARGET_NR_Linux + 27)
+#define TARGET_NR_shmget (TARGET_NR_Linux + 28)
+#define TARGET_NR_shmat (TARGET_NR_Linux + 29)
+#define TARGET_NR_shmctl (TARGET_NR_Linux + 30)
+#define TARGET_NR_dup (TARGET_NR_Linux + 31)
+#define TARGET_NR_dup2 (TARGET_NR_Linux + 32)
+#define TARGET_NR_pause (TARGET_NR_Linux + 33)
+#define TARGET_NR_nanosleep (TARGET_NR_Linux + 34)
+#define TARGET_NR_getitimer (TARGET_NR_Linux + 35)
+#define TARGET_NR_setitimer (TARGET_NR_Linux + 36)
+#define TARGET_NR_alarm (TARGET_NR_Linux + 37)
+#define TARGET_NR_getpid (TARGET_NR_Linux + 38)
+#define TARGET_NR_sendfile (TARGET_NR_Linux + 39)
+#define TARGET_NR_socket (TARGET_NR_Linux + 40)
+#define TARGET_NR_connect (TARGET_NR_Linux + 41)
+#define TARGET_NR_accept (TARGET_NR_Linux + 42)
+#define TARGET_NR_sendto (TARGET_NR_Linux + 43)
+#define TARGET_NR_recvfrom (TARGET_NR_Linux + 44)
+#define TARGET_NR_sendmsg (TARGET_NR_Linux + 45)
+#define TARGET_NR_recvmsg (TARGET_NR_Linux + 46)
+#define TARGET_NR_shutdown (TARGET_NR_Linux + 47)
+#define TARGET_NR_bind (TARGET_NR_Linux + 48)
+#define TARGET_NR_listen (TARGET_NR_Linux + 49)
+#define TARGET_NR_getsockname (TARGET_NR_Linux + 50)
+#define TARGET_NR_getpeername (TARGET_NR_Linux + 51)
+#define TARGET_NR_socketpair (TARGET_NR_Linux + 52)
+#define TARGET_NR_setsockopt (TARGET_NR_Linux + 53)
+#define TARGET_NR_getsockopt (TARGET_NR_Linux + 54)
+#define TARGET_NR_clone (TARGET_NR_Linux + 55)
+#define TARGET_NR_fork (TARGET_NR_Linux + 56)
+#define TARGET_NR_execve (TARGET_NR_Linux + 57)
+#define TARGET_NR_exit (TARGET_NR_Linux + 58)
+#define TARGET_NR_wait4 (TARGET_NR_Linux + 59)
+#define TARGET_NR_kill (TARGET_NR_Linux + 60)
+#define TARGET_NR_uname (TARGET_NR_Linux + 61)
+#define TARGET_NR_semget (TARGET_NR_Linux + 62)
+#define TARGET_NR_semop (TARGET_NR_Linux + 63)
+#define TARGET_NR_semctl (TARGET_NR_Linux + 64)
+#define TARGET_NR_shmdt (TARGET_NR_Linux + 65)
+#define TARGET_NR_msgget (TARGET_NR_Linux + 66)
+#define TARGET_NR_msgsnd (TARGET_NR_Linux + 67)
+#define TARGET_NR_msgrcv (TARGET_NR_Linux + 68)
+#define TARGET_NR_msgctl (TARGET_NR_Linux + 69)
+#define TARGET_NR_fcntl (TARGET_NR_Linux + 70)
+#define TARGET_NR_flock (TARGET_NR_Linux + 71)
+#define TARGET_NR_fsync (TARGET_NR_Linux + 72)
+#define TARGET_NR_fdatasync (TARGET_NR_Linux + 73)
+#define TARGET_NR_truncate (TARGET_NR_Linux + 74)
+#define TARGET_NR_ftruncate (TARGET_NR_Linux + 75)
+#define TARGET_NR_getdents (TARGET_NR_Linux + 76)
+#define TARGET_NR_getcwd (TARGET_NR_Linux + 77)
+#define TARGET_NR_chdir (TARGET_NR_Linux + 78)
+#define TARGET_NR_fchdir (TARGET_NR_Linux + 79)
+#define TARGET_NR_rename (TARGET_NR_Linux + 80)
+#define TARGET_NR_mkdir (TARGET_NR_Linux + 81)
+#define TARGET_NR_rmdir (TARGET_NR_Linux + 82)
+#define TARGET_NR_creat (TARGET_NR_Linux + 83)
+#define TARGET_NR_link (TARGET_NR_Linux + 84)
+#define TARGET_NR_unlink (TARGET_NR_Linux + 85)
+#define TARGET_NR_symlink (TARGET_NR_Linux + 86)
+#define TARGET_NR_readlink (TARGET_NR_Linux + 87)
+#define TARGET_NR_chmod (TARGET_NR_Linux + 88)
+#define TARGET_NR_fchmod (TARGET_NR_Linux + 89)
+#define TARGET_NR_chown (TARGET_NR_Linux + 90)
+#define TARGET_NR_fchown (TARGET_NR_Linux + 91)
+#define TARGET_NR_lchown (TARGET_NR_Linux + 92)
+#define TARGET_NR_umask (TARGET_NR_Linux + 93)
+#define TARGET_NR_gettimeofday (TARGET_NR_Linux + 94)
+#define TARGET_NR_getrlimit (TARGET_NR_Linux + 95)
+#define TARGET_NR_getrusage (TARGET_NR_Linux + 96)
+#define TARGET_NR_sysinfo (TARGET_NR_Linux + 97)
+#define TARGET_NR_times (TARGET_NR_Linux + 98)
+#define TARGET_NR_ptrace (TARGET_NR_Linux + 99)
+#define TARGET_NR_getuid (TARGET_NR_Linux + 100)
+#define TARGET_NR_syslog (TARGET_NR_Linux + 101)
+#define TARGET_NR_getgid (TARGET_NR_Linux + 102)
+#define TARGET_NR_setuid (TARGET_NR_Linux + 103)
+#define TARGET_NR_setgid (TARGET_NR_Linux + 104)
+#define TARGET_NR_geteuid (TARGET_NR_Linux + 105)
+#define TARGET_NR_getegid (TARGET_NR_Linux + 106)
+#define TARGET_NR_setpgid (TARGET_NR_Linux + 107)
+#define TARGET_NR_getppid (TARGET_NR_Linux + 108)
+#define TARGET_NR_getpgrp (TARGET_NR_Linux + 109)
+#define TARGET_NR_setsid (TARGET_NR_Linux + 110)
+#define TARGET_NR_setreuid (TARGET_NR_Linux + 111)
+#define TARGET_NR_setregid (TARGET_NR_Linux + 112)
+#define TARGET_NR_getgroups (TARGET_NR_Linux + 113)
+#define TARGET_NR_setgroups (TARGET_NR_Linux + 114)
+#define TARGET_NR_setresuid (TARGET_NR_Linux + 115)
+#define TARGET_NR_getresuid (TARGET_NR_Linux + 116)
+#define TARGET_NR_setresgid (TARGET_NR_Linux + 117)
+#define TARGET_NR_getresgid (TARGET_NR_Linux + 118)
+#define TARGET_NR_getpgid (TARGET_NR_Linux + 119)
+#define TARGET_NR_setfsuid (TARGET_NR_Linux + 120)
+#define TARGET_NR_setfsgid (TARGET_NR_Linux + 121)
+#define TARGET_NR_getsid (TARGET_NR_Linux + 122)
+#define TARGET_NR_capget (TARGET_NR_Linux + 123)
+#define TARGET_NR_capset (TARGET_NR_Linux + 124)
+#define TARGET_NR_rt_sigpending (TARGET_NR_Linux + 125)
+#define TARGET_NR_rt_sigtimedwait (TARGET_NR_Linux + 126)
+#define TARGET_NR_rt_sigqueueinfo (TARGET_NR_Linux + 127)
+#define TARGET_NR_rt_sigsuspend (TARGET_NR_Linux + 128)
+#define TARGET_NR_sigaltstack (TARGET_NR_Linux + 129)
+#define TARGET_NR_utime (TARGET_NR_Linux + 130)
+#define TARGET_NR_mknod (TARGET_NR_Linux + 131)
+#define TARGET_NR_personality (TARGET_NR_Linux + 132)
+#define TARGET_NR_ustat (TARGET_NR_Linux + 133)
+#define TARGET_NR_statfs (TARGET_NR_Linux + 134)
+#define TARGET_NR_fstatfs (TARGET_NR_Linux + 135)
+#define TARGET_NR_sysfs (TARGET_NR_Linux + 136)
+#define TARGET_NR_getpriority (TARGET_NR_Linux + 137)
+#define TARGET_NR_setpriority (TARGET_NR_Linux + 138)
+#define TARGET_NR_sched_setparam (TARGET_NR_Linux + 139)
+#define TARGET_NR_sched_getparam (TARGET_NR_Linux + 140)
+#define TARGET_NR_sched_setscheduler (TARGET_NR_Linux + 141)
+#define TARGET_NR_sched_getscheduler (TARGET_NR_Linux + 142)
+#define TARGET_NR_sched_get_priority_max (TARGET_NR_Linux + 143)
+#define TARGET_NR_sched_get_priority_min (TARGET_NR_Linux + 144)
+#define TARGET_NR_sched_rr_get_interval (TARGET_NR_Linux + 145)
+#define TARGET_NR_mlock (TARGET_NR_Linux + 146)
+#define TARGET_NR_munlock (TARGET_NR_Linux + 147)
+#define TARGET_NR_mlockall (TARGET_NR_Linux + 148)
+#define TARGET_NR_munlockall (TARGET_NR_Linux + 149)
+#define TARGET_NR_vhangup (TARGET_NR_Linux + 150)
+#define TARGET_NR_pivot_root (TARGET_NR_Linux + 151)
+#define TARGET_NR__sysctl (TARGET_NR_Linux + 152)
+#define TARGET_NR_prctl (TARGET_NR_Linux + 153)
+#define TARGET_NR_adjtimex (TARGET_NR_Linux + 154)
+#define TARGET_NR_setrlimit (TARGET_NR_Linux + 155)
+#define TARGET_NR_chroot (TARGET_NR_Linux + 156)
+#define TARGET_NR_sync (TARGET_NR_Linux + 157)
+#define TARGET_NR_acct (TARGET_NR_Linux + 158)
+#define TARGET_NR_settimeofday (TARGET_NR_Linux + 159)
+#define TARGET_NR_mount (TARGET_NR_Linux + 160)
+#define TARGET_NR_umount2 (TARGET_NR_Linux + 161)
+#define TARGET_NR_swapon (TARGET_NR_Linux + 162)
+#define TARGET_NR_swapoff (TARGET_NR_Linux + 163)
+#define TARGET_NR_reboot (TARGET_NR_Linux + 164)
+#define TARGET_NR_sethostname (TARGET_NR_Linux + 165)
+#define TARGET_NR_setdomainname (TARGET_NR_Linux + 166)
+#define TARGET_NR_create_module (TARGET_NR_Linux + 167)
+#define TARGET_NR_init_module (TARGET_NR_Linux + 168)
+#define TARGET_NR_delete_module (TARGET_NR_Linux + 169)
+#define TARGET_NR_get_kernel_syms (TARGET_NR_Linux + 170)
+#define TARGET_NR_query_module (TARGET_NR_Linux + 171)
+#define TARGET_NR_quotactl (TARGET_NR_Linux + 172)
+#define TARGET_NR_nfsservctl (TARGET_NR_Linux + 173)
+#define TARGET_NR_getpmsg (TARGET_NR_Linux + 174)
+#define TARGET_NR_putpmsg (TARGET_NR_Linux + 175)
+#define TARGET_NR_afs_syscall (TARGET_NR_Linux + 176)
+#define TARGET_NR_reserved177 (TARGET_NR_Linux + 177)
+#define TARGET_NR_gettid (TARGET_NR_Linux + 178)
+#define TARGET_NR_readahead (TARGET_NR_Linux + 179)
+#define TARGET_NR_setxattr (TARGET_NR_Linux + 180)
+#define TARGET_NR_lsetxattr (TARGET_NR_Linux + 181)
+#define TARGET_NR_fsetxattr (TARGET_NR_Linux + 182)
+#define TARGET_NR_getxattr (TARGET_NR_Linux + 183)
+#define TARGET_NR_lgetxattr (TARGET_NR_Linux + 184)
+#define TARGET_NR_fgetxattr (TARGET_NR_Linux + 185)
+#define TARGET_NR_listxattr (TARGET_NR_Linux + 186)
+#define TARGET_NR_llistxattr (TARGET_NR_Linux + 187)
+#define TARGET_NR_flistxattr (TARGET_NR_Linux + 188)
+#define TARGET_NR_removexattr (TARGET_NR_Linux + 189)
+#define TARGET_NR_lremovexattr (TARGET_NR_Linux + 190)
+#define TARGET_NR_fremovexattr (TARGET_NR_Linux + 191)
+#define TARGET_NR_tkill (TARGET_NR_Linux + 192)
+#define TARGET_NR_reserved193 (TARGET_NR_Linux + 193)
+#define TARGET_NR_futex (TARGET_NR_Linux + 194)
+#define TARGET_NR_sched_setaffinity (TARGET_NR_Linux + 195)
+#define TARGET_NR_sched_getaffinity (TARGET_NR_Linux + 196)
+#define TARGET_NR_cacheflush (TARGET_NR_Linux + 197)
+#define TARGET_NR_cachectl (TARGET_NR_Linux + 198)
+#define TARGET_NR_sysmips (TARGET_NR_Linux + 199)
+#define TARGET_NR_io_setup (TARGET_NR_Linux + 200)
+#define TARGET_NR_io_destroy (TARGET_NR_Linux + 201)
+#define TARGET_NR_io_getevents (TARGET_NR_Linux + 202)
+#define TARGET_NR_io_submit (TARGET_NR_Linux + 203)
+#define TARGET_NR_io_cancel (TARGET_NR_Linux + 204)
+#define TARGET_NR_exit_group (TARGET_NR_Linux + 205)
+#define TARGET_NR_lookup_dcookie (TARGET_NR_Linux + 206)
+#define TARGET_NR_epoll_create (TARGET_NR_Linux + 207)
+#define TARGET_NR_epoll_ctl (TARGET_NR_Linux + 208)
+#define TARGET_NR_epoll_wait (TARGET_NR_Linux + 209)
+#define TARGET_NR_remap_file_pages (TARGET_NR_Linux + 210)
+#define TARGET_NR_rt_sigreturn (TARGET_NR_Linux + 211)
+#define TARGET_NR_set_tid_address (TARGET_NR_Linux + 212)
+#define TARGET_NR_restart_syscall (TARGET_NR_Linux + 213)
+#define TARGET_NR_semtimedop (TARGET_NR_Linux + 214)
+#define TARGET_NR_fadvise64 (TARGET_NR_Linux + 215)
+#define TARGET_NR_timer_create (TARGET_NR_Linux + 216)
+#define TARGET_NR_timer_settime (TARGET_NR_Linux + 217)
+#define TARGET_NR_timer_gettime (TARGET_NR_Linux + 218)
+#define TARGET_NR_timer_getoverrun (TARGET_NR_Linux + 219)
+#define TARGET_NR_timer_delete (TARGET_NR_Linux + 220)
+#define TARGET_NR_clock_settime (TARGET_NR_Linux + 221)
+#define TARGET_NR_clock_gettime (TARGET_NR_Linux + 222)
+#define TARGET_NR_clock_getres (TARGET_NR_Linux + 223)
+#define TARGET_NR_clock_nanosleep (TARGET_NR_Linux + 224)
+#define TARGET_NR_tgkill (TARGET_NR_Linux + 225)
+#define TARGET_NR_utimes (TARGET_NR_Linux + 226)
+#define TARGET_NR_mbind (TARGET_NR_Linux + 227)
+#define TARGET_NR_get_mempolicy (TARGET_NR_Linux + 228)
+#define TARGET_NR_set_mempolicy (TARGET_NR_Linux + 229)
+#define TARGET_NR_mq_open (TARGET_NR_Linux + 230)
+#define TARGET_NR_mq_unlink (TARGET_NR_Linux + 231)
+#define TARGET_NR_mq_timedsend (TARGET_NR_Linux + 232)
+#define TARGET_NR_mq_timedreceive (TARGET_NR_Linux + 233)
+#define TARGET_NR_mq_notify (TARGET_NR_Linux + 234)
+#define TARGET_NR_mq_getsetattr (TARGET_NR_Linux + 235)
+#define TARGET_NR_vserver (TARGET_NR_Linux + 236)
+#define TARGET_NR_waitid (TARGET_NR_Linux + 237)
+/* #define TARGET_NR_sys_setaltroot (TARGET_NR_Linux + 238) */
+#define TARGET_NR_add_key (TARGET_NR_Linux + 239)
+#define TARGET_NR_request_key (TARGET_NR_Linux + 240)
+#define TARGET_NR_keyctl (TARGET_NR_Linux + 241)
+#define TARGET_NR_set_thread_area (TARGET_NR_Linux + 242)
+#define TARGET_NR_inotify_init (TARGET_NR_Linux + 243)
+#define TARGET_NR_inotify_add_watch (TARGET_NR_Linux + 244)
+#define TARGET_NR_inotify_rm_watch (TARGET_NR_Linux + 245)
+#define TARGET_NR_migrate_pages (TARGET_NR_Linux + 246)
+#define TARGET_NR_openat (TARGET_NR_Linux + 247)
+#define TARGET_NR_mkdirat (TARGET_NR_Linux + 248)
+#define TARGET_NR_mknodat (TARGET_NR_Linux + 249)
+#define TARGET_NR_fchownat (TARGET_NR_Linux + 250)
+#define TARGET_NR_futimesat (TARGET_NR_Linux + 251)
+#define TARGET_NR_newfstatat (TARGET_NR_Linux + 252)
+#define TARGET_NR_unlinkat (TARGET_NR_Linux + 253)
+#define TARGET_NR_renameat (TARGET_NR_Linux + 254)
+#define TARGET_NR_linkat (TARGET_NR_Linux + 255)
+#define TARGET_NR_symlinkat (TARGET_NR_Linux + 256)
+#define TARGET_NR_readlinkat (TARGET_NR_Linux + 257)
+#define TARGET_NR_fchmodat (TARGET_NR_Linux + 258)
+#define TARGET_NR_faccessat (TARGET_NR_Linux + 259)
+#define TARGET_NR_pselect6 (TARGET_NR_Linux + 260)
+#define TARGET_NR_ppoll (TARGET_NR_Linux + 261)
+#define TARGET_NR_unshare (TARGET_NR_Linux + 262)
+#define TARGET_NR_splice (TARGET_NR_Linux + 263)
+#define TARGET_NR_sync_file_range (TARGET_NR_Linux + 264)
+#define TARGET_NR_tee (TARGET_NR_Linux + 265)
+#define TARGET_NR_vmsplice (TARGET_NR_Linux + 266)
+#define TARGET_NR_move_pages (TARGET_NR_Linux + 267)
+#define TARGET_NR_set_robust_list (TARGET_NR_Linux + 268)
+#define TARGET_NR_get_robust_list (TARGET_NR_Linux + 269)
+#define TARGET_NR_kexec_load (TARGET_NR_Linux + 270)
+#define TARGET_NR_getcpu (TARGET_NR_Linux + 271)
+#define TARGET_NR_epoll_pwait (TARGET_NR_Linux + 272)
+#define TARGET_NR_ioprio_set (TARGET_NR_Linux + 273)
+#define TARGET_NR_ioprio_get (TARGET_NR_Linux + 274)
+#define TARGET_NR_utimensat (TARGET_NR_Linux + 275)
+#define TARGET_NR_signalfd (TARGET_NR_Linux + 276)
+#define TARGET_NR_timerfd (TARGET_NR_Linux + 277)
+#define TARGET_NR_eventfd (TARGET_NR_Linux + 278)
+#define TARGET_NR_fallocate (TARGET_NR_Linux + 279)
+#define TARGET_NR_timerfd_create (TARGET_NR_Linux + 280)
+#define TARGET_NR_timerfd_gettime (TARGET_NR_Linux + 281)
+#define TARGET_NR_timerfd_settime (TARGET_NR_Linux + 282)
+#define TARGET_NR_signalfd4 (TARGET_NR_Linux + 283)
+#define TARGET_NR_eventfd2 (TARGET_NR_Linux + 284)
+#define TARGET_NR_epoll_create1 (TARGET_NR_Linux + 285)
+#define TARGET_NR_dup3 (TARGET_NR_Linux + 286)
+#define TARGET_NR_pipe2 (TARGET_NR_Linux + 287)
+#define TARGET_NR_inotify_init1 (TARGET_NR_Linux + 288)
+#define TARGET_NR_preadv (TARGET_NR_Linux + 289)
+#define TARGET_NR_pwritev (TARGET_NR_Linux + 290)
+#define TARGET_NR_rt_tgsigqueueinfo (TARGET_NR_Linux + 291)
+#define TARGET_NR_perf_event_open (TARGET_NR_Linux + 292)
+#define TARGET_NR_accept4 (TARGET_NR_Linux + 293)
+#define TARGET_NR_recvmmsg (TARGET_NR_Linux + 294)
+#define TARGET_NR_fanotify_init (TARGET_NR_Linux + 295)
+#define TARGET_NR_fanotify_mark (TARGET_NR_Linux + 296)
+#define TARGET_NR_prlimit64 (TARGET_NR_Linux + 297)
+#define TARGET_NR_name_to_handle_at (TARGET_NR_Linux + 298)
+#define TARGET_NR_open_by_handle_at (TARGET_NR_Linux + 299)
+#define TARGET_NR_clock_adjtime (TARGET_NR_Linux + 300)
+#define TARGET_NR_syncfs (TARGET_NR_Linux + 301)
+#endif
diff --git a/linux-user/mipsn32/syscall.h b/linux-user/mipsn32/syscall.h
deleted file mode 100644
index ebe98f2070..0000000000
--- a/linux-user/mipsn32/syscall.h
+++ /dev/null
@@ -1,224 +0,0 @@
-
-/* this struct defines the way the registers are stored on the
- stack during a system call. */
-
-struct target_pt_regs {
- /* Saved main processor registers. */
- target_ulong regs[32];
-
- /* Saved special registers. */
- target_ulong cp0_status;
- target_ulong lo;
- target_ulong hi;
- target_ulong cp0_badvaddr;
- target_ulong cp0_cause;
- target_ulong cp0_epc;
-};
-
-/* Target errno definitions taken from asm-mips/errno.h */
-#undef TARGET_ENOMSG
-#define TARGET_ENOMSG 35 /* Identifier removed */
-#undef TARGET_EIDRM
-#define TARGET_EIDRM 36 /* Identifier removed */
-#undef TARGET_ECHRNG
-#define TARGET_ECHRNG 37 /* Channel number out of range */
-#undef TARGET_EL2NSYNC
-#define TARGET_EL2NSYNC 38 /* Level 2 not synchronized */
-#undef TARGET_EL3HLT
-#define TARGET_EL3HLT 39 /* Level 3 halted */
-#undef TARGET_EL3RST
-#define TARGET_EL3RST 40 /* Level 3 reset */
-#undef TARGET_ELNRNG
-#define TARGET_ELNRNG 41 /* Link number out of range */
-#undef TARGET_EUNATCH
-#define TARGET_EUNATCH 42 /* Protocol driver not attached */
-#undef TARGET_ENOCSI
-#define TARGET_ENOCSI 43 /* No CSI structure available */
-#undef TARGET_EL2HLT
-#define TARGET_EL2HLT 44 /* Level 2 halted */
-#undef TARGET_EDEADLK
-#define TARGET_EDEADLK 45 /* Resource deadlock would occur */
-#undef TARGET_ENOLCK
-#define TARGET_ENOLCK 46 /* No record locks available */
-#undef TARGET_EBADE
-#define TARGET_EBADE 50 /* Invalid exchange */
-#undef TARGET_EBADR
-#define TARGET_EBADR 51 /* Invalid request descriptor */
-#undef TARGET_EXFULL
-#define TARGET_EXFULL 52 /* TARGET_Exchange full */
-#undef TARGET_ENOANO
-#define TARGET_ENOANO 53 /* No anode */
-#undef TARGET_EBADRQC
-#define TARGET_EBADRQC 54 /* Invalid request code */
-#undef TARGET_EBADSLT
-#define TARGET_EBADSLT 55 /* Invalid slot */
-#undef TARGET_EDEADLOCK
-#define TARGET_EDEADLOCK 56 /* File locking deadlock error */
-#undef TARGET_EBFONT
-#define TARGET_EBFONT 59 /* Bad font file format */
-#undef TARGET_ENOSTR
-#define TARGET_ENOSTR 60 /* Device not a stream */
-#undef TARGET_ENODATA
-#define TARGET_ENODATA 61 /* No data available */
-#undef TARGET_ETIME
-#define TARGET_ETIME 62 /* Timer expired */
-#undef TARGET_ENOSR
-#define TARGET_ENOSR 63 /* Out of streams resources */
-#undef TARGET_ENONET
-#define TARGET_ENONET 64 /* Machine is not on the network */
-#undef TARGET_ENOPKG
-#define TARGET_ENOPKG 65 /* Package not installed */
-#undef TARGET_EREMOTE
-#define TARGET_EREMOTE 66 /* Object is remote */
-#undef TARGET_ENOLINK
-#define TARGET_ENOLINK 67 /* Link has been severed */
-#undef TARGET_EADV
-#define TARGET_EADV 68 /* Advertise error */
-#undef TARGET_ESRMNT
-#define TARGET_ESRMNT 69 /* Srmount error */
-#undef TARGET_ECOMM
-#define TARGET_ECOMM 70 /* Communication error on send */
-#undef TARGET_EPROTO
-#define TARGET_EPROTO 71 /* Protocol error */
-#undef TARGET_EDOTDOT
-#define TARGET_EDOTDOT 73 /* RFS specific error */
-#undef TARGET_EMULTIHOP
-#define TARGET_EMULTIHOP 74 /* Multihop attempted */
-#undef TARGET_EBADMSG
-#define TARGET_EBADMSG 77 /* Not a data message */
-#undef TARGET_ENAMETOOLONG
-#define TARGET_ENAMETOOLONG 78 /* File name too long */
-#undef TARGET_EOVERFLOW
-#define TARGET_EOVERFLOW 79 /* Value too large for defined data type */
-#undef TARGET_ENOTUNIQ
-#define TARGET_ENOTUNIQ 80 /* Name not unique on network */
-#undef TARGET_EBADFD
-#define TARGET_EBADFD 81 /* File descriptor in bad state */
-#undef TARGET_EREMCHG
-#define TARGET_EREMCHG 82 /* Remote address changed */
-#undef TARGET_ELIBACC
-#define TARGET_ELIBACC 83 /* Can not access a needed shared library */
-#undef TARGET_ELIBBAD
-#define TARGET_ELIBBAD 84 /* Accessing a corrupted shared library */
-#undef TARGET_ELIBSCN
-#define TARGET_ELIBSCN 85 /* .lib section in a.out corrupted */
-#undef TARGET_ELIBMAX
-#define TARGET_ELIBMAX 86 /* Attempting to link in too many shared libraries */
-#undef TARGET_ELIBEXEC
-#define TARGET_ELIBEXEC 87 /* Cannot exec a shared library directly */
-#undef TARGET_EILSEQ
-#define TARGET_EILSEQ 88 /* Illegal byte sequence */
-#undef TARGET_ENOSYS
-#define TARGET_ENOSYS 89 /* Function not implemented */
-#undef TARGET_ELOOP
-#define TARGET_ELOOP 90 /* Too many symbolic links encountered */
-#undef TARGET_ERESTART
-#define TARGET_ERESTART 91 /* Interrupted system call should be restarted */
-#undef TARGET_ESTRPIPE
-#define TARGET_ESTRPIPE 92 /* Streams pipe error */
-#undef TARGET_ENOTEMPTY
-#define TARGET_ENOTEMPTY 93 /* Directory not empty */
-#undef TARGET_EUSERS
-#define TARGET_EUSERS 94 /* Too many users */
-#undef TARGET_ENOTSOCK
-#define TARGET_ENOTSOCK 95 /* Socket operation on non-socket */
-#undef TARGET_EDESTADDRREQ
-#define TARGET_EDESTADDRREQ 96 /* Destination address required */
-#undef TARGET_EMSGSIZE
-#define TARGET_EMSGSIZE 97 /* Message too long */
-#undef TARGET_EPROTOTYPE
-#define TARGET_EPROTOTYPE 98 /* Protocol wrong type for socket */
-#undef TARGET_ENOPROTOOPT
-#define TARGET_ENOPROTOOPT 99 /* Protocol not available */
-#undef TARGET_EPROTONOSUPPORT
-#define TARGET_EPROTONOSUPPORT 120 /* Protocol not supported */
-#undef TARGET_ESOCKTNOSUPPORT
-#define TARGET_ESOCKTNOSUPPORT 121 /* Socket type not supported */
-#undef TARGET_EOPNOTSUPP
-#define TARGET_EOPNOTSUPP 122 /* Operation not supported on transport endpoint */
-#undef TARGET_EPFNOSUPPORT
-#define TARGET_EPFNOSUPPORT 123 /* Protocol family not supported */
-#undef TARGET_EAFNOSUPPORT
-#define TARGET_EAFNOSUPPORT 124 /* Address family not supported by protocol */
-#undef TARGET_EADDRINUSE
-#define TARGET_EADDRINUSE 125 /* Address already in use */
-#undef TARGET_EADDRNOTAVAIL
-#define TARGET_EADDRNOTAVAIL 126 /* Cannot assign requested address */
-#undef TARGET_ENETDOWN
-#define TARGET_ENETDOWN 127 /* Network is down */
-#undef TARGET_ENETUNREACH
-#define TARGET_ENETUNREACH 128 /* Network is unreachable */
-#undef TARGET_ENETRESET
-#define TARGET_ENETRESET 129 /* Network dropped connection because of reset */
-#undef TARGET_ECONNABORTED
-#define TARGET_ECONNABORTED 130 /* Software caused connection abort */
-#undef TARGET_ECONNRESET
-#define TARGET_ECONNRESET 131 /* Connection reset by peer */
-#undef TARGET_ENOBUFS
-#define TARGET_ENOBUFS 132 /* No buffer space available */
-#undef TARGET_EISCONN
-#define TARGET_EISCONN 133 /* Transport endpoint is already connected */
-#undef TARGET_ENOTCONN
-#define TARGET_ENOTCONN 134 /* Transport endpoint is not connected */
-#undef TARGET_EUCLEAN
-#define TARGET_EUCLEAN 135 /* Structure needs cleaning */
-#undef TARGET_ENOTNAM
-#define TARGET_ENOTNAM 137 /* Not a XENIX named type file */
-#undef TARGET_ENAVAIL
-#define TARGET_ENAVAIL 138 /* No XENIX semaphores available */
-#undef TARGET_EISNAM
-#define TARGET_EISNAM 139 /* Is a named type file */
-#undef TARGET_EREMOTEIO
-#define TARGET_EREMOTEIO 140 /* Remote I/O error */
-#undef TARGET_EINIT
-#define TARGET_EINIT 141 /* Reserved */
-#undef TARGET_EREMDEV
-#define TARGET_EREMDEV 142 /* TARGET_Error 142 */
-#undef TARGET_ESHUTDOWN
-#define TARGET_ESHUTDOWN 143 /* Cannot send after transport endpoint shutdown */
-#undef TARGET_ETOOMANYREFS
-#define TARGET_ETOOMANYREFS 144 /* Too many references: cannot splice */
-#undef TARGET_ETIMEDOUT
-#define TARGET_ETIMEDOUT 145 /* Connection timed out */
-#undef TARGET_ECONNREFUSED
-#define TARGET_ECONNREFUSED 146 /* Connection refused */
-#undef TARGET_EHOSTDOWN
-#define TARGET_EHOSTDOWN 147 /* Host is down */
-#undef TARGET_EHOSTUNREACH
-#define TARGET_EHOSTUNREACH 148 /* No route to host */
-#undef TARGET_EALREADY
-#define TARGET_EALREADY 149 /* Operation already in progress */
-#undef TARGET_EINPROGRESS
-#define TARGET_EINPROGRESS 150 /* Operation now in progress */
-#undef TARGET_ESTALE
-#define TARGET_ESTALE 151 /* Stale NFS file handle */
-#undef TARGET_ECANCELED
-#define TARGET_ECANCELED 158 /* AIO operation canceled */
-/*
- * These error are Linux extensions.
- */
-#undef TARGET_ENOMEDIUM
-#define TARGET_ENOMEDIUM 159 /* No medium found */
-#undef TARGET_EMEDIUMTYPE
-#define TARGET_EMEDIUMTYPE 160 /* Wrong medium type */
-#undef TARGET_ENOKEY
-#define TARGET_ENOKEY 161 /* Required key not available */
-#undef TARGET_EKEYEXPIRED
-#define TARGET_EKEYEXPIRED 162 /* Key has expired */
-#undef TARGET_EKEYREVOKED
-#define TARGET_EKEYREVOKED 163 /* Key has been revoked */
-#undef TARGET_EKEYREJECTED
-#define TARGET_EKEYREJECTED 164 /* Key was rejected by service */
-
-/* for robust mutexes */
-#undef TARGET_EOWNERDEAD
-#define TARGET_EOWNERDEAD 165 /* Owner died */
-#undef TARGET_ENOTRECOVERABLE
-#define TARGET_ENOTRECOVERABLE 166 /* State not recoverable */
-
-
-
-/* Nasty hack: define a fake errno value for use by sigreturn. */
-#define TARGET_QEMU_ESIGRETURN 255
-
-#define UNAME_MACHINE "mips64"
diff --git a/linux-user/mipsn32/syscall_nr.h b/linux-user/mipsn32/syscall_nr.h
deleted file mode 100644
index 4e1aca3a9b..0000000000
--- a/linux-user/mipsn32/syscall_nr.h
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * Linux N32 syscalls are in the range from 6000 to 6999.
- */
-#define TARGET_NR_Linux 6000
-#define TARGET_NR_read (TARGET_NR_Linux + 0)
-#define TARGET_NR_write (TARGET_NR_Linux + 1)
-#define TARGET_NR_open (TARGET_NR_Linux + 2)
-#define TARGET_NR_close (TARGET_NR_Linux + 3)
-#define TARGET_NR_stat (TARGET_NR_Linux + 4)
-#define TARGET_NR_fstat (TARGET_NR_Linux + 5)
-#define TARGET_NR_lstat (TARGET_NR_Linux + 6)
-#define TARGET_NR_poll (TARGET_NR_Linux + 7)
-#define TARGET_NR_lseek (TARGET_NR_Linux + 8)
-#define TARGET_NR_mmap (TARGET_NR_Linux + 9)
-#define TARGET_NR_mprotect (TARGET_NR_Linux + 10)
-#define TARGET_NR_munmap (TARGET_NR_Linux + 11)
-#define TARGET_NR_brk (TARGET_NR_Linux + 12)
-#define TARGET_NR_rt_sigaction (TARGET_NR_Linux + 13)
-#define TARGET_NR_rt_sigprocmask (TARGET_NR_Linux + 14)
-#define TARGET_NR_ioctl (TARGET_NR_Linux + 15)
-#define TARGET_NR_pread64 (TARGET_NR_Linux + 16)
-#define TARGET_NR_pwrite64 (TARGET_NR_Linux + 17)
-#define TARGET_NR_readv (TARGET_NR_Linux + 18)
-#define TARGET_NR_writev (TARGET_NR_Linux + 19)
-#define TARGET_NR_access (TARGET_NR_Linux + 20)
-#define TARGET_NR_pipe (TARGET_NR_Linux + 21)
-#define TARGET_NR__newselect (TARGET_NR_Linux + 22)
-#define TARGET_NR_sched_yield (TARGET_NR_Linux + 23)
-#define TARGET_NR_mremap (TARGET_NR_Linux + 24)
-#define TARGET_NR_msync (TARGET_NR_Linux + 25)
-#define TARGET_NR_mincore (TARGET_NR_Linux + 26)
-#define TARGET_NR_madvise (TARGET_NR_Linux + 27)
-#define TARGET_NR_shmget (TARGET_NR_Linux + 28)
-#define TARGET_NR_shmat (TARGET_NR_Linux + 29)
-#define TARGET_NR_shmctl (TARGET_NR_Linux + 30)
-#define TARGET_NR_dup (TARGET_NR_Linux + 31)
-#define TARGET_NR_dup2 (TARGET_NR_Linux + 32)
-#define TARGET_NR_pause (TARGET_NR_Linux + 33)
-#define TARGET_NR_nanosleep (TARGET_NR_Linux + 34)
-#define TARGET_NR_getitimer (TARGET_NR_Linux + 35)
-#define TARGET_NR_setitimer (TARGET_NR_Linux + 36)
-#define TARGET_NR_alarm (TARGET_NR_Linux + 37)
-#define TARGET_NR_getpid (TARGET_NR_Linux + 38)
-#define TARGET_NR_sendfile (TARGET_NR_Linux + 39)
-#define TARGET_NR_socket (TARGET_NR_Linux + 40)
-#define TARGET_NR_connect (TARGET_NR_Linux + 41)
-#define TARGET_NR_accept (TARGET_NR_Linux + 42)
-#define TARGET_NR_sendto (TARGET_NR_Linux + 43)
-#define TARGET_NR_recvfrom (TARGET_NR_Linux + 44)
-#define TARGET_NR_sendmsg (TARGET_NR_Linux + 45)
-#define TARGET_NR_recvmsg (TARGET_NR_Linux + 46)
-#define TARGET_NR_shutdown (TARGET_NR_Linux + 47)
-#define TARGET_NR_bind (TARGET_NR_Linux + 48)
-#define TARGET_NR_listen (TARGET_NR_Linux + 49)
-#define TARGET_NR_getsockname (TARGET_NR_Linux + 50)
-#define TARGET_NR_getpeername (TARGET_NR_Linux + 51)
-#define TARGET_NR_socketpair (TARGET_NR_Linux + 52)
-#define TARGET_NR_setsockopt (TARGET_NR_Linux + 53)
-#define TARGET_NR_getsockopt (TARGET_NR_Linux + 54)
-#define TARGET_NR_clone (TARGET_NR_Linux + 55)
-#define TARGET_NR_fork (TARGET_NR_Linux + 56)
-#define TARGET_NR_execve (TARGET_NR_Linux + 57)
-#define TARGET_NR_exit (TARGET_NR_Linux + 58)
-#define TARGET_NR_wait4 (TARGET_NR_Linux + 59)
-#define TARGET_NR_kill (TARGET_NR_Linux + 60)
-#define TARGET_NR_uname (TARGET_NR_Linux + 61)
-#define TARGET_NR_semget (TARGET_NR_Linux + 62)
-#define TARGET_NR_semop (TARGET_NR_Linux + 63)
-#define TARGET_NR_semctl (TARGET_NR_Linux + 64)
-#define TARGET_NR_shmdt (TARGET_NR_Linux + 65)
-#define TARGET_NR_msgget (TARGET_NR_Linux + 66)
-#define TARGET_NR_msgsnd (TARGET_NR_Linux + 67)
-#define TARGET_NR_msgrcv (TARGET_NR_Linux + 68)
-#define TARGET_NR_msgctl (TARGET_NR_Linux + 69)
-#define TARGET_NR_fcntl (TARGET_NR_Linux + 70)
-#define TARGET_NR_flock (TARGET_NR_Linux + 71)
-#define TARGET_NR_fsync (TARGET_NR_Linux + 72)
-#define TARGET_NR_fdatasync (TARGET_NR_Linux + 73)
-#define TARGET_NR_truncate (TARGET_NR_Linux + 74)
-#define TARGET_NR_ftruncate (TARGET_NR_Linux + 75)
-#define TARGET_NR_getdents (TARGET_NR_Linux + 76)
-#define TARGET_NR_getcwd (TARGET_NR_Linux + 77)
-#define TARGET_NR_chdir (TARGET_NR_Linux + 78)
-#define TARGET_NR_fchdir (TARGET_NR_Linux + 79)
-#define TARGET_NR_rename (TARGET_NR_Linux + 80)
-#define TARGET_NR_mkdir (TARGET_NR_Linux + 81)
-#define TARGET_NR_rmdir (TARGET_NR_Linux + 82)
-#define TARGET_NR_creat (TARGET_NR_Linux + 83)
-#define TARGET_NR_link (TARGET_NR_Linux + 84)
-#define TARGET_NR_unlink (TARGET_NR_Linux + 85)
-#define TARGET_NR_symlink (TARGET_NR_Linux + 86)
-#define TARGET_NR_readlink (TARGET_NR_Linux + 87)
-#define TARGET_NR_chmod (TARGET_NR_Linux + 88)
-#define TARGET_NR_fchmod (TARGET_NR_Linux + 89)
-#define TARGET_NR_chown (TARGET_NR_Linux + 90)
-#define TARGET_NR_fchown (TARGET_NR_Linux + 91)
-#define TARGET_NR_lchown (TARGET_NR_Linux + 92)
-#define TARGET_NR_umask (TARGET_NR_Linux + 93)
-#define TARGET_NR_gettimeofday (TARGET_NR_Linux + 94)
-#define TARGET_NR_getrlimit (TARGET_NR_Linux + 95)
-#define TARGET_NR_getrusage (TARGET_NR_Linux + 96)
-#define TARGET_NR_sysinfo (TARGET_NR_Linux + 97)
-#define TARGET_NR_times (TARGET_NR_Linux + 98)
-#define TARGET_NR_ptrace (TARGET_NR_Linux + 99)
-#define TARGET_NR_getuid (TARGET_NR_Linux + 100)
-#define TARGET_NR_syslog (TARGET_NR_Linux + 101)
-#define TARGET_NR_getgid (TARGET_NR_Linux + 102)
-#define TARGET_NR_setuid (TARGET_NR_Linux + 103)
-#define TARGET_NR_setgid (TARGET_NR_Linux + 104)
-#define TARGET_NR_geteuid (TARGET_NR_Linux + 105)
-#define TARGET_NR_getegid (TARGET_NR_Linux + 106)
-#define TARGET_NR_setpgid (TARGET_NR_Linux + 107)
-#define TARGET_NR_getppid (TARGET_NR_Linux + 108)
-#define TARGET_NR_getpgrp (TARGET_NR_Linux + 109)
-#define TARGET_NR_setsid (TARGET_NR_Linux + 110)
-#define TARGET_NR_setreuid (TARGET_NR_Linux + 111)
-#define TARGET_NR_setregid (TARGET_NR_Linux + 112)
-#define TARGET_NR_getgroups (TARGET_NR_Linux + 113)
-#define TARGET_NR_setgroups (TARGET_NR_Linux + 114)
-#define TARGET_NR_setresuid (TARGET_NR_Linux + 115)
-#define TARGET_NR_getresuid (TARGET_NR_Linux + 116)
-#define TARGET_NR_setresgid (TARGET_NR_Linux + 117)
-#define TARGET_NR_getresgid (TARGET_NR_Linux + 118)
-#define TARGET_NR_getpgid (TARGET_NR_Linux + 119)
-#define TARGET_NR_setfsuid (TARGET_NR_Linux + 120)
-#define TARGET_NR_setfsgid (TARGET_NR_Linux + 121)
-#define TARGET_NR_getsid (TARGET_NR_Linux + 122)
-#define TARGET_NR_capget (TARGET_NR_Linux + 123)
-#define TARGET_NR_capset (TARGET_NR_Linux + 124)
-#define TARGET_NR_rt_sigpending (TARGET_NR_Linux + 125)
-#define TARGET_NR_rt_sigtimedwait (TARGET_NR_Linux + 126)
-#define TARGET_NR_rt_sigqueueinfo (TARGET_NR_Linux + 127)
-#define TARGET_NR_rt_sigsuspend (TARGET_NR_Linux + 128)
-#define TARGET_NR_sigaltstack (TARGET_NR_Linux + 129)
-#define TARGET_NR_utime (TARGET_NR_Linux + 130)
-#define TARGET_NR_mknod (TARGET_NR_Linux + 131)
-#define TARGET_NR_personality (TARGET_NR_Linux + 132)
-#define TARGET_NR_ustat (TARGET_NR_Linux + 133)
-#define TARGET_NR_statfs (TARGET_NR_Linux + 134)
-#define TARGET_NR_fstatfs (TARGET_NR_Linux + 135)
-#define TARGET_NR_sysfs (TARGET_NR_Linux + 136)
-#define TARGET_NR_getpriority (TARGET_NR_Linux + 137)
-#define TARGET_NR_setpriority (TARGET_NR_Linux + 138)
-#define TARGET_NR_sched_setparam (TARGET_NR_Linux + 139)
-#define TARGET_NR_sched_getparam (TARGET_NR_Linux + 140)
-#define TARGET_NR_sched_setscheduler (TARGET_NR_Linux + 141)
-#define TARGET_NR_sched_getscheduler (TARGET_NR_Linux + 142)
-#define TARGET_NR_sched_get_priority_max (TARGET_NR_Linux + 143)
-#define TARGET_NR_sched_get_priority_min (TARGET_NR_Linux + 144)
-#define TARGET_NR_sched_rr_get_interval (TARGET_NR_Linux + 145)
-#define TARGET_NR_mlock (TARGET_NR_Linux + 146)
-#define TARGET_NR_munlock (TARGET_NR_Linux + 147)
-#define TARGET_NR_mlockall (TARGET_NR_Linux + 148)
-#define TARGET_NR_munlockall (TARGET_NR_Linux + 149)
-#define TARGET_NR_vhangup (TARGET_NR_Linux + 150)
-#define TARGET_NR_pivot_root (TARGET_NR_Linux + 151)
-#define TARGET_NR__sysctl (TARGET_NR_Linux + 152)
-#define TARGET_NR_prctl (TARGET_NR_Linux + 153)
-#define TARGET_NR_adjtimex (TARGET_NR_Linux + 154)
-#define TARGET_NR_setrlimit (TARGET_NR_Linux + 155)
-#define TARGET_NR_chroot (TARGET_NR_Linux + 156)
-#define TARGET_NR_sync (TARGET_NR_Linux + 157)
-#define TARGET_NR_acct (TARGET_NR_Linux + 158)
-#define TARGET_NR_settimeofday (TARGET_NR_Linux + 159)
-#define TARGET_NR_mount (TARGET_NR_Linux + 160)
-#define TARGET_NR_umount2 (TARGET_NR_Linux + 161)
-#define TARGET_NR_swapon (TARGET_NR_Linux + 162)
-#define TARGET_NR_swapoff (TARGET_NR_Linux + 163)
-#define TARGET_NR_reboot (TARGET_NR_Linux + 164)
-#define TARGET_NR_sethostname (TARGET_NR_Linux + 165)
-#define TARGET_NR_setdomainname (TARGET_NR_Linux + 166)
-#define TARGET_NR_create_module (TARGET_NR_Linux + 167)
-#define TARGET_NR_init_module (TARGET_NR_Linux + 168)
-#define TARGET_NR_delete_module (TARGET_NR_Linux + 169)
-#define TARGET_NR_get_kernel_syms (TARGET_NR_Linux + 170)
-#define TARGET_NR_query_module (TARGET_NR_Linux + 171)
-#define TARGET_NR_quotactl (TARGET_NR_Linux + 172)
-#define TARGET_NR_nfsservctl (TARGET_NR_Linux + 173)
-#define TARGET_NR_getpmsg (TARGET_NR_Linux + 174)
-#define TARGET_NR_putpmsg (TARGET_NR_Linux + 175)
-#define TARGET_NR_afs_syscall (TARGET_NR_Linux + 176)
-#define TARGET_NR_reserved177 (TARGET_NR_Linux + 177)
-#define TARGET_NR_gettid (TARGET_NR_Linux + 178)
-#define TARGET_NR_readahead (TARGET_NR_Linux + 179)
-#define TARGET_NR_setxattr (TARGET_NR_Linux + 180)
-#define TARGET_NR_lsetxattr (TARGET_NR_Linux + 181)
-#define TARGET_NR_fsetxattr (TARGET_NR_Linux + 182)
-#define TARGET_NR_getxattr (TARGET_NR_Linux + 183)
-#define TARGET_NR_lgetxattr (TARGET_NR_Linux + 184)
-#define TARGET_NR_fgetxattr (TARGET_NR_Linux + 185)
-#define TARGET_NR_listxattr (TARGET_NR_Linux + 186)
-#define TARGET_NR_llistxattr (TARGET_NR_Linux + 187)
-#define TARGET_NR_flistxattr (TARGET_NR_Linux + 188)
-#define TARGET_NR_removexattr (TARGET_NR_Linux + 189)
-#define TARGET_NR_lremovexattr (TARGET_NR_Linux + 190)
-#define TARGET_NR_fremovexattr (TARGET_NR_Linux + 191)
-#define TARGET_NR_tkill (TARGET_NR_Linux + 192)
-#define TARGET_NR_reserved193 (TARGET_NR_Linux + 193)
-#define TARGET_NR_futex (TARGET_NR_Linux + 194)
-#define TARGET_NR_sched_setaffinity (TARGET_NR_Linux + 195)
-#define TARGET_NR_sched_getaffinity (TARGET_NR_Linux + 196)
-#define TARGET_NR_cacheflush (TARGET_NR_Linux + 197)
-#define TARGET_NR_cachectl (TARGET_NR_Linux + 198)
-#define TARGET_NR_sysmips (TARGET_NR_Linux + 199)
-#define TARGET_NR_io_setup (TARGET_NR_Linux + 200)
-#define TARGET_NR_io_destroy (TARGET_NR_Linux + 201)
-#define TARGET_NR_io_getevents (TARGET_NR_Linux + 202)
-#define TARGET_NR_io_submit (TARGET_NR_Linux + 203)
-#define TARGET_NR_io_cancel (TARGET_NR_Linux + 204)
-#define TARGET_NR_exit_group (TARGET_NR_Linux + 205)
-#define TARGET_NR_lookup_dcookie (TARGET_NR_Linux + 206)
-#define TARGET_NR_epoll_create (TARGET_NR_Linux + 207)
-#define TARGET_NR_epoll_ctl (TARGET_NR_Linux + 208)
-#define TARGET_NR_epoll_wait (TARGET_NR_Linux + 209)
-#define TARGET_NR_remap_file_pages (TARGET_NR_Linux + 210)
-#define TARGET_NR_rt_sigreturn (TARGET_NR_Linux + 211)
-#define TARGET_NR_fcntl64 (TARGET_NR_Linux + 212)
-#define TARGET_NR_set_tid_address (TARGET_NR_Linux + 213)
-#define TARGET_NR_restart_syscall (TARGET_NR_Linux + 214)
-#define TARGET_NR_semtimedop (TARGET_NR_Linux + 215)
-#define TARGET_NR_fadvise64 (TARGET_NR_Linux + 216)
-#define TARGET_NR_statfs64 (TARGET_NR_Linux + 217)
-#define TARGET_NR_fstatfs64 (TARGET_NR_Linux + 218)
-#define TARGET_NR_sendfile64 (TARGET_NR_Linux + 219)
-#define TARGET_NR_timer_create (TARGET_NR_Linux + 220)
-#define TARGET_NR_timer_settime (TARGET_NR_Linux + 221)
-#define TARGET_NR_timer_gettime (TARGET_NR_Linux + 222)
-#define TARGET_NR_timer_getoverrun (TARGET_NR_Linux + 223)
-#define TARGET_NR_timer_delete (TARGET_NR_Linux + 224)
-#define TARGET_NR_clock_settime (TARGET_NR_Linux + 225)
-#define TARGET_NR_clock_gettime (TARGET_NR_Linux + 226)
-#define TARGET_NR_clock_getres (TARGET_NR_Linux + 227)
-#define TARGET_NR_clock_nanosleep (TARGET_NR_Linux + 228)
-#define TARGET_NR_tgkill (TARGET_NR_Linux + 229)
-#define TARGET_NR_utimes (TARGET_NR_Linux + 230)
-#define TARGET_NR_mbind (TARGET_NR_Linux + 231)
-#define TARGET_NR_get_mempolicy (TARGET_NR_Linux + 232)
-#define TARGET_NR_set_mempolicy (TARGET_NR_Linux + 233)
-#define TARGET_NR_mq_open (TARGET_NR_Linux + 234)
-#define TARGET_NR_mq_unlink (TARGET_NR_Linux + 235)
-#define TARGET_NR_mq_timedsend (TARGET_NR_Linux + 236)
-#define TARGET_NR_mq_timedreceive (TARGET_NR_Linux + 237)
-#define TARGET_NR_mq_notify (TARGET_NR_Linux + 238)
-#define TARGET_NR_mq_getsetattr (TARGET_NR_Linux + 239)
-#define TARGET_NR_vserver (TARGET_NR_Linux + 240)
-#define TARGET_NR_waitid (TARGET_NR_Linux + 241)
-/* #define TARGET_NR_sys_setaltroot (TARGET_NR_Linux + 242) */
-#define TARGET_NR_add_key (TARGET_NR_Linux + 243)
-#define TARGET_NR_request_key (TARGET_NR_Linux + 244)
-#define TARGET_NR_keyctl (TARGET_NR_Linux + 245)
-#define TARGET_NR_set_thread_area (TARGET_NR_Linux + 246)
-#define TARGET_NR_inotify_init (TARGET_NR_Linux + 247)
-#define TARGET_NR_inotify_add_watch (TARGET_NR_Linux + 248)
-#define TARGET_NR_inotify_rm_watch (TARGET_NR_Linux + 249)
-#define TARGET_NR_migrate_pages (TARGET_NR_Linux + 250)
-#define TARGET_NR_openat (TARGET_NR_Linux + 251)
-#define TARGET_NR_mkdirat (TARGET_NR_Linux + 252)
-#define TARGET_NR_mknodat (TARGET_NR_Linux + 253)
-#define TARGET_NR_fchownat (TARGET_NR_Linux + 254)
-#define TARGET_NR_futimesat (TARGET_NR_Linux + 255)
-#define TARGET_NR_newfstatat (TARGET_NR_Linux + 256)
-#define TARGET_NR_unlinkat (TARGET_NR_Linux + 257)
-#define TARGET_NR_renameat (TARGET_NR_Linux + 258)
-#define TARGET_NR_linkat (TARGET_NR_Linux + 259)
-#define TARGET_NR_symlinkat (TARGET_NR_Linux + 260)
-#define TARGET_NR_readlinkat (TARGET_NR_Linux + 261)
-#define TARGET_NR_fchmodat (TARGET_NR_Linux + 262)
-#define TARGET_NR_faccessat (TARGET_NR_Linux + 263)
-#define TARGET_NR_pselect6 (TARGET_NR_Linux + 264)
-#define TARGET_NR_ppoll (TARGET_NR_Linux + 265)
-#define TARGET_NR_unshare (TARGET_NR_Linux + 266)
-#define TARGET_NR_splice (TARGET_NR_Linux + 267)
-#define TARGET_NR_sync_file_range (TARGET_NR_Linux + 268)
-#define TARGET_NR_tee (TARGET_NR_Linux + 269)
-#define TARGET_NR_vmsplice (TARGET_NR_Linux + 270)
-#define TARGET_NR_move_pages (TARGET_NR_Linux + 271)
-#define TARGET_NR_set_robust_list (TARGET_NR_Linux + 272)
-#define TARGET_NR_get_robust_list (TARGET_NR_Linux + 273)
-#define TARGET_NR_kexec_load (TARGET_NR_Linux + 274)
-#define TARGET_NR_getcpu (TARGET_NR_Linux + 275)
-#define TARGET_NR_epoll_pwait (TARGET_NR_Linux + 276)
-#define TARGET_NR_ioprio_set (TARGET_NR_Linux + 277)
-#define TARGET_NR_ioprio_get (TARGET_NR_Linux + 278)
-#define TARGET_NR_utimensat (TARGET_NR_Linux + 279)
-#define TARGET_NR_signalfd (TARGET_NR_Linux + 280)
-#define TARGET_NR_timerfd (TARGET_NR_Linux + 281)
-#define TARGET_NR_eventfd (TARGET_NR_Linux + 282)
-#define TARGET_NR_fallocate (TARGET_NR_Linux + 283)
-#define TARGET_NR_timerfd_create (TARGET_NR_Linux + 284)
-#define TARGET_NR_timerfd_gettime (TARGET_NR_Linux + 285)
-#define TARGET_NR_timerfd_settime (TARGET_NR_Linux + 286)
-#define TARGET_NR_signalfd4 (TARGET_NR_Linux + 287)
-#define TARGET_NR_eventfd2 (TARGET_NR_Linux + 288)
-#define TARGET_NR_epoll_create1 (TARGET_NR_Linux + 289)
-#define TARGET_NR_dup3 (TARGET_NR_Linux + 290)
-#define TARGET_NR_pipe2 (TARGET_NR_Linux + 291)
-#define TARGET_NR_inotify_init1 (TARGET_NR_Linux + 292)
-#define TARGET_NR_preadv (TARGET_NR_Linux + 293)
-#define TARGET_NR_pwritev (TARGET_NR_Linux + 294)
-#define TARGET_NR_rt_tgsigqueueinfo (TARGET_NR_Linux + 295)
-#define TARGET_NR_perf_event_open (TARGET_NR_Linux + 296)
-#define TARGET_NR_accept4 (TARGET_NR_Linux + 297)
-#define TARGET_NR_recvmmsg (TARGET_NR_Linux + 298)
-#define TARGET_NR_getdents64 (TARGET_NR_Linux + 299)
-#define TARGET_NR_fanotify_init (TARGET_NR_Linux + 300)
-#define TARGET_NR_fanotify_mark (TARGET_NR_Linux + 301)
-#define TARGET_NR_prlimit64 (TARGET_NR_Linux + 302)
-#define TARGET_NR_name_to_handle_at (TARGET_NR_Linux + 303)
-#define TARGET_NR_open_by_handle_at (TARGET_NR_Linux + 304)
-#define TARGET_NR_clock_adjtime (TARGET_NR_Linux + 305)
-#define TARGET_NR_syncfs (TARGET_NR_Linux + 306)
diff --git a/linux-user/mipsn32/target_signal.h b/linux-user/mipsn32/target_signal.h
deleted file mode 100644
index ff20d9e33e..0000000000
--- a/linux-user/mipsn32/target_signal.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef TARGET_SIGNAL_H
-#define TARGET_SIGNAL_H
-
-#include "cpu.h"
-
-/* this struct defines a stack used during syscall handling */
-
-typedef struct target_sigaltstack {
- int32_t ss_sp;
- uint32_t ss_size;
- int32_t ss_flags;
-} target_stack_t;
-
-
-/*
- * sigaltstack controls
- */
-#define TARGET_SS_ONSTACK 1
-#define TARGET_SS_DISABLE 2
-
-#define TARGET_MINSIGSTKSZ 2048
-#define TARGET_SIGSTKSZ 8192
-
-static inline target_ulong get_sp_from_cpustate(CPUMIPSState *state)
-{
- return state->active_tc.gpr[29];
-}
-
-#endif /* TARGET_SIGNAL_H */
diff --git a/linux-user/mipsn32/termbits.h b/linux-user/mipsn32/termbits.h
deleted file mode 100644
index d3a6cf8f91..0000000000
--- a/linux-user/mipsn32/termbits.h
+++ /dev/null
@@ -1,245 +0,0 @@
-/* from asm/termbits.h */
-
-#define TARGET_NCCS 23
-
-struct target_termios {
- unsigned int c_iflag; /* input mode flags */
- unsigned int c_oflag; /* output mode flags */
- unsigned int c_cflag; /* control mode flags */
- unsigned int c_lflag; /* local mode flags */
- unsigned char c_line; /* line discipline */
- unsigned char c_cc[TARGET_NCCS]; /* control characters */
-};
-
-/* c_iflag bits */
-#define TARGET_IGNBRK 0000001
-#define TARGET_BRKINT 0000002
-#define TARGET_IGNPAR 0000004
-#define TARGET_PARMRK 0000010
-#define TARGET_INPCK 0000020
-#define TARGET_ISTRIP 0000040
-#define TARGET_INLCR 0000100
-#define TARGET_IGNCR 0000200
-#define TARGET_ICRNL 0000400
-#define TARGET_IUCLC 0001000
-#define TARGET_IXON 0002000
-#define TARGET_IXANY 0004000
-#define TARGET_IXOFF 0010000
-#define TARGET_IMAXBEL 0020000
-#define TARGET_IUTF8 0040000
-
-/* c_oflag bits */
-#define TARGET_OPOST 0000001
-#define TARGET_OLCUC 0000002
-#define TARGET_ONLCR 0000004
-#define TARGET_OCRNL 0000010
-#define TARGET_ONOCR 0000020
-#define TARGET_ONLRET 0000040
-#define TARGET_OFILL 0000100
-#define TARGET_OFDEL 0000200
-#define TARGET_NLDLY 0000400
-#define TARGET_NL0 0000000
-#define TARGET_NL1 0000400
-#define TARGET_CRDLY 0003000
-#define TARGET_CR0 0000000
-#define TARGET_CR1 0001000
-#define TARGET_CR2 0002000
-#define TARGET_CR3 0003000
-#define TARGET_TABDLY 0014000
-#define TARGET_TAB0 0000000
-#define TARGET_TAB1 0004000
-#define TARGET_TAB2 0010000
-#define TARGET_TAB3 0014000
-#define TARGET_XTABS 0014000
-#define TARGET_BSDLY 0020000
-#define TARGET_BS0 0000000
-#define TARGET_BS1 0020000
-#define TARGET_VTDLY 0040000
-#define TARGET_VT0 0000000
-#define TARGET_VT1 0040000
-#define TARGET_FFDLY 0100000
-#define TARGET_FF0 0000000
-#define TARGET_FF1 0100000
-
-/* c_cflag bit meaning */
-#define TARGET_CBAUD 0010017
-#define TARGET_B0 0000000 /* hang up */
-#define TARGET_B50 0000001
-#define TARGET_B75 0000002
-#define TARGET_B110 0000003
-#define TARGET_B134 0000004
-#define TARGET_B150 0000005
-#define TARGET_B200 0000006
-#define TARGET_B300 0000007
-#define TARGET_B600 0000010
-#define TARGET_B1200 0000011
-#define TARGET_B1800 0000012
-#define TARGET_B2400 0000013
-#define TARGET_B4800 0000014
-#define TARGET_B9600 0000015
-#define TARGET_B19200 0000016
-#define TARGET_B38400 0000017
-#define TARGET_EXTA B19200
-#define TARGET_EXTB B38400
-#define TARGET_CSIZE 0000060
-#define TARGET_CS5 0000000
-#define TARGET_CS6 0000020
-#define TARGET_CS7 0000040
-#define TARGET_CS8 0000060
-#define TARGET_CSTOPB 0000100
-#define TARGET_CREAD 0000200
-#define TARGET_PARENB 0000400
-#define TARGET_PARODD 0001000
-#define TARGET_HUPCL 0002000
-#define TARGET_CLOCAL 0004000
-#define TARGET_CBAUDEX 0010000
-#define TARGET_BOTHER 0010000
-#define TARGET_B57600 0010001
-#define TARGET_B115200 0010002
-#define TARGET_B230400 0010003
-#define TARGET_B460800 0010004
-#define TARGET_B500000 0010005
-#define TARGET_B576000 0010006
-#define TARGET_B921600 0010007
-#define TARGET_B1000000 0010010
-#define TARGET_B1152000 0010011
-#define TARGET_B1500000 0010012
-#define TARGET_B2000000 0010013
-#define TARGET_B2500000 0010014
-#define TARGET_B3000000 0010015
-#define TARGET_B3500000 0010016
-#define TARGET_B4000000 0010017
-#define TARGET_CIBAUD 002003600000 /* input baud rate (not used) */
-#define TARGET_CMSPAR 010000000000 /* mark or space (stick) parity */
-#define TARGET_CRTSCTS 020000000000 /* flow control */
-
-/* c_lflag bits */
-#define TARGET_ISIG 0000001
-#define TARGET_ICANON 0000002
-#define TARGET_XCASE 0000004
-#define TARGET_ECHO 0000010
-#define TARGET_ECHOE 0000020
-#define TARGET_ECHOK 0000040
-#define TARGET_ECHONL 0000100
-#define TARGET_NOFLSH 0000200
-#define TARGET_IEXTEN 0000400
-#define TARGET_ECHOCTL 0001000
-#define TARGET_ECHOPRT 0002000
-#define TARGET_ECHOKE 0004000
-#define TARGET_FLUSHO 0010000
-#define TARGET_PENDIN 0040000
-#define TARGET_TOSTOP 0100000
-#define TARGET_ITOSTOP TARGET_TOSTOP
-
-/* c_cc character offsets */
-#define TARGET_VINTR 0
-#define TARGET_VQUIT 1
-#define TARGET_VERASE 2
-#define TARGET_VKILL 3
-#define TARGET_VMIN 4
-#define TARGET_VTIME 5
-#define TARGET_VEOL2 6
-#define TARGET_VSWTC 7
-#define TARGET_VSTART 8
-#define TARGET_VSTOP 9
-#define TARGET_VSUSP 10
-/* VDSUSP not supported */
-#define TARGET_VREPRINT 12
-#define TARGET_VDISCARD 13
-#define TARGET_VWERASE 14
-#define TARGET_VLNEXT 15
-#define TARGET_VEOF 16
-#define TARGET_VEOL 17
-
-/* ioctls */
-
-#define TARGET_TCGETA 0x5401
-#define TARGET_TCSETA 0x5402 /* Clashes with SNDCTL_TMR_START sound ioctl */
-#define TARGET_TCSETAW 0x5403
-#define TARGET_TCSETAF 0x5404
-
-#define TARGET_TCSBRK 0x5405
-#define TARGET_TCXONC 0x5406
-#define TARGET_TCFLSH 0x5407
-
-#define TARGET_TCGETS 0x540d
-#define TARGET_TCSETS 0x540e
-#define TARGET_TCSETSW 0x540f
-#define TARGET_TCSETSF 0x5410
-
-#define TARGET_TIOCEXCL 0x740d /* set exclusive use of tty */
-#define TARGET_TIOCNXCL 0x740e /* reset exclusive use of tty */
-#define TARGET_TIOCOUTQ 0x7472 /* output queue size */
-#define TARGET_TIOCSTI 0x5472 /* simulate terminal input */
-#define TARGET_TIOCMGET 0x741d /* get all modem bits */
-#define TARGET_TIOCMBIS 0x741b /* bis modem bits */
-#define TARGET_TIOCMBIC 0x741c /* bic modem bits */
-#define TARGET_TIOCMSET 0x741a /* set all modem bits */
-#define TARGET_TIOCPKT 0x5470 /* pty: set/clear packet mode */
-#define TARGET_TIOCPKT_DATA 0x00 /* data packet */
-#define TARGET_TIOCPKT_FLUSHREAD 0x01 /* flush packet */
-#define TARGET_TIOCPKT_FLUSHWRITE 0x02 /* flush packet */
-#define TARGET_TIOCPKT_STOP 0x04 /* stop output */
-#define TARGET_TIOCPKT_START 0x08 /* start output */
-#define TARGET_TIOCPKT_NOSTOP 0x10 /* no more ^S, ^Q */
-#define TARGET_TIOCPKT_DOSTOP 0x20 /* now do ^S ^Q */
-/* #define TIOCPKT_IOCTL 0x40 state change of pty driver */
-#define TARGET_TIOCSWINSZ TARGET_IOW('t', 103, struct winsize) /* set window size */
-#define TARGET_TIOCGWINSZ TARGET_IOR('t', 104, struct winsize) /* get window size */
-#define TARGET_TIOCNOTTY 0x5471 /* void tty association */
-#define TARGET_TIOCSETD 0x7401
-#define TARGET_TIOCGETD 0x7400
-
-#define TARGET_FIOCLEX 0x6601
-#define TARGET_FIONCLEX 0x6602
-#define TARGET_FIOASYNC 0x667d
-#define TARGET_FIONBIO 0x667e
-#define TARGET_FIOQSIZE 0x667f
-
-#define TARGET_TIOCGLTC 0x7474 /* get special local chars */
-#define TARGET_TIOCSLTC 0x7475 /* set special local chars */
-#define TARGET_TIOCSPGRP TARGET_IOW('t', 118, int) /* set pgrp of tty */
-#define TARGET_TIOCGPGRP TARGET_IOR('t', 119, int) /* get pgrp of tty */
-#define TARGET_TIOCCONS TARGET_IOW('t', 120, int) /* become virtual console */
-
-#define TARGET_FIONREAD 0x467f
-#define TARGET_TIOCINQ TARGET_FIONREAD
-
-#define TARGET_TIOCGETP 0x7408
-#define TARGET_TIOCSETP 0x7409
-#define TARGET_TIOCSETN 0x740a /* TIOCSETP wo flush */
-
-/* #define TARGET_TIOCSETA TARGET_IOW('t', 20, struct termios) set termios struct */
-/* #define TARGET_TIOCSETAW TARGET_IOW('t', 21, struct termios) drain output, set */
-/* #define TARGET_TIOCSETAF TARGET_IOW('t', 22, struct termios) drn out, fls in, set */
-/* #define TARGET_TIOCGETD TARGET_IOR('t', 26, int) get line discipline */
-/* #define TARGET_TIOCSETD TARGET_IOW('t', 27, int) set line discipline */
- /* 127-124 compat */
-
-#define TARGET_TIOCSBRK 0x5427 /* BSD compatibility */
-#define TARGET_TIOCCBRK 0x5428 /* BSD compatibility */
-#define TARGET_TIOCGSID 0x7416 /* Return the session ID of FD */
-#define TARGET_TIOCGPTN TARGET_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
-#define TARGET_TIOCSPTLCK TARGET_IOW('T',0x31, int) /* Lock/unlock Pty */
-
-/* I hope the range from 0x5480 on is free ... */
-#define TARGET_TIOCSCTTY 0x5480 /* become controlling tty */
-#define TARGET_TIOCGSOFTCAR 0x5481
-#define TARGET_TIOCSSOFTCAR 0x5482
-#define TARGET_TIOCLINUX 0x5483
-#define TARGET_TIOCGSERIAL 0x5484
-#define TARGET_TIOCSSERIAL 0x5485
-#define TARGET_TCSBRKP 0x5486 /* Needed for POSIX tcsendbreak() */
-#define TARGET_TIOCSERCONFIG 0x5488
-#define TARGET_TIOCSERGWILD 0x5489
-#define TARGET_TIOCSERSWILD 0x548a
-#define TARGET_TIOCGLCKTRMIOS 0x548b
-#define TARGET_TIOCSLCKTRMIOS 0x548c
-#define TARGET_TIOCSERGSTRUCT 0x548d /* For debugging only */
-#define TARGET_TIOCSERGETLSR 0x548e /* Get line status register */
-#define TARGET_TIOCSERGETMULTI 0x548f /* Get multiport config */
-#define TARGET_TIOCSERSETMULTI 0x5490 /* Set multiport config */
-#define TARGET_TIOCMIWAIT 0x5491 /* wait for a change on serial input line(s) */
-#define TARGET_TIOCGICOUNT 0x5492 /* read serial port inline interrupt counts */
-#define TARGET_TIOCGHAYESESP 0x5493 /* Get Hayes ESP configuration */
-#define TARGET_TIOCSHAYESESP 0x5494 /* Set Hayes ESP configuration */
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 67c23118a0..1055507224 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -2438,66 +2438,9 @@ void sparc64_get_context(CPUSPARCState *env)
force_sig(TARGET_SIGSEGV);
}
#endif
-#elif defined(TARGET_ABI_MIPSN64)
-
-# warning signal handling not implemented
-
-static void setup_frame(int sig, struct target_sigaction *ka,
- target_sigset_t *set, CPUMIPSState *env)
-{
- fprintf(stderr, "setup_frame: not implemented\n");
-}
-
-static void setup_rt_frame(int sig, struct target_sigaction *ka,
- target_siginfo_t *info,
- target_sigset_t *set, CPUMIPSState *env)
-{
- fprintf(stderr, "setup_rt_frame: not implemented\n");
-}
-
-long do_sigreturn(CPUMIPSState *env)
-{
- fprintf(stderr, "do_sigreturn: not implemented\n");
- return -TARGET_ENOSYS;
-}
-
-long do_rt_sigreturn(CPUMIPSState *env)
-{
- fprintf(stderr, "do_rt_sigreturn: not implemented\n");
- return -TARGET_ENOSYS;
-}
-
-#elif defined(TARGET_ABI_MIPSN32)
-
-# warning signal handling not implemented
-
-static void setup_frame(int sig, struct target_sigaction *ka,
- target_sigset_t *set, CPUMIPSState *env)
-{
- fprintf(stderr, "setup_frame: not implemented\n");
-}
-
-static void setup_rt_frame(int sig, struct target_sigaction *ka,
- target_siginfo_t *info,
- target_sigset_t *set, CPUMIPSState *env)
-{
- fprintf(stderr, "setup_rt_frame: not implemented\n");
-}
-
-long do_sigreturn(CPUMIPSState *env)
-{
- fprintf(stderr, "do_sigreturn: not implemented\n");
- return -TARGET_ENOSYS;
-}
-
-long do_rt_sigreturn(CPUMIPSState *env)
-{
- fprintf(stderr, "do_rt_sigreturn: not implemented\n");
- return -TARGET_ENOSYS;
-}
-
-#elif defined(TARGET_ABI_MIPSO32)
+#elif defined(TARGET_MIPS) || defined(TARGET_MIPS64)
+# if defined(TARGET_ABI_MIPSO32)
struct target_sigcontext {
uint32_t sc_regmask; /* Unused */
uint32_t sc_status;
@@ -2519,6 +2462,25 @@ struct target_sigcontext {
target_ulong sc_hi3;
target_ulong sc_lo3;
};
+# else /* N32 || N64 */
+struct target_sigcontext {
+ uint64_t sc_regs[32];
+ uint64_t sc_fpregs[32];
+ uint64_t sc_mdhi;
+ uint64_t sc_hi1;
+ uint64_t sc_hi2;
+ uint64_t sc_hi3;
+ uint64_t sc_mdlo;
+ uint64_t sc_lo1;
+ uint64_t sc_lo2;
+ uint64_t sc_lo3;
+ uint64_t sc_pc;
+ uint32_t sc_fpc_csr;
+ uint32_t sc_used_math;
+ uint32_t sc_dsp;
+ uint32_t sc_reserved;
+};
+# endif /* O32 */
struct sigframe {
uint32_t sf_ass[4]; /* argument save space for o32 */
@@ -2546,18 +2508,17 @@ struct target_rt_sigframe {
/* Install trampoline to jump back from signal handler */
static inline int install_sigtramp(unsigned int *tramp, unsigned int syscall)
{
- int err;
+ int err = 0;
/*
- * Set up the return code ...
- *
- * li v0, __NR__foo_sigreturn
- * syscall
- */
+ * Set up the return code ...
+ *
+ * li v0, __NR__foo_sigreturn
+ * syscall
+ */
- err = __put_user(0x24020000 + syscall, tramp + 0);
+ err |= __put_user(0x24020000 + syscall, tramp + 0);
err |= __put_user(0x0000000c , tramp + 1);
- /* flush_cache_sigtramp((unsigned long) tramp); */
return err;
}
@@ -2565,74 +2526,37 @@ static inline int
setup_sigcontext(CPUMIPSState *regs, struct target_sigcontext *sc)
{
int err = 0;
+ int i;
err |= __put_user(regs->active_tc.PC, &sc->sc_pc);
-#define save_gp_reg(i) do { \
- err |= __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); \
- } while(0)
- __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
- save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
- save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
- save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
- save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
- save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
- save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
- save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
- save_gp_reg(31);
-#undef save_gp_reg
+ __put_user(0, &sc->sc_regs[0]);
+ for (i = 1; i < 32; ++i) {
+ err |= __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);
+ }
err |= __put_user(regs->active_tc.HI[0], &sc->sc_mdhi);
err |= __put_user(regs->active_tc.LO[0], &sc->sc_mdlo);
- /* Not used yet, but might be useful if we ever have DSP suppport */
-#if 0
- if (cpu_has_dsp) {
- err |= __put_user(mfhi1(), &sc->sc_hi1);
- err |= __put_user(mflo1(), &sc->sc_lo1);
- err |= __put_user(mfhi2(), &sc->sc_hi2);
- err |= __put_user(mflo2(), &sc->sc_lo2);
- err |= __put_user(mfhi3(), &sc->sc_hi3);
- err |= __put_user(mflo3(), &sc->sc_lo3);
- err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
- }
- /* same with 64 bit */
-#ifdef CONFIG_64BIT
- err |= __put_user(regs->hi, &sc->sc_hi[0]);
- err |= __put_user(regs->lo, &sc->sc_lo[0]);
- if (cpu_has_dsp) {
- err |= __put_user(mfhi1(), &sc->sc_hi[1]);
- err |= __put_user(mflo1(), &sc->sc_lo[1]);
- err |= __put_user(mfhi2(), &sc->sc_hi[2]);
- err |= __put_user(mflo2(), &sc->sc_lo[2]);
- err |= __put_user(mfhi3(), &sc->sc_hi[3]);
- err |= __put_user(mflo3(), &sc->sc_lo[3]);
- err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
+ /* Rather than checking for dsp existence, always copy. The storage
+ would just be garbage otherwise. */
+ err |= __put_user(regs->active_tc.HI[1], &sc->sc_hi1);
+ err |= __put_user(regs->active_tc.HI[2], &sc->sc_hi2);
+ err |= __put_user(regs->active_tc.HI[3], &sc->sc_hi3);
+ err |= __put_user(regs->active_tc.LO[1], &sc->sc_lo1);
+ err |= __put_user(regs->active_tc.LO[2], &sc->sc_lo2);
+ err |= __put_user(regs->active_tc.LO[3], &sc->sc_lo3);
+ {
+ uint32_t dsp = cpu_rddsp(0x3ff, regs);
+ err |= __put_user(dsp, &sc->sc_dsp);
}
-#endif
-#endif
-
-#if 0
- err |= __put_user(!!used_math(), &sc->sc_used_math);
-
- if (!used_math())
- goto out;
- /*
- * Save FPU state to signal context. Signal handler will "inherit"
- * current FPU state.
- */
- preempt_disable();
+ err |= __put_user(1, &sc->sc_used_math);
- if (!is_fpu_owner()) {
- own_fpu();
- restore_fp(current);
+ for (i = 0; i < 32; ++i) {
+ err |= __put_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i]);
}
- err |= save_fp_context(sc);
- preempt_enable();
- out:
-#endif
return err;
}
@@ -2640,70 +2564,36 @@ static inline int
restore_sigcontext(CPUMIPSState *regs, struct target_sigcontext *sc)
{
int err = 0;
+ int i;
err |= __get_user(regs->CP0_EPC, &sc->sc_pc);
err |= __get_user(regs->active_tc.HI[0], &sc->sc_mdhi);
err |= __get_user(regs->active_tc.LO[0], &sc->sc_mdlo);
-#define restore_gp_reg(i) do { \
- err |= __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); \
- } while(0)
- restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
- restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
- restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
- restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
- restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
- restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
- restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
- restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
- restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
- restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
- restore_gp_reg(31);
-#undef restore_gp_reg
-
-#if 0
- if (cpu_has_dsp) {
- err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
- err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
- err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
- err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
- err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
- err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
- err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
- }
-#ifdef CONFIG_64BIT
- err |= __get_user(regs->hi, &sc->sc_hi[0]);
- err |= __get_user(regs->lo, &sc->sc_lo[0]);
- if (cpu_has_dsp) {
- err |= __get_user(treg, &sc->sc_hi[1]); mthi1(treg);
- err |= __get_user(treg, &sc->sc_lo[1]); mthi1(treg);
- err |= __get_user(treg, &sc->sc_hi[2]); mthi2(treg);
- err |= __get_user(treg, &sc->sc_lo[2]); mthi2(treg);
- err |= __get_user(treg, &sc->sc_hi[3]); mthi3(treg);
- err |= __get_user(treg, &sc->sc_lo[3]); mthi3(treg);
- err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
+ for (i = 1; i < 32; ++i) {
+ err |= __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);
}
-#endif
-
- err |= __get_user(used_math, &sc->sc_used_math);
- conditional_used_math(used_math);
- preempt_disable();
+ err |= __get_user(regs->active_tc.HI[1], &sc->sc_hi1);
+ err |= __get_user(regs->active_tc.HI[2], &sc->sc_hi2);
+ err |= __get_user(regs->active_tc.HI[3], &sc->sc_hi3);
+ err |= __get_user(regs->active_tc.LO[1], &sc->sc_lo1);
+ err |= __get_user(regs->active_tc.LO[2], &sc->sc_lo2);
+ err |= __get_user(regs->active_tc.LO[3], &sc->sc_lo3);
+ {
+ uint32_t dsp;
+ err |= __get_user(dsp, &sc->sc_dsp);
+ cpu_wrdsp(dsp, 0x3ff, regs);
+ }
- if (used_math()) {
- /* restore fpu context if we have used it before */
- own_fpu();
- err |= restore_fp_context(sc);
- } else {
- /* signal handler may have used FPU. Give it up. */
- lose_fpu();
+ for (i = 0; i < 32; ++i) {
+ err |= __get_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i]);
}
- preempt_enable();
-#endif
return err;
}
+
/*
* Determine which stack to use..
*/
@@ -2730,6 +2620,7 @@ get_sigframe(struct target_sigaction *ka, CPUMIPSState *regs, size_t frame_size)
return (sp - frame_size) & ~7;
}
+# if defined(TARGET_ABI_MIPSO32)
/* compare linux/arch/mips/kernel/signal.c:setup_frame() */
static void setup_frame(int sig, struct target_sigaction * ka,
target_sigset_t *set, CPUMIPSState *regs)
@@ -2827,6 +2718,7 @@ badframe:
force_sig(TARGET_SIGSEGV/*, current*/);
return 0;
}
+# endif /* O32 */
static void setup_rt_frame(int sig, struct target_sigaction *ka,
target_siginfo_t *info,
@@ -5557,10 +5449,15 @@ void process_pending_signals(CPUArchState *cpu_env)
}
#endif
/* prepare the stack frame of the virtual CPU */
+#if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64)
+ /* These targets do not have traditional signals. */
+ setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
+#else
if (sa->sa_flags & TARGET_SA_SIGINFO)
setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
else
setup_frame(sig, sa, &target_old_set, cpu_env);
+#endif
if (sa->sa_flags & TARGET_SA_RESETHAND)
sa->_sa_handler = TARGET_SIG_DFL;
}
diff --git a/net/hub.c b/net/hub.c
index a24c9d17f7..df32074de0 100644
--- a/net/hub.c
+++ b/net/hub.c
@@ -338,3 +338,17 @@ void net_hub_check_clients(void)
}
}
}
+
+bool net_hub_flush(NetClientState *nc)
+{
+ NetHubPort *port;
+ NetHubPort *source_port = DO_UPCAST(NetHubPort, nc, nc);
+ int ret = 0;
+
+ QLIST_FOREACH(port, &source_port->hub->ports, next) {
+ if (port != source_port) {
+ ret += qemu_net_queue_flush(port->nc.send_queue);
+ }
+ }
+ return ret ? true : false;
+}
diff --git a/net/hub.h b/net/hub.h
index 583ada89d8..a625effe00 100644
--- a/net/hub.h
+++ b/net/hub.h
@@ -21,5 +21,6 @@ NetClientState *net_hub_add_port(int hub_id, const char *name);
NetClientState *net_hub_find_client_by_name(int hub_id, const char *name);
void net_hub_info(Monitor *mon);
void net_hub_check_clients(void);
+bool net_hub_flush(NetClientState *nc);
#endif /* NET_HUB_H */
diff --git a/net/net.c b/net/net.c
index be03a8dd14..f3d67f8322 100644
--- a/net/net.c
+++ b/net/net.c
@@ -235,23 +235,20 @@ NICState *qemu_new_nic(NetClientInfo *info,
const char *name,
void *opaque)
{
- NetClientState *nc;
NetClientState **peers = conf->peers.ncs;
NICState *nic;
- int i;
+ int i, queues = MAX(1, conf->queues);
assert(info->type == NET_CLIENT_OPTIONS_KIND_NIC);
assert(info->size >= sizeof(NICState));
- nc = qemu_new_net_client(info, peers[0], model, name);
- nc->queue_index = 0;
-
- nic = qemu_get_nic(nc);
+ nic = g_malloc0(info->size + sizeof(NetClientState) * queues);
+ nic->ncs = (void *)nic + info->size;
nic->conf = conf;
nic->opaque = opaque;
- for (i = 1; i < conf->queues; i++) {
- qemu_net_client_setup(&nic->ncs[i], info, peers[i], model, nc->name,
+ for (i = 0; i < queues; i++) {
+ qemu_net_client_setup(&nic->ncs[i], info, peers[i], model, name,
NULL);
nic->ncs[i].queue_index = i;
}
@@ -261,7 +258,7 @@ NICState *qemu_new_nic(NetClientInfo *info,
NetClientState *qemu_get_subqueue(NICState *nic, int queue_index)
{
- return &nic->ncs[queue_index];
+ return nic->ncs + queue_index;
}
NetClientState *qemu_get_queue(NICState *nic)
@@ -273,7 +270,7 @@ NICState *qemu_get_nic(NetClientState *nc)
{
NetClientState *nc0 = nc - nc->queue_index;
- return DO_UPCAST(NICState, ncs[0], nc0);
+ return (NICState *)((void *)nc0 - nc->info->size);
}
void *qemu_get_nic_opaque(NetClientState *nc)
@@ -368,6 +365,8 @@ void qemu_del_nic(NICState *nic)
qemu_cleanup_net_client(nc);
qemu_free_net_client(nc);
}
+
+ g_free(nic);
}
void qemu_foreach_nic(qemu_nic_foreach func, void *opaque)
@@ -441,6 +440,12 @@ void qemu_flush_queued_packets(NetClientState *nc)
{
nc->receive_disabled = 0;
+ if (nc->peer && nc->peer->info->type == NET_CLIENT_OPTIONS_KIND_HUBPORT) {
+ if (net_hub_flush(nc->peer)) {
+ qemu_notify_event();
+ }
+ return;
+ }
if (qemu_net_queue_flush(nc->send_queue)) {
/* We emptied the queue successfully, signal to the IO thread to repoll
* the file descriptor (for tap, for example).
diff --git a/net/queue.c b/net/queue.c
index 6eaf5b63c0..859d02a136 100644
--- a/net/queue.c
+++ b/net/queue.c
@@ -50,6 +50,8 @@ struct NetPacket {
struct NetQueue {
void *opaque;
+ uint32_t nq_maxlen;
+ uint32_t nq_count;
QTAILQ_HEAD(packets, NetPacket) packets;
@@ -63,6 +65,8 @@ NetQueue *qemu_new_net_queue(void *opaque)
queue = g_malloc0(sizeof(NetQueue));
queue->opaque = opaque;
+ queue->nq_maxlen = 10000;
+ queue->nq_count = 0;
QTAILQ_INIT(&queue->packets);
@@ -92,6 +96,9 @@ static void qemu_net_queue_append(NetQueue *queue,
{
NetPacket *packet;
+ if (queue->nq_count >= queue->nq_maxlen && !sent_cb) {
+ return; /* drop if queue full and no callback */
+ }
packet = g_malloc(sizeof(NetPacket) + size);
packet->sender = sender;
packet->flags = flags;
@@ -99,6 +106,7 @@ static void qemu_net_queue_append(NetQueue *queue,
packet->sent_cb = sent_cb;
memcpy(packet->data, buf, size);
+ queue->nq_count++;
QTAILQ_INSERT_TAIL(&queue->packets, packet, entry);
}
@@ -113,6 +121,9 @@ static void qemu_net_queue_append_iov(NetQueue *queue,
size_t max_len = 0;
int i;
+ if (queue->nq_count >= queue->nq_maxlen && !sent_cb) {
+ return; /* drop if queue full and no callback */
+ }
for (i = 0; i < iovcnt; i++) {
max_len += iov[i].iov_len;
}
@@ -130,6 +141,7 @@ static void qemu_net_queue_append_iov(NetQueue *queue,
packet->size += len;
}
+ queue->nq_count++;
QTAILQ_INSERT_TAIL(&queue->packets, packet, entry);
}
@@ -220,6 +232,7 @@ void qemu_net_queue_purge(NetQueue *queue, NetClientState *from)
QTAILQ_FOREACH_SAFE(packet, &queue->packets, entry, next) {
if (packet->sender == from) {
QTAILQ_REMOVE(&queue->packets, packet, entry);
+ queue->nq_count--;
g_free(packet);
}
}
@@ -233,6 +246,7 @@ bool qemu_net_queue_flush(NetQueue *queue)
packet = QTAILQ_FIRST(&queue->packets);
QTAILQ_REMOVE(&queue->packets, packet, entry);
+ queue->nq_count--;
ret = qemu_net_queue_deliver(queue,
packet->sender,
@@ -240,6 +254,7 @@ bool qemu_net_queue_flush(NetQueue *queue)
packet->data,
packet->size);
if (ret == 0) {
+ queue->nq_count++;
QTAILQ_INSERT_HEAD(&queue->packets, packet, entry);
return false;
}
diff --git a/net/tap-linux.c b/net/tap-linux.c
index a9531892a6..36c09e24d8 100644
--- a/net/tap-linux.c
+++ b/net/tap-linux.c
@@ -42,6 +42,7 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr,
struct ifreq ifr;
int fd, ret;
int len = sizeof(struct virtio_net_hdr);
+ unsigned int features;
TFR(fd = open(PATH_NET_TUN, O_RDWR));
if (fd < 0) {
@@ -51,9 +52,12 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr,
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
- if (*vnet_hdr) {
- unsigned int features;
+ if (ioctl(fd, TUNGETFEATURES, &features) == 0 &&
+ features & IFF_ONE_QUEUE) {
+ ifr.ifr_flags |= IFF_ONE_QUEUE;
+ }
+ if (*vnet_hdr) {
if (ioctl(fd, TUNGETFEATURES, &features) == 0 &&
features & IFF_VNET_HDR) {
*vnet_hdr = 1;
@@ -78,8 +82,6 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr,
}
if (mq_required) {
- unsigned int features;
-
if ((ioctl(fd, TUNGETFEATURES, &features) != 0) ||
!(features & IFF_MULTI_QUEUE)) {
error_report("multiqueue required, but no kernel "
diff --git a/net/tap-linux.h b/net/tap-linux.h
index 65087e1419..1cf35d41bd 100644
--- a/net/tap-linux.h
+++ b/net/tap-linux.h
@@ -34,10 +34,11 @@
#endif
/* TUNSETIFF ifr flags */
-#define IFF_TAP 0x0002
-#define IFF_NO_PI 0x1000
-#define IFF_VNET_HDR 0x4000
-#define IFF_MULTI_QUEUE 0x0100
+#define IFF_TAP 0x0002
+#define IFF_NO_PI 0x1000
+#define IFF_ONE_QUEUE 0x2000
+#define IFF_VNET_HDR 0x4000
+#define IFF_MULTI_QUEUE 0x0100
#define IFF_ATTACH_QUEUE 0x0200
#define IFF_DETACH_QUEUE 0x0400
diff --git a/net/tap.c b/net/tap.c
index 48c254ed85..daab350efc 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -693,6 +693,13 @@ int net_init_tap(const NetClientOptions *opts, const char *name,
queues = tap->has_queues ? tap->queues : 1;
vhostfdname = tap->has_vhostfd ? tap->vhostfd : NULL;
+ /* QEMU vlans does not support multiqueue tap, in this case peer is set.
+ * For -netdev, peer is always NULL. */
+ if (peer && (tap->has_queues || tap->has_fds || tap->has_vhostfds)) {
+ error_report("Multiqueue tap cannnot be used with QEMU vlans");
+ return -1;
+ }
+
if (tap->has_fd) {
if (tap->has_ifname || tap->has_script || tap->has_downscript ||
tap->has_vnet_hdr || tap->has_helper || tap->has_queues ||
diff --git a/pc-bios/bios.bin b/pc-bios/bios.bin
index ab5dd9db6a..ec9eeb12c6 100644
--- a/pc-bios/bios.bin
+++ b/pc-bios/bios.bin
Binary files differ
diff --git a/qemu-char.c b/qemu-char.c
index 6dc1474546..04aa589c7e 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -28,8 +28,6 @@
#include "qemu/timer.h"
#include "char/char.h"
#include "hw/usb.h"
-#include "char/baum.h"
-#include "char/msmouse.h"
#include "qmp-commands.h"
#include <unistd.h>
@@ -122,20 +120,18 @@ void qemu_chr_be_event(CharDriverState *s, int event)
s->chr_event(s->handler_opaque, event);
}
-static void qemu_chr_fire_open_event(void *opaque)
+static gboolean qemu_chr_generic_open_bh(gpointer opaque)
{
CharDriverState *s = opaque;
qemu_chr_be_event(s, CHR_EVENT_OPENED);
- qemu_free_timer(s->open_timer);
- s->open_timer = NULL;
+ s->idle_tag = 0;
+ return FALSE;
}
void qemu_chr_generic_open(CharDriverState *s)
{
- if (s->open_timer == NULL) {
- s->open_timer = qemu_new_timer_ms(rt_clock,
- qemu_chr_fire_open_event, s);
- qemu_mod_timer(s->open_timer, qemu_get_clock_ms(rt_clock) - 1);
+ if (s->idle_tag == 0) {
+ s->idle_tag = g_idle_add(qemu_chr_generic_open_bh, s);
}
}
@@ -539,66 +535,242 @@ int send_all(int fd, const void *_buf, int len1)
}
#endif /* !_WIN32 */
-#define STDIO_MAX_CLIENTS 1
-static int stdio_nb_clients;
+typedef struct IOWatchPoll
+{
+ GSource *src;
+ int max_size;
+
+ IOCanReadHandler *fd_can_read;
+ void *opaque;
+
+ QTAILQ_ENTRY(IOWatchPoll) node;
+} IOWatchPoll;
+
+static QTAILQ_HEAD(, IOWatchPoll) io_watch_poll_list =
+ QTAILQ_HEAD_INITIALIZER(io_watch_poll_list);
+
+static IOWatchPoll *io_watch_poll_from_source(GSource *source)
+{
+ IOWatchPoll *i;
+
+ QTAILQ_FOREACH(i, &io_watch_poll_list, node) {
+ if (i->src == source) {
+ return i;
+ }
+ }
+
+ return NULL;
+}
+
+static gboolean io_watch_poll_prepare(GSource *source, gint *timeout_)
+{
+ IOWatchPoll *iwp = io_watch_poll_from_source(source);
+
+ iwp->max_size = iwp->fd_can_read(iwp->opaque);
+ if (iwp->max_size == 0) {
+ return FALSE;
+ }
+
+ return g_io_watch_funcs.prepare(source, timeout_);
+}
+
+static gboolean io_watch_poll_check(GSource *source)
+{
+ IOWatchPoll *iwp = io_watch_poll_from_source(source);
+
+ if (iwp->max_size == 0) {
+ return FALSE;
+ }
+
+ return g_io_watch_funcs.check(source);
+}
+
+static gboolean io_watch_poll_dispatch(GSource *source, GSourceFunc callback,
+ gpointer user_data)
+{
+ return g_io_watch_funcs.dispatch(source, callback, user_data);
+}
+
+static void io_watch_poll_finalize(GSource *source)
+{
+ IOWatchPoll *iwp = io_watch_poll_from_source(source);
+ QTAILQ_REMOVE(&io_watch_poll_list, iwp, node);
+ g_io_watch_funcs.finalize(source);
+}
+
+static GSourceFuncs io_watch_poll_funcs = {
+ .prepare = io_watch_poll_prepare,
+ .check = io_watch_poll_check,
+ .dispatch = io_watch_poll_dispatch,
+ .finalize = io_watch_poll_finalize,
+};
+
+/* Can only be used for read */
+static guint io_add_watch_poll(GIOChannel *channel,
+ IOCanReadHandler *fd_can_read,
+ GIOFunc fd_read,
+ gpointer user_data)
+{
+ IOWatchPoll *iwp;
+ GSource *src;
+ guint tag;
+
+ src = g_io_create_watch(channel, G_IO_IN | G_IO_ERR | G_IO_HUP);
+ g_source_set_funcs(src, &io_watch_poll_funcs);
+ g_source_set_callback(src, (GSourceFunc)fd_read, user_data, NULL);
+ tag = g_source_attach(src, NULL);
+ g_source_unref(src);
+
+ iwp = g_malloc0(sizeof(*iwp));
+ iwp->src = src;
+ iwp->max_size = 0;
+ iwp->fd_can_read = fd_can_read;
+ iwp->opaque = user_data;
+
+ QTAILQ_INSERT_HEAD(&io_watch_poll_list, iwp, node);
+
+ return tag;
+}
#ifndef _WIN32
+static GIOChannel *io_channel_from_fd(int fd)
+{
+ GIOChannel *chan;
-typedef struct {
- int fd_in, fd_out;
- int max_size;
-} FDCharDriver;
+ if (fd == -1) {
+ return NULL;
+ }
+ chan = g_io_channel_unix_new(fd);
-static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
+ g_io_channel_set_encoding(chan, NULL, NULL);
+ g_io_channel_set_buffered(chan, FALSE);
+
+ return chan;
+}
+#endif
+
+static GIOChannel *io_channel_from_socket(int fd)
{
- FDCharDriver *s = chr->opaque;
- return send_all(s->fd_out, buf, len);
+ GIOChannel *chan;
+
+ if (fd == -1) {
+ return NULL;
+ }
+
+#ifdef _WIN32
+ chan = g_io_channel_win32_new_socket(fd);
+#else
+ chan = g_io_channel_unix_new(fd);
+#endif
+
+ g_io_channel_set_encoding(chan, NULL, NULL);
+ g_io_channel_set_buffered(chan, FALSE);
+
+ return chan;
}
-static int fd_chr_read_poll(void *opaque)
+static int io_channel_send_all(GIOChannel *fd, const void *_buf, int len1)
{
- CharDriverState *chr = opaque;
- FDCharDriver *s = chr->opaque;
+ GIOStatus status;
+ gsize bytes_written;
+ int len;
+ const uint8_t *buf = _buf;
- s->max_size = qemu_chr_be_can_write(chr);
- return s->max_size;
+ len = len1;
+ while (len > 0) {
+ status = g_io_channel_write_chars(fd, (const gchar *)buf, len,
+ &bytes_written, NULL);
+ if (status != G_IO_STATUS_NORMAL) {
+ if (status == G_IO_STATUS_AGAIN) {
+ errno = EAGAIN;
+ return -1;
+ } else {
+ errno = EINVAL;
+ return -1;
+ }
+ } else if (status == G_IO_STATUS_EOF) {
+ break;
+ } else {
+ buf += bytes_written;
+ len -= bytes_written;
+ }
+ }
+ return len1 - len;
}
-static void fd_chr_read(void *opaque)
+#ifndef _WIN32
+
+typedef struct FDCharDriver {
+ CharDriverState *chr;
+ GIOChannel *fd_in, *fd_out;
+ guint fd_in_tag;
+ int max_size;
+ QTAILQ_ENTRY(FDCharDriver) node;
+} FDCharDriver;
+
+static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
+{
+ FDCharDriver *s = chr->opaque;
+
+ return io_channel_send_all(s->fd_out, buf, len);
+}
+
+static gboolean fd_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque)
{
CharDriverState *chr = opaque;
FDCharDriver *s = chr->opaque;
- int size, len;
+ int len;
uint8_t buf[READ_BUF_LEN];
+ GIOStatus status;
+ gsize bytes_read;
len = sizeof(buf);
- if (len > s->max_size)
+ if (len > s->max_size) {
len = s->max_size;
- if (len == 0)
- return;
- size = read(s->fd_in, buf, len);
- if (size == 0) {
- /* FD has been closed. Remove it from the active list. */
- qemu_set_fd_handler2(s->fd_in, NULL, NULL, NULL, NULL);
+ }
+ if (len == 0) {
+ return FALSE;
+ }
+
+ status = g_io_channel_read_chars(chan, (gchar *)buf,
+ len, &bytes_read, NULL);
+ if (status == G_IO_STATUS_EOF) {
qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
- return;
+ return FALSE;
}
- if (size > 0) {
- qemu_chr_be_write(chr, buf, size);
+ if (status == G_IO_STATUS_NORMAL) {
+ qemu_chr_be_write(chr, buf, bytes_read);
}
+
+ return TRUE;
+}
+
+static int fd_chr_read_poll(void *opaque)
+{
+ CharDriverState *chr = opaque;
+ FDCharDriver *s = chr->opaque;
+
+ s->max_size = qemu_chr_be_can_write(chr);
+ return s->max_size;
+}
+
+static GSource *fd_chr_add_watch(CharDriverState *chr, GIOCondition cond)
+{
+ FDCharDriver *s = chr->opaque;
+ return g_io_create_watch(s->fd_out, cond);
}
static void fd_chr_update_read_handler(CharDriverState *chr)
{
FDCharDriver *s = chr->opaque;
- if (s->fd_in >= 0) {
- if (display_type == DT_NOGRAPHIC && s->fd_in == 0) {
- } else {
- qemu_set_fd_handler2(s->fd_in, fd_chr_read_poll,
- fd_chr_read, NULL, chr);
- }
+ if (s->fd_in_tag) {
+ g_source_remove(s->fd_in_tag);
+ }
+
+ if (s->fd_in) {
+ s->fd_in_tag = io_add_watch_poll(s->fd_in, fd_chr_read_poll, fd_chr_read, chr);
}
}
@@ -606,11 +778,16 @@ static void fd_chr_close(struct CharDriverState *chr)
{
FDCharDriver *s = chr->opaque;
- if (s->fd_in >= 0) {
- if (display_type == DT_NOGRAPHIC && s->fd_in == 0) {
- } else {
- qemu_set_fd_handler2(s->fd_in, NULL, NULL, NULL, NULL);
- }
+ if (s->fd_in_tag) {
+ g_source_remove(s->fd_in_tag);
+ s->fd_in_tag = 0;
+ }
+
+ if (s->fd_in) {
+ g_io_channel_unref(s->fd_in);
+ }
+ if (s->fd_out) {
+ g_io_channel_unref(s->fd_out);
}
g_free(s);
@@ -625,9 +802,12 @@ static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out)
chr = g_malloc0(sizeof(CharDriverState));
s = g_malloc0(sizeof(FDCharDriver));
- s->fd_in = fd_in;
- s->fd_out = fd_out;
+ s->fd_in = io_channel_from_fd(fd_in);
+ s->fd_out = io_channel_from_fd(fd_out);
+ fcntl(fd_out, F_SETFL, O_NONBLOCK);
+ s->chr = chr;
chr->opaque = s;
+ chr->chr_add_watch = fd_chr_add_watch;
chr->chr_write = fd_chr_write;
chr->chr_update_read_handler = fd_chr_update_read_handler;
chr->chr_close = fd_chr_close;
@@ -677,53 +857,6 @@ static CharDriverState *qemu_chr_open_pipe(QemuOpts *opts)
return qemu_chr_open_fd(fd_in, fd_out);
}
-
-/* for STDIO, we handle the case where several clients use it
- (nographic mode) */
-
-#define TERM_FIFO_MAX_SIZE 1
-
-static uint8_t term_fifo[TERM_FIFO_MAX_SIZE];
-static int term_fifo_size;
-
-static int stdio_read_poll(void *opaque)
-{
- CharDriverState *chr = opaque;
-
- /* try to flush the queue if needed */
- if (term_fifo_size != 0 && qemu_chr_be_can_write(chr) > 0) {
- qemu_chr_be_write(chr, term_fifo, 1);
- term_fifo_size = 0;
- }
- /* see if we can absorb more chars */
- if (term_fifo_size == 0)
- return 1;
- else
- return 0;
-}
-
-static void stdio_read(void *opaque)
-{
- int size;
- uint8_t buf[1];
- CharDriverState *chr = opaque;
-
- size = read(0, buf, 1);
- if (size == 0) {
- /* stdin has been closed. Remove it from the active list. */
- qemu_set_fd_handler2(0, NULL, NULL, NULL, NULL);
- qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
- return;
- }
- if (size > 0) {
- if (qemu_chr_be_can_write(chr) > 0) {
- qemu_chr_be_write(chr, buf, 1);
- } else if (term_fifo_size == 0) {
- term_fifo[term_fifo_size++] = buf[0];
- }
- }
-}
-
/* init terminal so that we can grab keys */
static struct termios oldtty;
static int old_fd0_flags;
@@ -760,8 +893,6 @@ static void qemu_chr_set_echo_stdio(CharDriverState *chr, bool echo)
static void qemu_chr_close_stdio(struct CharDriverState *chr)
{
term_exit();
- stdio_nb_clients--;
- qemu_set_fd_handler2(0, NULL, NULL, NULL, NULL);
fd_chr_close(chr);
}
@@ -769,25 +900,18 @@ static CharDriverState *qemu_chr_open_stdio(QemuOpts *opts)
{
CharDriverState *chr;
- if (stdio_nb_clients >= STDIO_MAX_CLIENTS) {
- return NULL;
- }
if (is_daemonized()) {
error_report("cannot use stdio with -daemonize");
return NULL;
}
- if (stdio_nb_clients == 0) {
- old_fd0_flags = fcntl(0, F_GETFL);
- tcgetattr (0, &oldtty);
- fcntl(0, F_SETFL, O_NONBLOCK);
- atexit(term_exit);
- }
+ old_fd0_flags = fcntl(0, F_GETFL);
+ tcgetattr (0, &oldtty);
+ fcntl(0, F_SETFL, O_NONBLOCK);
+ atexit(term_exit);
chr = qemu_chr_open_fd(0, 1);
chr->chr_close = qemu_chr_close_stdio;
chr->chr_set_echo = qemu_chr_set_echo_stdio;
- qemu_set_fd_handler2(0, stdio_read_poll, stdio_read, NULL, chr);
- stdio_nb_clients++;
stdio_allow_signal = qemu_opt_get_bool(opts, "signal",
display_type != DT_NOGRAPHIC);
qemu_chr_fe_set_echo(chr, false);
@@ -859,16 +983,55 @@ static void cfmakeraw (struct termios *termios_p)
#define HAVE_CHARDEV_TTY 1
typedef struct {
- int fd;
+ GIOChannel *fd;
+ guint fd_tag;
int connected;
int polling;
int read_bytes;
- QEMUTimer *timer;
+ guint timer_tag;
} PtyCharDriver;
static void pty_chr_update_read_handler(CharDriverState *chr);
static void pty_chr_state(CharDriverState *chr, int connected);
+static gboolean pty_chr_timer(gpointer opaque)
+{
+ struct CharDriverState *chr = opaque;
+ PtyCharDriver *s = chr->opaque;
+
+ if (s->connected) {
+ goto out;
+ }
+ if (s->polling) {
+ /* If we arrive here without polling being cleared due
+ * read returning -EIO, then we are (re-)connected */
+ pty_chr_state(chr, 1);
+ goto out;
+ }
+
+ /* Next poll ... */
+ pty_chr_update_read_handler(chr);
+
+out:
+ return FALSE;
+}
+
+static void pty_chr_rearm_timer(CharDriverState *chr, int ms)
+{
+ PtyCharDriver *s = chr->opaque;
+
+ if (s->timer_tag) {
+ g_source_remove(s->timer_tag);
+ s->timer_tag = 0;
+ }
+
+ if (ms == 1000) {
+ s->timer_tag = g_timeout_add_seconds(1, pty_chr_timer, chr);
+ } else {
+ s->timer_tag = g_timeout_add(ms, pty_chr_timer, chr);
+ }
+}
+
static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
{
PtyCharDriver *s = chr->opaque;
@@ -878,7 +1041,13 @@ static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
pty_chr_update_read_handler(chr);
return 0;
}
- return send_all(s->fd, buf, len);
+ return io_channel_send_all(s->fd, buf, len);
+}
+
+static GSource *pty_chr_add_watch(CharDriverState *chr, GIOCondition cond)
+{
+ PtyCharDriver *s = chr->opaque;
+ return g_io_create_watch(s->fd, cond);
}
static int pty_chr_read_poll(void *opaque)
@@ -890,36 +1059,39 @@ static int pty_chr_read_poll(void *opaque)
return s->read_bytes;
}
-static void pty_chr_read(void *opaque)
+static gboolean pty_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque)
{
CharDriverState *chr = opaque;
PtyCharDriver *s = chr->opaque;
- int size, len;
+ gsize size, len;
uint8_t buf[READ_BUF_LEN];
+ GIOStatus status;
len = sizeof(buf);
if (len > s->read_bytes)
len = s->read_bytes;
if (len == 0)
- return;
- size = read(s->fd, buf, len);
- if ((size == -1 && errno == EIO) ||
- (size == 0)) {
+ return FALSE;
+ status = g_io_channel_read_chars(s->fd, (gchar *)buf, len, &size, NULL);
+ if (status != G_IO_STATUS_NORMAL) {
pty_chr_state(chr, 0);
- return;
- }
- if (size > 0) {
+ return FALSE;
+ } else {
pty_chr_state(chr, 1);
qemu_chr_be_write(chr, buf, size);
}
+ return TRUE;
}
static void pty_chr_update_read_handler(CharDriverState *chr)
{
PtyCharDriver *s = chr->opaque;
- qemu_set_fd_handler2(s->fd, pty_chr_read_poll,
- pty_chr_read, NULL, chr);
+ if (s->fd_tag) {
+ g_source_remove(s->fd_tag);
+ }
+
+ s->fd_tag = io_add_watch_poll(s->fd, pty_chr_read_poll, pty_chr_read, chr);
s->polling = 1;
/*
* Short timeout here: just need wait long enougth that qemu makes
@@ -929,7 +1101,7 @@ static void pty_chr_update_read_handler(CharDriverState *chr)
* timeout to the normal (much longer) poll interval before the
* timer triggers.
*/
- qemu_mod_timer(s->timer, qemu_get_clock_ms(rt_clock) + 10);
+ pty_chr_rearm_timer(chr, 10);
}
static void pty_chr_state(CharDriverState *chr, int connected)
@@ -937,13 +1109,14 @@ static void pty_chr_state(CharDriverState *chr, int connected)
PtyCharDriver *s = chr->opaque;
if (!connected) {
- qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
+ g_source_remove(s->fd_tag);
+ s->fd_tag = 0;
s->connected = 0;
s->polling = 0;
/* (re-)connect poll interval for idle guests: once per second.
* We check more frequently in case the guests sends data to
* the virtual device linked to our pty. */
- qemu_mod_timer(s->timer, qemu_get_clock_ms(rt_clock) + 1000);
+ pty_chr_rearm_timer(chr, 1000);
} else {
if (!s->connected)
qemu_chr_generic_open(chr);
@@ -951,32 +1124,21 @@ static void pty_chr_state(CharDriverState *chr, int connected)
}
}
-static void pty_chr_timer(void *opaque)
-{
- struct CharDriverState *chr = opaque;
- PtyCharDriver *s = chr->opaque;
-
- if (s->connected)
- return;
- if (s->polling) {
- /* If we arrive here without polling being cleared due
- * read returning -EIO, then we are (re-)connected */
- pty_chr_state(chr, 1);
- return;
- }
-
- /* Next poll ... */
- pty_chr_update_read_handler(chr);
-}
static void pty_chr_close(struct CharDriverState *chr)
{
PtyCharDriver *s = chr->opaque;
+ int fd;
- qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
- close(s->fd);
- qemu_del_timer(s->timer);
- qemu_free_timer(s->timer);
+ if (s->fd_tag) {
+ g_source_remove(s->fd_tag);
+ }
+ fd = g_io_channel_unix_get_fd(s->fd);
+ g_io_channel_unref(s->fd);
+ close(fd);
+ if (s->timer_tag) {
+ g_source_remove(s->timer_tag);
+ }
g_free(s);
qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
}
@@ -1025,9 +1187,10 @@ static CharDriverState *qemu_chr_open_pty(QemuOpts *opts)
chr->chr_write = pty_chr_write;
chr->chr_update_read_handler = pty_chr_update_read_handler;
chr->chr_close = pty_chr_close;
+ chr->chr_add_watch = pty_chr_add_watch;
- s->fd = master_fd;
- s->timer = qemu_new_timer_ms(rt_clock, pty_chr_timer, chr);
+ s->fd = io_channel_from_fd(master_fd);
+ s->timer_tag = 0;
return chr;
}
@@ -1155,22 +1318,24 @@ static int tty_serial_ioctl(CharDriverState *chr, int cmd, void *arg)
case CHR_IOCTL_SERIAL_SET_PARAMS:
{
QEMUSerialSetParams *ssp = arg;
- tty_serial_init(s->fd_in, ssp->speed, ssp->parity,
+ tty_serial_init(g_io_channel_unix_get_fd(s->fd_in),
+ ssp->speed, ssp->parity,
ssp->data_bits, ssp->stop_bits);
}
break;
case CHR_IOCTL_SERIAL_SET_BREAK:
{
int enable = *(int *)arg;
- if (enable)
- tcsendbreak(s->fd_in, 1);
+ if (enable) {
+ tcsendbreak(g_io_channel_unix_get_fd(s->fd_in), 1);
+ }
}
break;
case CHR_IOCTL_SERIAL_GET_TIOCM:
{
int sarg = 0;
int *targ = (int *)arg;
- ioctl(s->fd_in, TIOCMGET, &sarg);
+ ioctl(g_io_channel_unix_get_fd(s->fd_in), TIOCMGET, &sarg);
*targ = 0;
if (sarg & TIOCM_CTS)
*targ |= CHR_TIOCM_CTS;
@@ -1190,7 +1355,7 @@ static int tty_serial_ioctl(CharDriverState *chr, int cmd, void *arg)
{
int sarg = *(int *)arg;
int targ = 0;
- ioctl(s->fd_in, TIOCMGET, &targ);
+ ioctl(g_io_channel_unix_get_fd(s->fd_in), TIOCMGET, &targ);
targ &= ~(CHR_TIOCM_CTS | CHR_TIOCM_CAR | CHR_TIOCM_DSR
| CHR_TIOCM_RI | CHR_TIOCM_DTR | CHR_TIOCM_RTS);
if (sarg & CHR_TIOCM_CTS)
@@ -1205,7 +1370,7 @@ static int tty_serial_ioctl(CharDriverState *chr, int cmd, void *arg)
targ |= TIOCM_DTR;
if (sarg & CHR_TIOCM_RTS)
targ |= TIOCM_RTS;
- ioctl(s->fd_in, TIOCMSET, &targ);
+ ioctl(g_io_channel_unix_get_fd(s->fd_in), TIOCMSET, &targ);
}
break;
default:
@@ -1220,7 +1385,7 @@ static void qemu_chr_close_tty(CharDriverState *chr)
int fd = -1;
if (s) {
- fd = s->fd_in;
+ fd = g_io_channel_unix_get_fd(s->fd_in);
}
fd_chr_close(chr);
@@ -1448,8 +1613,6 @@ static CharDriverState *qemu_chr_open_pp_fd(int fd)
#else /* _WIN32 */
-static CharDriverState *stdio_clients[STDIO_MAX_CLIENTS];
-
typedef struct {
int max_size;
HANDLE hcom, hrecv, hsend;
@@ -1951,7 +2114,6 @@ static void win_stdio_close(CharDriverState *chr)
g_free(chr->opaque);
g_free(chr);
- stdio_nb_clients--;
}
static CharDriverState *qemu_chr_open_win_stdio(QemuOpts *opts)
@@ -1961,11 +2123,6 @@ static CharDriverState *qemu_chr_open_win_stdio(QemuOpts *opts)
DWORD dwMode;
int is_console = 0;
- if (stdio_nb_clients >= STDIO_MAX_CLIENTS
- || ((display_type != DT_NOGRAPHIC) && (stdio_nb_clients != 0))) {
- return NULL;
- }
-
chr = g_malloc0(sizeof(CharDriverState));
stdio = g_malloc0(sizeof(WinStdioCharState));
@@ -1981,37 +2138,34 @@ static CharDriverState *qemu_chr_open_win_stdio(QemuOpts *opts)
chr->chr_write = win_stdio_write;
chr->chr_close = win_stdio_close;
- if (stdio_nb_clients == 0) {
- if (is_console) {
- if (qemu_add_wait_object(stdio->hStdIn,
- win_stdio_wait_func, chr)) {
- fprintf(stderr, "qemu_add_wait_object: failed\n");
- }
- } else {
- DWORD dwId;
-
- stdio->hInputReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
- stdio->hInputDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
- stdio->hInputThread = CreateThread(NULL, 0, win_stdio_thread,
- chr, 0, &dwId);
-
- if (stdio->hInputThread == INVALID_HANDLE_VALUE
- || stdio->hInputReadyEvent == INVALID_HANDLE_VALUE
- || stdio->hInputDoneEvent == INVALID_HANDLE_VALUE) {
- fprintf(stderr, "cannot create stdio thread or event\n");
- exit(1);
- }
- if (qemu_add_wait_object(stdio->hInputReadyEvent,
- win_stdio_thread_wait_func, chr)) {
- fprintf(stderr, "qemu_add_wait_object: failed\n");
- }
+ if (is_console) {
+ if (qemu_add_wait_object(stdio->hStdIn,
+ win_stdio_wait_func, chr)) {
+ fprintf(stderr, "qemu_add_wait_object: failed\n");
+ }
+ } else {
+ DWORD dwId;
+
+ stdio->hInputReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ stdio->hInputDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ stdio->hInputThread = CreateThread(NULL, 0, win_stdio_thread,
+ chr, 0, &dwId);
+
+ if (stdio->hInputThread == INVALID_HANDLE_VALUE
+ || stdio->hInputReadyEvent == INVALID_HANDLE_VALUE
+ || stdio->hInputDoneEvent == INVALID_HANDLE_VALUE) {
+ fprintf(stderr, "cannot create stdio thread or event\n");
+ exit(1);
+ }
+ if (qemu_add_wait_object(stdio->hInputReadyEvent,
+ win_stdio_thread_wait_func, chr)) {
+ fprintf(stderr, "qemu_add_wait_object: failed\n");
}
}
dwMode |= ENABLE_LINE_INPUT;
- stdio_clients[stdio_nb_clients++] = chr;
- if (stdio_nb_clients == 1 && is_console) {
+ if (is_console) {
/* set the terminal in raw mode */
/* ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS */
dwMode |= ENABLE_PROCESSED_INPUT;
@@ -2026,11 +2180,14 @@ static CharDriverState *qemu_chr_open_win_stdio(QemuOpts *opts)
}
#endif /* !_WIN32 */
+
/***********************************************************/
/* UDP Net console */
typedef struct {
int fd;
+ GIOChannel *chan;
+ guint tag;
uint8_t buf[READ_BUF_LEN];
int bufcnt;
int bufptr;
@@ -2040,8 +2197,17 @@ typedef struct {
static int udp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
{
NetCharDriver *s = chr->opaque;
+ gsize bytes_written;
+ GIOStatus status;
+
+ status = g_io_channel_write_chars(s->chan, (const gchar *)buf, len, &bytes_written, NULL);
+ if (status == G_IO_STATUS_EOF) {
+ return 0;
+ } else if (status != G_IO_STATUS_NORMAL) {
+ return -1;
+ }
- return send(s->fd, (const void *)buf, len, 0);
+ return bytes_written;
}
static int udp_chr_read_poll(void *opaque)
@@ -2062,17 +2228,22 @@ static int udp_chr_read_poll(void *opaque)
return s->max_size;
}
-static void udp_chr_read(void *opaque)
+static gboolean udp_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque)
{
CharDriverState *chr = opaque;
NetCharDriver *s = chr->opaque;
+ gsize bytes_read = 0;
+ GIOStatus status;
if (s->max_size == 0)
- return;
- s->bufcnt = qemu_recv(s->fd, s->buf, sizeof(s->buf), 0);
+ return FALSE;
+ status = g_io_channel_read_chars(s->chan, (gchar *)s->buf, sizeof(s->buf),
+ &bytes_read, NULL);
+ s->bufcnt = bytes_read;
s->bufptr = s->bufcnt;
- if (s->bufcnt <= 0)
- return;
+ if (status != G_IO_STATUS_NORMAL) {
+ return FALSE;
+ }
s->bufptr = 0;
while (s->max_size > 0 && s->bufptr < s->bufcnt) {
@@ -2080,23 +2251,32 @@ static void udp_chr_read(void *opaque)
s->bufptr++;
s->max_size = qemu_chr_be_can_write(chr);
}
+
+ return TRUE;
}
static void udp_chr_update_read_handler(CharDriverState *chr)
{
NetCharDriver *s = chr->opaque;
- if (s->fd >= 0) {
- qemu_set_fd_handler2(s->fd, udp_chr_read_poll,
- udp_chr_read, NULL, chr);
+ if (s->tag) {
+ g_source_remove(s->tag);
+ s->tag = 0;
+ }
+
+ if (s->chan) {
+ s->tag = io_add_watch_poll(s->chan, udp_chr_read_poll, udp_chr_read, chr);
}
}
static void udp_chr_close(CharDriverState *chr)
{
NetCharDriver *s = chr->opaque;
- if (s->fd >= 0) {
- qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
+ if (s->tag) {
+ g_source_remove(s->tag);
+ }
+ if (s->chan) {
+ g_io_channel_unref(s->chan);
closesocket(s->fd);
}
g_free(s);
@@ -2119,6 +2299,7 @@ static CharDriverState *qemu_chr_open_udp(QemuOpts *opts)
}
s->fd = fd;
+ s->chan = io_channel_from_socket(s->fd);
s->bufcnt = 0;
s->bufptr = 0;
chr->opaque = s;
@@ -2144,6 +2325,9 @@ return_err:
/* TCP Net console */
typedef struct {
+
+ GIOChannel *chan, *listen_chan;
+ guint tag, listen_tag;
int fd, listen_fd;
int connected;
int max_size;
@@ -2153,13 +2337,13 @@ typedef struct {
int msgfd;
} TCPCharDriver;
-static void tcp_chr_accept(void *opaque);
+static gboolean tcp_chr_accept(GIOChannel *chan, GIOCondition cond, void *opaque);
static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
{
TCPCharDriver *s = chr->opaque;
if (s->connected) {
- return send_all(s->fd, buf, len);
+ return io_channel_send_all(s->chan, buf, len);
} else {
/* XXX: indicate an error ? */
return len;
@@ -2299,15 +2483,22 @@ static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len)
}
#endif
-static void tcp_chr_read(void *opaque)
+static GSource *tcp_chr_add_watch(CharDriverState *chr, GIOCondition cond)
+{
+ TCPCharDriver *s = chr->opaque;
+ return g_io_create_watch(s->chan, cond);
+}
+
+static gboolean tcp_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque)
{
CharDriverState *chr = opaque;
TCPCharDriver *s = chr->opaque;
uint8_t buf[READ_BUF_LEN];
int len, size;
- if (!s->connected || s->max_size <= 0)
- return;
+ if (!s->connected || s->max_size <= 0) {
+ return FALSE;
+ }
len = sizeof(buf);
if (len > s->max_size)
len = s->max_size;
@@ -2315,10 +2506,13 @@ static void tcp_chr_read(void *opaque)
if (size == 0) {
/* connection closed */
s->connected = 0;
- if (s->listen_fd >= 0) {
- qemu_set_fd_handler2(s->listen_fd, NULL, tcp_chr_accept, NULL, chr);
+ if (s->listen_chan) {
+ s->listen_tag = g_io_add_watch(s->listen_chan, G_IO_IN, tcp_chr_accept, chr);
}
- qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
+ g_source_remove(s->tag);
+ s->tag = 0;
+ g_io_channel_unref(s->chan);
+ s->chan = NULL;
closesocket(s->fd);
s->fd = -1;
qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
@@ -2328,6 +2522,8 @@ static void tcp_chr_read(void *opaque)
if (size > 0)
qemu_chr_be_write(chr, buf, size);
}
+
+ return TRUE;
}
#ifndef _WIN32
@@ -2343,9 +2539,8 @@ static void tcp_chr_connect(void *opaque)
TCPCharDriver *s = chr->opaque;
s->connected = 1;
- if (s->fd >= 0) {
- qemu_set_fd_handler2(s->fd, tcp_chr_read_poll,
- tcp_chr_read, NULL, chr);
+ if (s->chan) {
+ s->tag = io_add_watch_poll(s->chan, tcp_chr_read_poll, tcp_chr_read, chr);
}
qemu_chr_generic_open(chr);
}
@@ -2365,12 +2560,6 @@ static void tcp_chr_telnet_init(int fd)
send(fd, (char *)buf, 3, 0);
}
-static void socket_set_nodelay(int fd)
-{
- int val = 1;
- setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
-}
-
static int tcp_chr_add_client(CharDriverState *chr, int fd)
{
TCPCharDriver *s = chr->opaque;
@@ -2381,13 +2570,15 @@ static int tcp_chr_add_client(CharDriverState *chr, int fd)
if (s->do_nodelay)
socket_set_nodelay(fd);
s->fd = fd;
- qemu_set_fd_handler2(s->listen_fd, NULL, NULL, NULL, NULL);
+ s->chan = io_channel_from_socket(fd);
+ g_source_remove(s->listen_tag);
+ s->listen_tag = 0;
tcp_chr_connect(chr);
return 0;
}
-static void tcp_chr_accept(void *opaque)
+static gboolean tcp_chr_accept(GIOChannel *channel, GIOCondition cond, void *opaque)
{
CharDriverState *chr = opaque;
TCPCharDriver *s = chr->opaque;
@@ -2412,7 +2603,7 @@ static void tcp_chr_accept(void *opaque)
}
fd = qemu_accept(s->listen_fd, addr, &len);
if (fd < 0 && errno != EINTR) {
- return;
+ return FALSE;
} else if (fd >= 0) {
if (s->do_telnetopt)
tcp_chr_telnet_init(fd);
@@ -2421,17 +2612,29 @@ static void tcp_chr_accept(void *opaque)
}
if (tcp_chr_add_client(chr, fd) < 0)
close(fd);
+
+ return TRUE;
}
static void tcp_chr_close(CharDriverState *chr)
{
TCPCharDriver *s = chr->opaque;
if (s->fd >= 0) {
- qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
+ if (s->tag) {
+ g_source_remove(s->tag);
+ }
+ if (s->chan) {
+ g_io_channel_unref(s->chan);
+ }
closesocket(s->fd);
}
if (s->listen_fd >= 0) {
- qemu_set_fd_handler2(s->listen_fd, NULL, NULL, NULL, NULL);
+ if (s->listen_tag) {
+ g_source_remove(s->listen_tag);
+ }
+ if (s->listen_chan) {
+ g_io_channel_unref(s->listen_chan);
+ }
closesocket(s->listen_fd);
}
g_free(s);
@@ -2494,10 +2697,12 @@ static CharDriverState *qemu_chr_open_socket_fd(int fd, bool do_nodelay,
chr->chr_close = tcp_chr_close;
chr->get_msgfd = tcp_get_msgfd;
chr->chr_add_client = tcp_chr_add_client;
+ chr->chr_add_watch = tcp_chr_add_watch;
if (is_listen) {
s->listen_fd = fd;
- qemu_set_fd_handler2(s->listen_fd, NULL, tcp_chr_accept, NULL, chr);
+ s->listen_chan = io_channel_from_socket(s->listen_fd);
+ s->listen_tag = g_io_add_watch(s->listen_chan, G_IO_IN, tcp_chr_accept, chr);
if (is_telnet) {
s->do_telnetopt = 1;
}
@@ -2505,13 +2710,14 @@ static CharDriverState *qemu_chr_open_socket_fd(int fd, bool do_nodelay,
s->connected = 1;
s->fd = fd;
socket_set_nodelay(fd);
+ s->chan = io_channel_from_socket(s->fd);
tcp_chr_connect(chr);
}
if (is_listen && is_waitconnect) {
printf("QEMU waiting for connection on: %s\n",
chr->filename);
- tcp_chr_accept(chr);
+ tcp_chr_accept(s->listen_chan, G_IO_IN, chr);
socket_set_nonblock(s->listen_fd);
}
return chr;
@@ -2972,53 +3178,31 @@ static CharDriverState *qemu_chr_open_pp(QemuOpts *opts)
#endif
-static const struct {
+typedef struct CharDriver {
const char *name;
CharDriverState *(*open)(QemuOpts *opts);
-} backend_table[] = {
- { .name = "null", .open = qemu_chr_open_null },
- { .name = "socket", .open = qemu_chr_open_socket },
- { .name = "udp", .open = qemu_chr_open_udp },
- { .name = "msmouse", .open = qemu_chr_open_msmouse },
- { .name = "vc", .open = vc_init },
- { .name = "memory", .open = qemu_chr_open_ringbuf },
-#ifdef _WIN32
- { .name = "file", .open = qemu_chr_open_win_file_out },
- { .name = "pipe", .open = qemu_chr_open_win_pipe },
- { .name = "console", .open = qemu_chr_open_win_con },
- { .name = "serial", .open = qemu_chr_open_win },
- { .name = "stdio", .open = qemu_chr_open_win_stdio },
-#else
- { .name = "file", .open = qemu_chr_open_file_out },
- { .name = "pipe", .open = qemu_chr_open_pipe },
- { .name = "stdio", .open = qemu_chr_open_stdio },
-#endif
-#ifdef CONFIG_BRLAPI
- { .name = "braille", .open = chr_baum_init },
-#endif
-#ifdef HAVE_CHARDEV_TTY
- { .name = "tty", .open = qemu_chr_open_tty },
- { .name = "serial", .open = qemu_chr_open_tty },
- { .name = "pty", .open = qemu_chr_open_pty },
-#endif
-#ifdef HAVE_CHARDEV_PARPORT
- { .name = "parallel", .open = qemu_chr_open_pp },
- { .name = "parport", .open = qemu_chr_open_pp },
-#endif
-#ifdef CONFIG_SPICE
- { .name = "spicevmc", .open = qemu_chr_open_spice },
-#if SPICE_SERVER_VERSION >= 0x000c02
- { .name = "spiceport", .open = qemu_chr_open_spice_port },
-#endif
-#endif
-};
+} CharDriver;
+
+static GSList *backends;
+
+void register_char_driver(const char *name, CharDriverState *(*open)(QemuOpts *))
+{
+ CharDriver *s;
+
+ s = g_malloc0(sizeof(*s));
+ s->name = g_strdup(name);
+ s->open = open;
+
+ backends = g_slist_append(backends, s);
+}
CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
void (*init)(struct CharDriverState *s),
Error **errp)
{
+ CharDriver *cd;
CharDriverState *chr;
- int i;
+ GSList *i;
if (qemu_opts_id(opts) == NULL) {
error_setg(errp, "chardev: no id specified");
@@ -3030,17 +3214,20 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
qemu_opts_id(opts));
goto err;
}
- for (i = 0; i < ARRAY_SIZE(backend_table); i++) {
- if (strcmp(backend_table[i].name, qemu_opt_get(opts, "backend")) == 0)
+ for (i = backends; i; i = i->next) {
+ cd = i->data;
+
+ if (strcmp(cd->name, qemu_opt_get(opts, "backend")) == 0) {
break;
+ }
}
- if (i == ARRAY_SIZE(backend_table)) {
+ if (i == NULL) {
error_setg(errp, "chardev: backend \"%s\" not found",
qemu_opt_get(opts, "backend"));
- goto err;
+ return NULL;
}
- chr = backend_table[i].open(opts);
+ chr = cd->open(opts);
if (!chr) {
error_setg(errp, "chardev: opening backend \"%s\" failed",
qemu_opt_get(opts, "backend"));
@@ -3120,6 +3307,24 @@ void qemu_chr_fe_close(struct CharDriverState *chr)
}
}
+guint qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond,
+ GIOFunc func, void *user_data)
+{
+ GSource *src;
+ guint tag;
+
+ if (s->chr_add_watch == NULL) {
+ return -ENOSYS;
+ }
+
+ src = s->chr_add_watch(s, cond);
+ g_source_set_callback(src, (GSourceFunc)func, user_data, NULL);
+ tag = g_source_attach(src, NULL);
+ g_source_unref(src);
+
+ return tag;
+}
+
void qemu_chr_delete(CharDriverState *chr)
{
QTAILQ_REMOVE(&chardevs, chr, next);
@@ -3454,3 +3659,33 @@ void qmp_chardev_remove(const char *id, Error **errp)
}
qemu_chr_delete(chr);
}
+
+static void register_types(void)
+{
+ register_char_driver("null", qemu_chr_open_null);
+ register_char_driver("socket", qemu_chr_open_socket);
+ register_char_driver("udp", qemu_chr_open_udp);
+ register_char_driver("memory", qemu_chr_open_ringbuf);
+#ifdef _WIN32
+ register_char_driver("file", qemu_chr_open_win_file_out);
+ register_char_driver("pipe", qemu_chr_open_win_pipe);
+ register_char_driver("console", qemu_chr_open_win_con);
+ register_char_driver("serial", qemu_chr_open_win);
+ register_char_driver("stdio", qemu_chr_open_win_stdio);
+#else
+ register_char_driver("file", qemu_chr_open_file_out);
+ register_char_driver("pipe", qemu_chr_open_pipe);
+ register_char_driver("stdio", qemu_chr_open_stdio);
+#endif
+#ifdef HAVE_CHARDEV_TTY
+ register_char_driver("tty", qemu_chr_open_tty);
+ register_char_driver("serial", qemu_chr_open_tty);
+ register_char_driver("pty", qemu_chr_open_pty);
+#endif
+#ifdef HAVE_CHARDEV_PARPORT
+ register_char_driver("parallel", qemu_chr_open_pp);
+ register_char_driver("parport", qemu_chr_open_pp);
+#endif
+}
+
+type_init(register_types);
diff --git a/qemu-doc.texi b/qemu-doc.texi
index 747e052fcb..af84bef0e9 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -830,7 +830,7 @@ QEMU-based virtual machines.
You can create a Sheepdog disk image with the command:
@example
-qemu-img create sheepdog:@var{image} @var{size}
+qemu-img create sheepdog:///@var{image} @var{size}
@end example
where @var{image} is the Sheepdog image name and @var{size} is its
size.
@@ -838,38 +838,44 @@ size.
To import the existing @var{filename} to Sheepdog, you can use a
convert command.
@example
-qemu-img convert @var{filename} sheepdog:@var{image}
+qemu-img convert @var{filename} sheepdog:///@var{image}
@end example
You can boot from the Sheepdog disk image with the command:
@example
-qemu-system-i386 sheepdog:@var{image}
+qemu-system-i386 sheepdog:///@var{image}
@end example
You can also create a snapshot of the Sheepdog image like qcow2.
@example
-qemu-img snapshot -c @var{tag} sheepdog:@var{image}
+qemu-img snapshot -c @var{tag} sheepdog:///@var{image}
@end example
where @var{tag} is a tag name of the newly created snapshot.
To boot from the Sheepdog snapshot, specify the tag name of the
snapshot.
@example
-qemu-system-i386 sheepdog:@var{image}:@var{tag}
+qemu-system-i386 sheepdog:///@var{image}#@var{tag}
@end example
You can create a cloned image from the existing snapshot.
@example
-qemu-img create -b sheepdog:@var{base}:@var{tag} sheepdog:@var{image}
+qemu-img create -b sheepdog:///@var{base}#@var{tag} sheepdog:///@var{image}
@end example
where @var{base} is a image name of the source snapshot and @var{tag}
is its tag name.
+You can use an unix socket instead of an inet socket:
+
+@example
+qemu-system-i386 sheepdog+unix:///@var{image}?socket=@var{path}
+@end example
+
If the Sheepdog daemon doesn't run on the local host, you need to
specify one of the Sheepdog servers to connect to.
@example
-qemu-img create sheepdog:@var{hostname}:@var{port}:@var{image} @var{size}
-qemu-system-i386 sheepdog:@var{hostname}:@var{port}:@var{image}
+qemu-img create sheepdog://@var{hostname}:@var{port}/@var{image} @var{size}
+qemu-system-i386 sheepdog://@var{hostname}:@var{port}/@var{image}
@end example
@node disk_images_iscsi
diff --git a/qemu-options.hx b/qemu-options.hx
index 797d992804..cd76f2a00c 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1408,7 +1408,8 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
#ifdef CONFIG_VDE
"vde|"
#endif
- "socket],id=str[,option][,option][,...]\n", QEMU_ARCH_ALL)
+ "socket|"
+ "hubport],id=str[,option][,option][,...]\n", QEMU_ARCH_ALL)
STEXI
@item -net nic[,vlan=@var{n}][,macaddr=@var{mac}][,model=@var{type}] [,name=@var{name}][,addr=@var{addr}][,vectors=@var{v}]
@findex -net
@@ -1730,6 +1731,14 @@ vde_switch -F -sock /tmp/myswitch
qemu-system-i386 linux.img -net nic -net vde,sock=/tmp/myswitch
@end example
+@item -netdev hubport,id=@var{id},hubid=@var{hubid}
+
+Create a hub port on QEMU "vlan" @var{hubid}.
+
+The hubport netdev lets you connect a NIC to a QEMU "vlan" instead of a single
+netdev. @code{-net} and @code{-device} with parameter @option{vlan} create the
+required hub automatically.
+
@item -net dump[,vlan=@var{n}][,file=@var{file}][,len=@var{len}]
Dump network traffic on VLAN @var{n} to file @var{file} (@file{qemu-vlan0.pcap} by default).
At most @var{len} bytes (64k by default) per packet are stored. The file format is
@@ -2099,23 +2108,13 @@ QEMU supports using either local sheepdog devices or remote networked
devices.
Syntax for specifying a sheepdog device
-@table @list
-``sheepdog:<vdiname>''
-
-``sheepdog:<vdiname>:<snapid>''
-
-``sheepdog:<vdiname>:<tag>''
-
-``sheepdog:<host>:<port>:<vdiname>''
-
-``sheepdog:<host>:<port>:<vdiname>:<snapid>''
-
-``sheepdog:<host>:<port>:<vdiname>:<tag>''
-@end table
+@example
+sheepdog[+tcp|+unix]://[host:port]/vdiname[?socket=path][#snapid|#tag]
+@end example
Example
@example
-qemu-system-i386 --drive file=sheepdog:192.0.2.1:30000:MyVirtualMachine
+qemu-system-i386 --drive file=sheepdog://192.0.2.1:30000/MyVirtualMachine
@end example
See also @url{http://http://www.osrg.net/sheepdog/}.
@@ -2133,7 +2132,7 @@ gluster[+transport]://[server[:port]]/volname/image[?socket=...]
Example
@example
-qemu-system-x86_84 --drive file=gluster://192.0.2.1/testvol/a.img
+qemu-system-x86_64 --drive file=gluster://192.0.2.1/testvol/a.img
@end example
See also @url{http://www.gluster.org}.
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 799adea1b7..95022e259f 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -822,7 +822,7 @@ Example:
-> { "execute": "netdev_add", "arguments": { "type": "user", "id": "netdev1" } }
<- { "return": {} }
-Note: The supported device options are the same ones supported by the '-net'
+Note: The supported device options are the same ones supported by the '-netdev'
command-line argument, which are listed in the '-help' output or QEMU's
manual
diff --git a/roms/seabios b/roms/seabios
-Subproject 4bd8aebf3534e10d9aa21e820903f2cf9120708
+Subproject 88cb66ea542906ffff8a80ef397b9e3adbb3311
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index 1542e43619..7b7ad60aea 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -384,83 +384,86 @@ int tcp_fconnect(struct socket *so)
* the time it gets to accept(), so... We simply accept
* here and SYN the local-host.
*/
-void
-tcp_connect(struct socket *inso)
+void tcp_connect(struct socket *inso)
{
- Slirp *slirp = inso->slirp;
- struct socket *so;
- struct sockaddr_in addr;
- socklen_t addrlen = sizeof(struct sockaddr_in);
- struct tcpcb *tp;
- int s, opt;
+ Slirp *slirp = inso->slirp;
+ struct socket *so;
+ struct sockaddr_in addr;
+ socklen_t addrlen = sizeof(struct sockaddr_in);
+ struct tcpcb *tp;
+ int s, opt;
- DEBUG_CALL("tcp_connect");
- DEBUG_ARG("inso = %lx", (long)inso);
+ DEBUG_CALL("tcp_connect");
+ DEBUG_ARG("inso = %lx", (long)inso);
- /*
- * If it's an SS_ACCEPTONCE socket, no need to socreate()
- * another socket, just use the accept() socket.
- */
- if (inso->so_state & SS_FACCEPTONCE) {
- /* FACCEPTONCE already have a tcpcb */
- so = inso;
- } else {
- if ((so = socreate(slirp)) == NULL) {
- /* If it failed, get rid of the pending connection */
- closesocket(accept(inso->s,(struct sockaddr *)&addr,&addrlen));
- return;
- }
- if (tcp_attach(so) < 0) {
- free(so); /* NOT sofree */
- return;
- }
- so->so_laddr = inso->so_laddr;
- so->so_lport = inso->so_lport;
- }
+ /*
+ * If it's an SS_ACCEPTONCE socket, no need to socreate()
+ * another socket, just use the accept() socket.
+ */
+ if (inso->so_state & SS_FACCEPTONCE) {
+ /* FACCEPTONCE already have a tcpcb */
+ so = inso;
+ } else {
+ so = socreate(slirp);
+ if (so == NULL) {
+ /* If it failed, get rid of the pending connection */
+ closesocket(accept(inso->s, (struct sockaddr *)&addr, &addrlen));
+ return;
+ }
+ if (tcp_attach(so) < 0) {
+ free(so); /* NOT sofree */
+ return;
+ }
+ so->so_laddr = inso->so_laddr;
+ so->so_lport = inso->so_lport;
+ }
- (void) tcp_mss(sototcpcb(so), 0);
+ tcp_mss(sototcpcb(so), 0);
- if ((s = accept(inso->s,(struct sockaddr *)&addr,&addrlen)) < 0) {
- tcp_close(sototcpcb(so)); /* This will sofree() as well */
- return;
- }
- socket_set_nonblock(s);
- opt = 1;
- setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int));
- opt = 1;
- setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int));
- opt = 1;
- setsockopt(s,IPPROTO_TCP,TCP_NODELAY,(char *)&opt,sizeof(int));
-
- so->so_fport = addr.sin_port;
- so->so_faddr = addr.sin_addr;
- /* Translate connections from localhost to the real hostname */
- if (so->so_faddr.s_addr == 0 ||
- (so->so_faddr.s_addr & loopback_mask) ==
- (loopback_addr.s_addr & loopback_mask)) {
- so->so_faddr = slirp->vhost_addr;
- }
+ s = accept(inso->s, (struct sockaddr *)&addr, &addrlen);
+ if (s < 0) {
+ tcp_close(sototcpcb(so)); /* This will sofree() as well */
+ return;
+ }
+ socket_set_nonblock(s);
+ opt = 1;
+ setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(int));
+ opt = 1;
+ setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (char *)&opt, sizeof(int));
+ socket_set_nodelay(s);
+
+ so->so_fport = addr.sin_port;
+ so->so_faddr = addr.sin_addr;
+ /* Translate connections from localhost to the real hostname */
+ if (so->so_faddr.s_addr == 0 ||
+ (so->so_faddr.s_addr & loopback_mask) ==
+ (loopback_addr.s_addr & loopback_mask)) {
+ so->so_faddr = slirp->vhost_addr;
+ }
- /* Close the accept() socket, set right state */
- if (inso->so_state & SS_FACCEPTONCE) {
- closesocket(so->s); /* If we only accept once, close the accept() socket */
- so->so_state = SS_NOFDREF; /* Don't select it yet, even though we have an FD */
- /* if it's not FACCEPTONCE, it's already NOFDREF */
- }
- so->s = s;
- so->so_state |= SS_INCOMING;
+ /* Close the accept() socket, set right state */
+ if (inso->so_state & SS_FACCEPTONCE) {
+ /* If we only accept once, close the accept() socket */
+ closesocket(so->s);
+
+ /* Don't select it yet, even though we have an FD */
+ /* if it's not FACCEPTONCE, it's already NOFDREF */
+ so->so_state = SS_NOFDREF;
+ }
+ so->s = s;
+ so->so_state |= SS_INCOMING;
- so->so_iptos = tcp_tos(so);
- tp = sototcpcb(so);
+ so->so_iptos = tcp_tos(so);
+ tp = sototcpcb(so);
- tcp_template(tp);
+ tcp_template(tp);
- tp->t_state = TCPS_SYN_SENT;
- tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
- tp->iss = slirp->tcp_iss;
- slirp->tcp_iss += TCP_ISSINCR/2;
- tcp_sendseqinit(tp);
- tcp_output(tp);
+ tp->t_state = TCPS_SYN_SENT;
+ tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
+ tp->iss = slirp->tcp_iss;
+ slirp->tcp_iss += TCP_ISSINCR/2;
+ tcp_sendseqinit(tp);
+ tcp_output(tp);
}
/*
diff --git a/spice-qemu-char.c b/spice-qemu-char.c
index a4d7de8c4f..aea3d24e7d 100644
--- a/spice-qemu-char.c
+++ b/spice-qemu-char.c
@@ -307,3 +307,13 @@ void qemu_spice_register_ports(void)
}
}
#endif
+
+static void register_types(void)
+{
+ register_char_driver("spicevmc", qemu_chr_open_spice);
+#if SPICE_SERVER_VERSION >= 0x000c02
+ register_char_driver("spiceport", qemu_chr_open_spice_port);
+#endif
+}
+
+type_init(register_types);
diff --git a/target-alpha/cpu-qom.h b/target-alpha/cpu-qom.h
index c0f6c6d165..252bd14821 100644
--- a/target-alpha/cpu-qom.h
+++ b/target-alpha/cpu-qom.h
@@ -72,5 +72,6 @@ static inline AlphaCPU *alpha_env_get_cpu(CPUAlphaState *env)
#define ENV_GET_CPU(e) CPU(alpha_env_get_cpu(e))
+#define ENV_OFFSET offsetof(AlphaCPU, env)
#endif
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index f8f76957a9..657f5e1e5f 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -3411,7 +3411,7 @@ static inline void gen_intermediate_code_internal(CPUAlphaState *env,
if (max_insns == 0)
max_insns = CF_COUNT_MASK;
- gen_icount_start();
+ gen_tb_start();
do {
if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
@@ -3478,7 +3478,7 @@ static inline void gen_intermediate_code_internal(CPUAlphaState *env,
abort();
}
- gen_icount_end(tb, num_insns);
+ gen_tb_end(tb, num_insns);
*tcg_ctx.gen_opc_ptr = INDEX_op_end;
if (search_pc) {
j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
diff --git a/target-arm/Makefile.objs b/target-arm/Makefile.objs
index b6f1a9ebf6..d89b57c114 100644
--- a/target-arm/Makefile.objs
+++ b/target-arm/Makefile.objs
@@ -1,4 +1,5 @@
obj-y += arm-semi.o
obj-$(CONFIG_SOFTMMU) += machine.o
+obj-$(CONFIG_KVM) += kvm.o
obj-y += translate.o op_helper.o helper.o cpu.o
obj-y += neon_helper.o iwmmxt_helper.o
diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
index aff7bf302e..7539727768 100644
--- a/target-arm/cpu-qom.h
+++ b/target-arm/cpu-qom.h
@@ -109,6 +109,8 @@ static inline ARMCPU *arm_env_get_cpu(CPUARMState *env)
#define ENV_GET_CPU(e) CPU(arm_env_get_cpu(e))
+#define ENV_OFFSET offsetof(ARMCPU, env)
+
void register_cp_regs_for_features(ARMCPU *cpu);
#endif
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 2902ba575b..c28a0d94c3 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -237,6 +237,7 @@ void arm_translate_init(void);
void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu);
int cpu_arm_exec(CPUARMState *s);
void do_interrupt(CPUARMState *);
+int bank_number(int mode);
void switch_mode(CPUARMState *, int);
uint32_t do_arm_semihosting(CPUARMState *env);
diff --git a/target-arm/helper.c b/target-arm/helper.c
index e97e1a59c7..6cad936d3e 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1617,7 +1617,7 @@ uint32_t HELPER(get_r13_banked)(CPUARMState *env, uint32_t mode)
#else
/* Map CPU modes onto saved register banks. */
-static inline int bank_number(CPUARMState *env, int mode)
+int bank_number(int mode)
{
switch (mode) {
case ARM_CPU_MODE_USR:
@@ -1634,8 +1634,7 @@ static inline int bank_number(CPUARMState *env, int mode)
case ARM_CPU_MODE_FIQ:
return 5;
}
- cpu_abort(env, "Bad mode %x\n", mode);
- return -1;
+ hw_error("bank number requested for bad CPSR mode value 0x%x\n", mode);
}
void switch_mode(CPUARMState *env, int mode)
@@ -1655,12 +1654,12 @@ void switch_mode(CPUARMState *env, int mode)
memcpy (env->regs + 8, env->fiq_regs, 5 * sizeof(uint32_t));
}
- i = bank_number(env, old_mode);
+ i = bank_number(old_mode);
env->banked_r13[i] = env->regs[13];
env->banked_r14[i] = env->regs[14];
env->banked_spsr[i] = env->spsr;
- i = bank_number(env, mode);
+ i = bank_number(mode);
env->regs[13] = env->banked_r13[i];
env->regs[14] = env->banked_r14[i];
env->spsr = env->banked_spsr[i];
@@ -2530,7 +2529,7 @@ void HELPER(set_r13_banked)(CPUARMState *env, uint32_t mode, uint32_t val)
if ((env->uncached_cpsr & CPSR_M) == mode) {
env->regs[13] = val;
} else {
- env->banked_r13[bank_number(env, mode)] = val;
+ env->banked_r13[bank_number(mode)] = val;
}
}
@@ -2539,7 +2538,7 @@ uint32_t HELPER(get_r13_banked)(CPUARMState *env, uint32_t mode)
if ((env->uncached_cpsr & CPSR_M) == mode) {
return env->regs[13];
} else {
- return env->banked_r13[bank_number(env, mode)];
+ return env->banked_r13[bank_number(mode)];
}
}
diff --git a/target-arm/kvm.c b/target-arm/kvm.c
new file mode 100644
index 0000000000..82e2e084c3
--- /dev/null
+++ b/target-arm/kvm.c
@@ -0,0 +1,493 @@
+/*
+ * ARM implementation of KVM hooks
+ *
+ * Copyright Christoffer Dall 2009-2010
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+
+#include <linux/kvm.h>
+
+#include "qemu-common.h"
+#include "qemu/timer.h"
+#include "sysemu/sysemu.h"
+#include "sysemu/kvm.h"
+#include "kvm_arm.h"
+#include "cpu.h"
+#include "hw/arm-misc.h"
+
+const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
+ KVM_CAP_LAST_INFO
+};
+
+int kvm_arch_init(KVMState *s)
+{
+ /* For ARM interrupt delivery is always asynchronous,
+ * whether we are using an in-kernel VGIC or not.
+ */
+ kvm_async_interrupts_allowed = true;
+ return 0;
+}
+
+unsigned long kvm_arch_vcpu_id(CPUState *cpu)
+{
+ return cpu->cpu_index;
+}
+
+int kvm_arch_init_vcpu(CPUState *cs)
+{
+ struct kvm_vcpu_init init;
+ int ret;
+ uint64_t v;
+ struct kvm_one_reg r;
+
+ init.target = KVM_ARM_TARGET_CORTEX_A15;
+ memset(init.features, 0, sizeof(init.features));
+ ret = kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init);
+ if (ret) {
+ return ret;
+ }
+ /* Query the kernel to make sure it supports 32 VFP
+ * registers: QEMU's "cortex-a15" CPU is always a
+ * VFP-D32 core. The simplest way to do this is just
+ * to attempt to read register d31.
+ */
+ r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP | 31;
+ r.addr = (uintptr_t)(&v);
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r);
+ if (ret == ENOENT) {
+ return EINVAL;
+ }
+ return ret;
+}
+
+/* We track all the KVM devices which need their memory addresses
+ * passing to the kernel in a list of these structures.
+ * When board init is complete we run through the list and
+ * tell the kernel the base addresses of the memory regions.
+ * We use a MemoryListener to track mapping and unmapping of
+ * the regions during board creation, so the board models don't
+ * need to do anything special for the KVM case.
+ */
+typedef struct KVMDevice {
+ struct kvm_arm_device_addr kda;
+ MemoryRegion *mr;
+ QSLIST_ENTRY(KVMDevice) entries;
+} KVMDevice;
+
+static QSLIST_HEAD(kvm_devices_head, KVMDevice) kvm_devices_head;
+
+static void kvm_arm_devlistener_add(MemoryListener *listener,
+ MemoryRegionSection *section)
+{
+ KVMDevice *kd;
+
+ QSLIST_FOREACH(kd, &kvm_devices_head, entries) {
+ if (section->mr == kd->mr) {
+ kd->kda.addr = section->offset_within_address_space;
+ }
+ }
+}
+
+static void kvm_arm_devlistener_del(MemoryListener *listener,
+ MemoryRegionSection *section)
+{
+ KVMDevice *kd;
+
+ QSLIST_FOREACH(kd, &kvm_devices_head, entries) {
+ if (section->mr == kd->mr) {
+ kd->kda.addr = -1;
+ }
+ }
+}
+
+static MemoryListener devlistener = {
+ .region_add = kvm_arm_devlistener_add,
+ .region_del = kvm_arm_devlistener_del,
+};
+
+static void kvm_arm_machine_init_done(Notifier *notifier, void *data)
+{
+ KVMDevice *kd, *tkd;
+
+ memory_listener_unregister(&devlistener);
+ QSLIST_FOREACH_SAFE(kd, &kvm_devices_head, entries, tkd) {
+ if (kd->kda.addr != -1) {
+ if (kvm_vm_ioctl(kvm_state, KVM_ARM_SET_DEVICE_ADDR,
+ &kd->kda) < 0) {
+ fprintf(stderr, "KVM_ARM_SET_DEVICE_ADDRESS failed: %s\n",
+ strerror(errno));
+ abort();
+ }
+ }
+ g_free(kd);
+ }
+}
+
+static Notifier notify = {
+ .notify = kvm_arm_machine_init_done,
+};
+
+void kvm_arm_register_device(MemoryRegion *mr, uint64_t devid)
+{
+ KVMDevice *kd;
+
+ if (!kvm_irqchip_in_kernel()) {
+ return;
+ }
+
+ if (QSLIST_EMPTY(&kvm_devices_head)) {
+ memory_listener_register(&devlistener, NULL);
+ qemu_add_machine_init_done_notifier(&notify);
+ }
+ kd = g_new0(KVMDevice, 1);
+ kd->mr = mr;
+ kd->kda.id = devid;
+ kd->kda.addr = -1;
+ QSLIST_INSERT_HEAD(&kvm_devices_head, kd, entries);
+}
+
+typedef struct Reg {
+ uint64_t id;
+ int offset;
+} Reg;
+
+#define COREREG(KERNELNAME, QEMUFIELD) \
+ { \
+ KVM_REG_ARM | KVM_REG_SIZE_U32 | \
+ KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(KERNELNAME), \
+ offsetof(CPUARMState, QEMUFIELD) \
+ }
+
+#define CP15REG(CRN, CRM, OPC1, OPC2, QEMUFIELD) \
+ { \
+ KVM_REG_ARM | KVM_REG_SIZE_U32 | \
+ (15 << KVM_REG_ARM_COPROC_SHIFT) | \
+ ((CRN) << KVM_REG_ARM_32_CRN_SHIFT) | \
+ ((CRM) << KVM_REG_ARM_CRM_SHIFT) | \
+ ((OPC1) << KVM_REG_ARM_OPC1_SHIFT) | \
+ ((OPC2) << KVM_REG_ARM_32_OPC2_SHIFT), \
+ offsetof(CPUARMState, QEMUFIELD) \
+ }
+
+#define VFPSYSREG(R) \
+ { \
+ KVM_REG_ARM | KVM_REG_SIZE_U32 | KVM_REG_ARM_VFP | \
+ KVM_REG_ARM_VFP_##R, \
+ offsetof(CPUARMState, vfp.xregs[ARM_VFP_##R]) \
+ }
+
+static const Reg regs[] = {
+ /* R0_usr .. R14_usr */
+ COREREG(usr_regs.uregs[0], regs[0]),
+ COREREG(usr_regs.uregs[1], regs[1]),
+ COREREG(usr_regs.uregs[2], regs[2]),
+ COREREG(usr_regs.uregs[3], regs[3]),
+ COREREG(usr_regs.uregs[4], regs[4]),
+ COREREG(usr_regs.uregs[5], regs[5]),
+ COREREG(usr_regs.uregs[6], regs[6]),
+ COREREG(usr_regs.uregs[7], regs[7]),
+ COREREG(usr_regs.uregs[8], usr_regs[0]),
+ COREREG(usr_regs.uregs[9], usr_regs[1]),
+ COREREG(usr_regs.uregs[10], usr_regs[2]),
+ COREREG(usr_regs.uregs[11], usr_regs[3]),
+ COREREG(usr_regs.uregs[12], usr_regs[4]),
+ COREREG(usr_regs.uregs[13], banked_r13[0]),
+ COREREG(usr_regs.uregs[14], banked_r14[0]),
+ /* R13, R14, SPSR for SVC, ABT, UND, IRQ banks */
+ COREREG(svc_regs[0], banked_r13[1]),
+ COREREG(svc_regs[1], banked_r14[1]),
+ COREREG(svc_regs[2], banked_spsr[1]),
+ COREREG(abt_regs[0], banked_r13[2]),
+ COREREG(abt_regs[1], banked_r14[2]),
+ COREREG(abt_regs[2], banked_spsr[2]),
+ COREREG(und_regs[0], banked_r13[3]),
+ COREREG(und_regs[1], banked_r14[3]),
+ COREREG(und_regs[2], banked_spsr[3]),
+ COREREG(irq_regs[0], banked_r13[4]),
+ COREREG(irq_regs[1], banked_r14[4]),
+ COREREG(irq_regs[2], banked_spsr[4]),
+ /* R8_fiq .. R14_fiq and SPSR_fiq */
+ COREREG(fiq_regs[0], fiq_regs[0]),
+ COREREG(fiq_regs[1], fiq_regs[1]),
+ COREREG(fiq_regs[2], fiq_regs[2]),
+ COREREG(fiq_regs[3], fiq_regs[3]),
+ COREREG(fiq_regs[4], fiq_regs[4]),
+ COREREG(fiq_regs[5], banked_r13[5]),
+ COREREG(fiq_regs[6], banked_r14[5]),
+ COREREG(fiq_regs[7], banked_spsr[5]),
+ /* R15 */
+ COREREG(usr_regs.uregs[15], regs[15]),
+ /* A non-comprehensive set of cp15 registers.
+ * TODO: drive this from the cp_regs hashtable instead.
+ */
+ CP15REG(1, 0, 0, 0, cp15.c1_sys), /* SCTLR */
+ CP15REG(2, 0, 0, 2, cp15.c2_control), /* TTBCR */
+ CP15REG(3, 0, 0, 0, cp15.c3), /* DACR */
+ /* VFP system registers */
+ VFPSYSREG(FPSID),
+ VFPSYSREG(MVFR1),
+ VFPSYSREG(MVFR0),
+ VFPSYSREG(FPEXC),
+ VFPSYSREG(FPINST),
+ VFPSYSREG(FPINST2),
+};
+
+int kvm_arch_put_registers(CPUState *cs, int level)
+{
+ ARMCPU *cpu = ARM_CPU(cs);
+ CPUARMState *env = &cpu->env;
+ struct kvm_one_reg r;
+ int mode, bn;
+ int ret, i;
+ uint32_t cpsr, fpscr;
+ uint64_t ttbr;
+
+ /* Make sure the banked regs are properly set */
+ mode = env->uncached_cpsr & CPSR_M;
+ bn = bank_number(mode);
+ if (mode == ARM_CPU_MODE_FIQ) {
+ memcpy(env->fiq_regs, env->regs + 8, 5 * sizeof(uint32_t));
+ } else {
+ memcpy(env->usr_regs, env->regs + 8, 5 * sizeof(uint32_t));
+ }
+ env->banked_r13[bn] = env->regs[13];
+ env->banked_r14[bn] = env->regs[14];
+ env->banked_spsr[bn] = env->spsr;
+
+ /* Now we can safely copy stuff down to the kernel */
+ for (i = 0; i < ARRAY_SIZE(regs); i++) {
+ r.id = regs[i].id;
+ r.addr = (uintptr_t)(env) + regs[i].offset;
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &r);
+ if (ret) {
+ return ret;
+ }
+ }
+
+ /* Special cases which aren't a single CPUARMState field */
+ cpsr = cpsr_read(env);
+ r.id = KVM_REG_ARM | KVM_REG_SIZE_U32 |
+ KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(usr_regs.ARM_cpsr);
+ r.addr = (uintptr_t)(&cpsr);
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &r);
+ if (ret) {
+ return ret;
+ }
+
+ /* TTBR0: cp15 crm=2 opc1=0 */
+ ttbr = ((uint64_t)env->cp15.c2_base0_hi << 32) | env->cp15.c2_base0;
+ r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | (15 << KVM_REG_ARM_COPROC_SHIFT) |
+ (2 << KVM_REG_ARM_CRM_SHIFT) | (0 << KVM_REG_ARM_OPC1_SHIFT);
+ r.addr = (uintptr_t)(&ttbr);
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &r);
+ if (ret) {
+ return ret;
+ }
+
+ /* TTBR1: cp15 crm=2 opc1=1 */
+ ttbr = ((uint64_t)env->cp15.c2_base1_hi << 32) | env->cp15.c2_base1;
+ r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | (15 << KVM_REG_ARM_COPROC_SHIFT) |
+ (2 << KVM_REG_ARM_CRM_SHIFT) | (1 << KVM_REG_ARM_OPC1_SHIFT);
+ r.addr = (uintptr_t)(&ttbr);
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &r);
+ if (ret) {
+ return ret;
+ }
+
+ /* VFP registers */
+ r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP;
+ for (i = 0; i < 32; i++) {
+ r.addr = (uintptr_t)(&env->vfp.regs[i]);
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &r);
+ if (ret) {
+ return ret;
+ }
+ r.id++;
+ }
+
+ r.id = KVM_REG_ARM | KVM_REG_SIZE_U32 | KVM_REG_ARM_VFP |
+ KVM_REG_ARM_VFP_FPSCR;
+ fpscr = vfp_get_fpscr(env);
+ r.addr = (uintptr_t)&fpscr;
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &r);
+
+ return ret;
+}
+
+int kvm_arch_get_registers(CPUState *cs)
+{
+ ARMCPU *cpu = ARM_CPU(cs);
+ CPUARMState *env = &cpu->env;
+ struct kvm_one_reg r;
+ int mode, bn;
+ int ret, i;
+ uint32_t cpsr, fpscr;
+ uint64_t ttbr;
+
+ for (i = 0; i < ARRAY_SIZE(regs); i++) {
+ r.id = regs[i].id;
+ r.addr = (uintptr_t)(env) + regs[i].offset;
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r);
+ if (ret) {
+ return ret;
+ }
+ }
+
+ /* Special cases which aren't a single CPUARMState field */
+ r.id = KVM_REG_ARM | KVM_REG_SIZE_U32 |
+ KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(usr_regs.ARM_cpsr);
+ r.addr = (uintptr_t)(&cpsr);
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r);
+ if (ret) {
+ return ret;
+ }
+ cpsr_write(env, cpsr, 0xffffffff);
+
+ /* TTBR0: cp15 crm=2 opc1=0 */
+ r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | (15 << KVM_REG_ARM_COPROC_SHIFT) |
+ (2 << KVM_REG_ARM_CRM_SHIFT) | (0 << KVM_REG_ARM_OPC1_SHIFT);
+ r.addr = (uintptr_t)(&ttbr);
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r);
+ if (ret) {
+ return ret;
+ }
+ env->cp15.c2_base0_hi = ttbr >> 32;
+ env->cp15.c2_base0 = ttbr;
+
+ /* TTBR1: cp15 crm=2 opc1=1 */
+ r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | (15 << KVM_REG_ARM_COPROC_SHIFT) |
+ (2 << KVM_REG_ARM_CRM_SHIFT) | (1 << KVM_REG_ARM_OPC1_SHIFT);
+ r.addr = (uintptr_t)(&ttbr);
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r);
+ if (ret) {
+ return ret;
+ }
+ env->cp15.c2_base1_hi = ttbr >> 32;
+ env->cp15.c2_base1 = ttbr;
+
+ /* Make sure the current mode regs are properly set */
+ mode = env->uncached_cpsr & CPSR_M;
+ bn = bank_number(mode);
+ if (mode == ARM_CPU_MODE_FIQ) {
+ memcpy(env->regs + 8, env->fiq_regs, 5 * sizeof(uint32_t));
+ } else {
+ memcpy(env->regs + 8, env->usr_regs, 5 * sizeof(uint32_t));
+ }
+ env->regs[13] = env->banked_r13[bn];
+ env->regs[14] = env->banked_r14[bn];
+ env->spsr = env->banked_spsr[bn];
+
+ /* The main GET_ONE_REG loop above set c2_control, but we need to
+ * update some extra cached precomputed values too.
+ * When this is driven from the cp_regs hashtable then this ugliness
+ * can disappear because we'll use the access function which sets
+ * these values automatically.
+ */
+ env->cp15.c2_mask = ~(0xffffffffu >> env->cp15.c2_control);
+ env->cp15.c2_base_mask = ~(0x3fffu >> env->cp15.c2_control);
+
+ /* VFP registers */
+ r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP;
+ for (i = 0; i < 32; i++) {
+ r.addr = (uintptr_t)(&env->vfp.regs[i]);
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r);
+ if (ret) {
+ return ret;
+ }
+ r.id++;
+ }
+
+ r.id = KVM_REG_ARM | KVM_REG_SIZE_U32 | KVM_REG_ARM_VFP |
+ KVM_REG_ARM_VFP_FPSCR;
+ r.addr = (uintptr_t)&fpscr;
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r);
+ if (ret) {
+ return ret;
+ }
+ vfp_set_fpscr(env, fpscr);
+
+ return 0;
+}
+
+void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run)
+{
+}
+
+void kvm_arch_post_run(CPUState *cs, struct kvm_run *run)
+{
+}
+
+int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
+{
+ return 0;
+}
+
+void kvm_arch_reset_vcpu(CPUState *cs)
+{
+}
+
+bool kvm_arch_stop_on_emulation_error(CPUState *cs)
+{
+ return true;
+}
+
+int kvm_arch_process_async_events(CPUState *cs)
+{
+ return 0;
+}
+
+int kvm_arch_on_sigbus_vcpu(CPUState *cs, int code, void *addr)
+{
+ return 1;
+}
+
+int kvm_arch_on_sigbus(int code, void *addr)
+{
+ return 1;
+}
+
+void kvm_arch_update_guest_debug(CPUState *cs, struct kvm_guest_debug *dbg)
+{
+ qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__);
+}
+
+int kvm_arch_insert_sw_breakpoint(CPUState *cs,
+ struct kvm_sw_breakpoint *bp)
+{
+ qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__);
+ return -EINVAL;
+}
+
+int kvm_arch_insert_hw_breakpoint(target_ulong addr,
+ target_ulong len, int type)
+{
+ qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__);
+ return -EINVAL;
+}
+
+int kvm_arch_remove_hw_breakpoint(target_ulong addr,
+ target_ulong len, int type)
+{
+ qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__);
+ return -EINVAL;
+}
+
+int kvm_arch_remove_sw_breakpoint(CPUState *cs,
+ struct kvm_sw_breakpoint *bp)
+{
+ qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__);
+ return -EINVAL;
+}
+
+void kvm_arch_remove_all_hw_breakpoints(void)
+{
+ qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__);
+}
diff --git a/target-arm/kvm_arm.h b/target-arm/kvm_arm.h
new file mode 100644
index 0000000000..b1c54ffb5d
--- /dev/null
+++ b/target-arm/kvm_arm.h
@@ -0,0 +1,32 @@
+/*
+ * QEMU KVM support -- ARM specific functions.
+ *
+ * Copyright (c) 2012 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef QEMU_KVM_ARM_H
+#define QEMU_KVM_ARM_H
+
+#include "sysemu/kvm.h"
+#include "exec/memory.h"
+
+/**
+ * kvm_arm_register_device:
+ * @mr: memory region for this device
+ * @devid: the KVM device ID
+ *
+ * Remember the memory region @mr, and when it is mapped by the
+ * machine model, tell the kernel that base address using the
+ * KVM_SET_DEVICE_ADDRESS ioctl. @devid should be the ID of
+ * the device as defined by KVM_SET_DEVICE_ADDRESS.
+ * The machine model may map and unmap the device multiple times;
+ * the kernel will only be told the final address at the point
+ * where machine init is complete.
+ */
+void kvm_arm_register_device(MemoryRegion *mr, uint64_t devid);
+
+#endif
diff --git a/target-arm/translate.c b/target-arm/translate.c
index f2f649dffd..35a21be931 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6601,6 +6601,70 @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
}
#endif
+/* gen_srs:
+ * @env: CPUARMState
+ * @s: DisasContext
+ * @mode: mode field from insn (which stack to store to)
+ * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
+ * @writeback: true if writeback bit set
+ *
+ * Generate code for the SRS (Store Return State) insn.
+ */
+static void gen_srs(DisasContext *s,
+ uint32_t mode, uint32_t amode, bool writeback)
+{
+ int32_t offset;
+ TCGv_i32 addr = tcg_temp_new_i32();
+ TCGv_i32 tmp = tcg_const_i32(mode);
+ gen_helper_get_r13_banked(addr, cpu_env, tmp);
+ tcg_temp_free_i32(tmp);
+ switch (amode) {
+ case 0: /* DA */
+ offset = -4;
+ break;
+ case 1: /* IA */
+ offset = 0;
+ break;
+ case 2: /* DB */
+ offset = -8;
+ break;
+ case 3: /* IB */
+ offset = 4;
+ break;
+ default:
+ abort();
+ }
+ tcg_gen_addi_i32(addr, addr, offset);
+ tmp = load_reg(s, 14);
+ gen_st32(tmp, addr, 0);
+ tmp = load_cpu_field(spsr);
+ tcg_gen_addi_i32(addr, addr, 4);
+ gen_st32(tmp, addr, 0);
+ if (writeback) {
+ switch (amode) {
+ case 0:
+ offset = -8;
+ break;
+ case 1:
+ offset = 4;
+ break;
+ case 2:
+ offset = -4;
+ break;
+ case 3:
+ offset = 0;
+ break;
+ default:
+ abort();
+ }
+ tcg_gen_addi_i32(addr, addr, offset);
+ tmp = tcg_const_i32(mode);
+ gen_helper_set_r13_banked(cpu_env, tmp, addr);
+ tcg_temp_free_i32(tmp);
+ }
+ tcg_temp_free_i32(addr);
+}
+
static void disas_arm_insn(CPUARMState * env, DisasContext *s)
{
unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
@@ -6693,49 +6757,11 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
}
} else if ((insn & 0x0e5fffe0) == 0x084d0500) {
/* srs */
- int32_t offset;
- if (IS_USER(s))
+ if (IS_USER(s)) {
goto illegal_op;
- ARCH(6);
- op1 = (insn & 0x1f);
- addr = tcg_temp_new_i32();
- tmp = tcg_const_i32(op1);
- gen_helper_get_r13_banked(addr, cpu_env, tmp);
- tcg_temp_free_i32(tmp);
- i = (insn >> 23) & 3;
- switch (i) {
- case 0: offset = -4; break; /* DA */
- case 1: offset = 0; break; /* IA */
- case 2: offset = -8; break; /* DB */
- case 3: offset = 4; break; /* IB */
- default: abort();
}
- if (offset)
- tcg_gen_addi_i32(addr, addr, offset);
- tmp = load_reg(s, 14);
- gen_st32(tmp, addr, 0);
- tmp = load_cpu_field(spsr);
- tcg_gen_addi_i32(addr, addr, 4);
- gen_st32(tmp, addr, 0);
- if (insn & (1 << 21)) {
- /* Base writeback. */
- switch (i) {
- case 0: offset = -8; break;
- case 1: offset = 4; break;
- case 2: offset = -4; break;
- case 3: offset = 0; break;
- default: abort();
- }
- if (offset)
- tcg_gen_addi_i32(addr, addr, offset);
- tmp = tcg_const_i32(op1);
- gen_helper_set_r13_banked(cpu_env, tmp, addr);
- tcg_temp_free_i32(tmp);
- tcg_temp_free_i32(addr);
- } else {
- tcg_temp_free_i32(addr);
- }
- return;
+ ARCH(6);
+ gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
} else if ((insn & 0x0e50ffe0) == 0x08100a00) {
/* rfe */
int32_t offset;
@@ -8154,9 +8180,10 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
} else {
/* Load/store multiple, RFE, SRS. */
if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
- /* Not available in user mode. */
- if (IS_USER(s))
+ /* RFE, SRS: not available in user mode or on M profile */
+ if (IS_USER(s) || IS_M(env)) {
goto illegal_op;
+ }
if (insn & (1 << 20)) {
/* rfe */
addr = load_reg(s, rn);
@@ -8180,32 +8207,8 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
gen_rfe(s, tmp, tmp2);
} else {
/* srs */
- op = (insn & 0x1f);
- addr = tcg_temp_new_i32();
- tmp = tcg_const_i32(op);
- gen_helper_get_r13_banked(addr, cpu_env, tmp);
- tcg_temp_free_i32(tmp);
- if ((insn & (1 << 24)) == 0) {
- tcg_gen_addi_i32(addr, addr, -8);
- }
- tmp = load_reg(s, 14);
- gen_st32(tmp, addr, 0);
- tcg_gen_addi_i32(addr, addr, 4);
- tmp = tcg_temp_new_i32();
- gen_helper_cpsr_read(tmp, cpu_env);
- gen_st32(tmp, addr, 0);
- if (insn & (1 << 21)) {
- if ((insn & (1 << 24)) == 0) {
- tcg_gen_addi_i32(addr, addr, -4);
- } else {
- tcg_gen_addi_i32(addr, addr, 4);
- }
- tmp = tcg_const_i32(op);
- gen_helper_set_r13_banked(cpu_env, tmp, addr);
- tcg_temp_free_i32(tmp);
- } else {
- tcg_temp_free_i32(addr);
- }
+ gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
+ insn & (1 << 21));
}
} else {
int i, loaded_base = 0;
@@ -9808,7 +9811,7 @@ static inline void gen_intermediate_code_internal(CPUARMState *env,
if (max_insns == 0)
max_insns = CF_COUNT_MASK;
- gen_icount_start();
+ gen_tb_start();
tcg_clear_temp_count();
@@ -10011,7 +10014,7 @@ static inline void gen_intermediate_code_internal(CPUARMState *env,
}
done_generating:
- gen_icount_end(tb, num_insns);
+ gen_tb_end(tb, num_insns);
*tcg_ctx.gen_opc_ptr = INDEX_op_end;
#ifdef DEBUG_DISAS
diff --git a/target-cris/cpu-qom.h b/target-cris/cpu-qom.h
index 2bac71fd81..11e528661d 100644
--- a/target-cris/cpu-qom.h
+++ b/target-cris/cpu-qom.h
@@ -71,5 +71,6 @@ static inline CRISCPU *cris_env_get_cpu(CPUCRISState *env)
#define ENV_GET_CPU(e) CPU(cris_env_get_cpu(e))
+#define ENV_OFFSET offsetof(CRISCPU, env)
#endif
diff --git a/target-cris/translate.c b/target-cris/translate.c
index 14c167fb0b..ec71ef4721 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -3250,7 +3250,7 @@ gen_intermediate_code_internal(CPUCRISState *env, TranslationBlock *tb,
max_insns = CF_COUNT_MASK;
}
- gen_icount_start();
+ gen_tb_start();
do {
check_breakpoint(env, dc);
@@ -3391,7 +3391,7 @@ gen_intermediate_code_internal(CPUCRISState *env, TranslationBlock *tb,
break;
}
}
- gen_icount_end(tb, num_insns);
+ gen_tb_end(tb, num_insns);
*tcg_ctx.gen_opc_ptr = INDEX_op_end;
if (search_pc) {
j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
index 48e6b54b1f..b7bdcb6892 100644
--- a/target-i386/cpu-qom.h
+++ b/target-i386/cpu-qom.h
@@ -74,5 +74,6 @@ static inline X86CPU *x86_env_get_cpu(CPUX86State *env)
#define ENV_GET_CPU(e) CPU(x86_env_get_cpu(e))
+#define ENV_OFFSET offsetof(X86CPU, env)
#endif
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 5582e5f4e6..8fb736a5b4 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2088,7 +2088,8 @@ static void x86_cpu_apic_init(X86CPU *cpu, Error **errp)
/* NOTE: the APIC is directly connected to the CPU - it is not
on the global memory bus. */
/* XXX: what if the base changes? */
- sysbus_mmio_map(SYS_BUS_DEVICE(env->apic_state), 0, MSI_ADDR_BASE);
+ sysbus_mmio_map_overlap(SYS_BUS_DEVICE(env->apic_state), 0,
+ MSI_ADDR_BASE, 0x1000);
apic_mapped = 1;
}
}
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 3b92f3b227..705147a00b 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -8324,7 +8324,7 @@ static inline void gen_intermediate_code_internal(CPUX86State *env,
if (max_insns == 0)
max_insns = CF_COUNT_MASK;
- gen_icount_start();
+ gen_tb_start();
for(;;) {
if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
@@ -8382,7 +8382,7 @@ static inline void gen_intermediate_code_internal(CPUX86State *env,
}
if (tb->cflags & CF_LAST_IO)
gen_io_end();
- gen_icount_end(tb, num_insns);
+ gen_tb_end(tb, num_insns);
*tcg_ctx.gen_opc_ptr = INDEX_op_end;
/* we don't forget to fill the last values */
if (search_pc) {
diff --git a/target-lm32/cpu-qom.h b/target-lm32/cpu-qom.h
index d7525b300c..c0b6ce5897 100644
--- a/target-lm32/cpu-qom.h
+++ b/target-lm32/cpu-qom.h
@@ -69,5 +69,6 @@ static inline LM32CPU *lm32_env_get_cpu(CPULM32State *env)
#define ENV_GET_CPU(e) CPU(lm32_env_get_cpu(e))
+#define ENV_OFFSET offsetof(LM32CPU, env)
#endif
diff --git a/target-lm32/translate.c b/target-lm32/translate.c
index ccaf838afa..695d9c59b2 100644
--- a/target-lm32/translate.c
+++ b/target-lm32/translate.c
@@ -1040,7 +1040,7 @@ static void gen_intermediate_code_internal(CPULM32State *env,
max_insns = CF_COUNT_MASK;
}
- gen_icount_start();
+ gen_tb_start();
do {
check_breakpoint(env, dc);
@@ -1102,7 +1102,7 @@ static void gen_intermediate_code_internal(CPULM32State *env,
}
}
- gen_icount_end(tb, num_insns);
+ gen_tb_end(tb, num_insns);
*tcg_ctx.gen_opc_ptr = INDEX_op_end;
if (search_pc) {
j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
diff --git a/target-m68k/cpu-qom.h b/target-m68k/cpu-qom.h
index 20e5684552..f4c33b2eb3 100644
--- a/target-m68k/cpu-qom.h
+++ b/target-m68k/cpu-qom.h
@@ -68,5 +68,6 @@ static inline M68kCPU *m68k_env_get_cpu(CPUM68KState *env)
#define ENV_GET_CPU(e) CPU(m68k_env_get_cpu(e))
+#define ENV_OFFSET offsetof(M68kCPU, env)
#endif
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 3f1478cc20..20a86d8efe 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -2999,7 +2999,7 @@ gen_intermediate_code_internal(CPUM68KState *env, TranslationBlock *tb,
if (max_insns == 0)
max_insns = CF_COUNT_MASK;
- gen_icount_start();
+ gen_tb_start();
do {
pc_offset = dc->pc - pc_start;
gen_throws_exception = NULL;
@@ -3063,7 +3063,7 @@ gen_intermediate_code_internal(CPUM68KState *env, TranslationBlock *tb,
break;
}
}
- gen_icount_end(tb, num_insns);
+ gen_tb_end(tb, num_insns);
*tcg_ctx.gen_opc_ptr = INDEX_op_end;
#ifdef DEBUG_DISAS
diff --git a/target-microblaze/cpu-qom.h b/target-microblaze/cpu-qom.h
index 5ea911c8e4..a0248a5a22 100644
--- a/target-microblaze/cpu-qom.h
+++ b/target-microblaze/cpu-qom.h
@@ -68,5 +68,6 @@ static inline MicroBlazeCPU *mb_env_get_cpu(CPUMBState *env)
#define ENV_GET_CPU(e) CPU(mb_env_get_cpu(e))
+#define ENV_OFFSET offsetof(MicroBlazeCPU, env)
#endif
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index 687b7d1433..a74da8e1a5 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -1770,7 +1770,7 @@ gen_intermediate_code_internal(CPUMBState *env, TranslationBlock *tb,
if (max_insns == 0)
max_insns = CF_COUNT_MASK;
- gen_icount_start();
+ gen_tb_start();
do
{
#if SIM_COMPAT
@@ -1894,7 +1894,7 @@ gen_intermediate_code_internal(CPUMBState *env, TranslationBlock *tb,
break;
}
}
- gen_icount_end(tb, num_insns);
+ gen_tb_end(tb, num_insns);
*tcg_ctx.gen_opc_ptr = INDEX_op_end;
if (search_pc) {
j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
diff --git a/target-mips/cpu-qom.h b/target-mips/cpu-qom.h
index 55aa692a85..c6bcddfb9a 100644
--- a/target-mips/cpu-qom.h
+++ b/target-mips/cpu-qom.h
@@ -72,5 +72,6 @@ static inline MIPSCPU *mips_env_get_cpu(CPUMIPSState *env)
#define ENV_GET_CPU(e) CPU(mips_env_get_cpu(e))
+#define ENV_OFFSET offsetof(MIPSCPU, env)
#endif
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 0e198b12db..ca63148b18 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -504,6 +504,9 @@ void mips_cpu_list (FILE *f, fprintf_function cpu_fprintf);
#define cpu_signal_handler cpu_mips_signal_handler
#define cpu_list mips_cpu_list
+extern void cpu_wrdsp(uint32_t rs, uint32_t mask_num, CPUMIPSState *env);
+extern uint32_t cpu_rddsp(uint32_t mask_num, CPUMIPSState *env);
+
#define CPU_SAVE_VERSION 3
/* MMU modes definitions. We carefully match the indices with our
diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
index 841f47b91d..472be35bbf 100644
--- a/target-mips/dsp_helper.c
+++ b/target-mips/dsp_helper.c
@@ -44,7 +44,8 @@ typedef union {
/*** MIPS DSP internal functions begin ***/
#define MIPSDSP_ABS(x) (((x) >= 0) ? x : -x)
-#define MIPSDSP_OVERFLOW(a, b, c, d) (!(!((a ^ b ^ -1) & (a ^ c) & d)))
+#define MIPSDSP_OVERFLOW_ADD(a, b, c, d) (~(a ^ b) & (a ^ c) & d)
+#define MIPSDSP_OVERFLOW_SUB(a, b, c, d) ((a ^ b) & (a ^ c) & d)
static inline void set_DSPControl_overflow_flag(uint32_t flag, int position,
CPUMIPSState *env)
@@ -142,7 +143,7 @@ static inline int16_t mipsdsp_add_i16(int16_t a, int16_t b, CPUMIPSState *env)
tempI = a + b;
- if (MIPSDSP_OVERFLOW(a, b, tempI, 0x8000)) {
+ if (MIPSDSP_OVERFLOW_ADD(a, b, tempI, 0x8000)) {
set_DSPControl_overflow_flag(1, 20, env);
}
@@ -156,7 +157,7 @@ static inline int16_t mipsdsp_sat_add_i16(int16_t a, int16_t b,
tempS = a + b;
- if (MIPSDSP_OVERFLOW(a, b, tempS, 0x8000)) {
+ if (MIPSDSP_OVERFLOW_ADD(a, b, tempS, 0x8000)) {
if (a > 0) {
tempS = 0x7FFF;
} else {
@@ -175,7 +176,7 @@ static inline int32_t mipsdsp_sat_add_i32(int32_t a, int32_t b,
tempI = a + b;
- if (MIPSDSP_OVERFLOW(a, b, tempI, 0x80000000)) {
+ if (MIPSDSP_OVERFLOW_ADD(a, b, tempI, 0x80000000)) {
if (a > 0) {
tempI = 0x7FFFFFFF;
} else {
@@ -858,7 +859,7 @@ static inline uint16_t mipsdsp_sub_i16(int16_t a, int16_t b, CPUMIPSState *env)
int16_t temp;
temp = a - b;
- if (MIPSDSP_OVERFLOW(a, -b, temp, 0x8000)) {
+ if (MIPSDSP_OVERFLOW_SUB(a, b, temp, 0x8000)) {
set_DSPControl_overflow_flag(1, 20, env);
}
@@ -871,8 +872,8 @@ static inline uint16_t mipsdsp_sat16_sub(int16_t a, int16_t b,
int16_t temp;
temp = a - b;
- if (MIPSDSP_OVERFLOW(a, -b, temp, 0x8000)) {
- if (a > 0) {
+ if (MIPSDSP_OVERFLOW_SUB(a, b, temp, 0x8000)) {
+ if (a >= 0) {
temp = 0x7FFF;
} else {
temp = 0x8000;
@@ -889,8 +890,8 @@ static inline uint32_t mipsdsp_sat32_sub(int32_t a, int32_t b,
int32_t temp;
temp = a - b;
- if (MIPSDSP_OVERFLOW(a, -b, temp, 0x80000000)) {
- if (a > 0) {
+ if (MIPSDSP_OVERFLOW_SUB(a, b, temp, 0x80000000)) {
+ if (a >= 0) {
temp = 0x7FFFFFFF;
} else {
temp = 0x80000000;
@@ -1004,7 +1005,7 @@ static inline uint32_t mipsdsp_sub32(int32_t a, int32_t b, CPUMIPSState *env)
int32_t temp;
temp = a - b;
- if (MIPSDSP_OVERFLOW(a, -b, temp, 0x80000000)) {
+ if (MIPSDSP_OVERFLOW_SUB(a, b, temp, 0x80000000)) {
set_DSPControl_overflow_flag(1, 20, env);
}
@@ -1017,7 +1018,7 @@ static inline int32_t mipsdsp_add_i32(int32_t a, int32_t b, CPUMIPSState *env)
temp = a + b;
- if (MIPSDSP_OVERFLOW(a, b, temp, 0x80000000)) {
+ if (MIPSDSP_OVERFLOW_ADD(a, b, temp, 0x80000000)) {
set_DSPControl_overflow_flag(1, 20, env);
}
@@ -2488,37 +2489,42 @@ DP_QH(dpsq_s_w_qh, 0, 1);
#endif
#define DP_L_W(name, is_add) \
-void helper_##name(uint32_t ac, target_ulong rs, target_ulong rt, \
- CPUMIPSState *env) \
-{ \
- int32_t temp63; \
- int64_t dotp, acc; \
- uint64_t temp; \
- \
- dotp = mipsdsp_mul_q31_q31(ac, rs, rt, env); \
- acc = ((uint64_t)env->active_tc.HI[ac] << 32) | \
- ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO); \
- if (!is_add) { \
- dotp = -dotp; \
- } \
- \
- temp = acc + dotp; \
- if (MIPSDSP_OVERFLOW((uint64_t)acc, (uint64_t)dotp, temp, \
- (0x01ull << 63))) { \
- temp63 = (temp >> 63) & 0x01; \
- if (temp63 == 1) { \
- temp = (0x01ull << 63) - 1; \
- } else { \
- temp = 0x01ull << 63; \
- } \
- \
- set_DSPControl_overflow_flag(1, 16 + ac, env); \
- } \
- \
- env->active_tc.HI[ac] = (target_long)(int32_t) \
- ((temp & MIPSDSP_LHI) >> 32); \
- env->active_tc.LO[ac] = (target_long)(int32_t) \
- (temp & MIPSDSP_LLO); \
+void helper_##name(uint32_t ac, target_ulong rs, target_ulong rt, \
+ CPUMIPSState *env) \
+{ \
+ int32_t temp63; \
+ int64_t dotp, acc; \
+ uint64_t temp; \
+ bool overflow; \
+ \
+ dotp = mipsdsp_mul_q31_q31(ac, rs, rt, env); \
+ acc = ((uint64_t)env->active_tc.HI[ac] << 32) | \
+ ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO); \
+ if (is_add) { \
+ temp = acc + dotp; \
+ overflow = MIPSDSP_OVERFLOW_ADD((uint64_t)acc, (uint64_t)dotp, \
+ temp, (0x01ull << 63)); \
+ } else { \
+ temp = acc - dotp; \
+ overflow = MIPSDSP_OVERFLOW_SUB((uint64_t)acc, (uint64_t)dotp, \
+ temp, (0x01ull << 63)); \
+ } \
+ \
+ if (overflow) { \
+ temp63 = (temp >> 63) & 0x01; \
+ if (temp63 == 1) { \
+ temp = (0x01ull << 63) - 1; \
+ } else { \
+ temp = 0x01ull << 63; \
+ } \
+ \
+ set_DSPControl_overflow_flag(1, 16 + ac, env); \
+ } \
+ \
+ env->active_tc.HI[ac] = (target_long)(int32_t) \
+ ((temp & MIPSDSP_LHI) >> 32); \
+ env->active_tc.LO[ac] = (target_long)(int32_t) \
+ (temp & MIPSDSP_LLO); \
}
DP_L_W(dpaq_sa_l_w, 1);
@@ -3637,7 +3643,7 @@ void helper_dmthlip(target_ulong rs, target_ulong ac, CPUMIPSState *env)
}
#endif
-void helper_wrdsp(target_ulong rs, target_ulong mask_num, CPUMIPSState *env)
+void cpu_wrdsp(uint32_t rs, uint32_t mask_num, CPUMIPSState *env)
{
uint8_t mask[6];
uint8_t i;
@@ -3703,7 +3709,12 @@ void helper_wrdsp(target_ulong rs, target_ulong mask_num, CPUMIPSState *env)
env->active_tc.DSPControl = dsp;
}
-target_ulong helper_rddsp(target_ulong masknum, CPUMIPSState *env)
+void helper_wrdsp(target_ulong rs, target_ulong mask_num, CPUMIPSState *env)
+{
+ return cpu_wrdsp(rs, mask_num, env);
+}
+
+uint32_t cpu_rddsp(uint32_t mask_num, CPUMIPSState *env)
{
uint8_t mask[6];
uint32_t ruler, i;
@@ -3712,7 +3723,7 @@ target_ulong helper_rddsp(target_ulong masknum, CPUMIPSState *env)
ruler = 0x01;
for (i = 0; i < 6; i++) {
- mask[i] = (masknum & ruler) >> i ;
+ mask[i] = (mask_num & ruler) >> i ;
ruler = ruler << 1;
}
@@ -3754,6 +3765,11 @@ target_ulong helper_rddsp(target_ulong masknum, CPUMIPSState *env)
return temp;
}
+target_ulong helper_rddsp(target_ulong mask_num, CPUMIPSState *env)
+{
+ return cpu_rddsp(mask_num, env);
+}
+
#undef MIPSDSP_LHI
#undef MIPSDSP_LLO
diff --git a/target-mips/translate.c b/target-mips/translate.c
index f10a533e80..694f07c49f 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -2582,10 +2582,9 @@ static void gen_shift(DisasContext *ctx, uint32_t opc,
}
/* Arithmetic on HI/LO registers */
-static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
+static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
{
const char *opn = "hilo";
- unsigned int acc;
if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
/* Treat as NOP. */
@@ -2593,12 +2592,6 @@ static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
return;
}
- if (opc == OPC_MFHI || opc == OPC_MFLO) {
- acc = ((ctx->opcode) >> 21) & 0x03;
- } else {
- acc = ((ctx->opcode) >> 11) & 0x03;
- }
-
if (acc != 0) {
check_dsp(ctx);
}
@@ -2661,12 +2654,11 @@ static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
MIPS_DEBUG("%s %s", opn, regnames[reg]);
}
-static void gen_muldiv (DisasContext *ctx, uint32_t opc,
- int rs, int rt)
+static void gen_muldiv(DisasContext *ctx, uint32_t opc,
+ int acc, int rs, int rt)
{
const char *opn = "mul/div";
TCGv t0, t1;
- unsigned int acc;
t0 = tcg_temp_new();
t1 = tcg_temp_new();
@@ -2674,6 +2666,10 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
gen_load_gpr(t0, rs);
gen_load_gpr(t1, rt);
+ if (acc != 0) {
+ check_dsp(ctx);
+ }
+
switch (opc) {
case OPC_DIV:
{
@@ -2688,10 +2684,10 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
tcg_gen_or_tl(t2, t2, t3);
tcg_gen_movi_tl(t3, 0);
tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
- tcg_gen_div_tl(cpu_LO[0], t0, t1);
- tcg_gen_rem_tl(cpu_HI[0], t0, t1);
- tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
- tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
+ tcg_gen_div_tl(cpu_LO[acc], t0, t1);
+ tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
+ tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
+ tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
tcg_temp_free(t3);
tcg_temp_free(t2);
}
@@ -2704,10 +2700,10 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
tcg_gen_ext32u_tl(t0, t0);
tcg_gen_ext32u_tl(t1, t1);
tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
- tcg_gen_divu_tl(cpu_LO[0], t0, t1);
- tcg_gen_remu_tl(cpu_HI[0], t0, t1);
- tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
- tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
+ tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
+ tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
+ tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
+ tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
tcg_temp_free(t3);
tcg_temp_free(t2);
}
@@ -2717,11 +2713,6 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
{
TCGv_i32 t2 = tcg_temp_new_i32();
TCGv_i32 t3 = tcg_temp_new_i32();
- acc = ((ctx->opcode) >> 11) & 0x03;
- if (acc != 0) {
- check_dsp(ctx);
- }
-
tcg_gen_trunc_tl_i32(t2, t0);
tcg_gen_trunc_tl_i32(t3, t1);
tcg_gen_muls2_i32(t2, t3, t2, t3);
@@ -2736,11 +2727,6 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
{
TCGv_i32 t2 = tcg_temp_new_i32();
TCGv_i32 t3 = tcg_temp_new_i32();
- acc = ((ctx->opcode) >> 11) & 0x03;
- if (acc != 0) {
- check_dsp(ctx);
- }
-
tcg_gen_trunc_tl_i32(t2, t0);
tcg_gen_trunc_tl_i32(t3, t1);
tcg_gen_mulu2_i32(t2, t3, t2, t3);
@@ -2763,8 +2749,8 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
tcg_gen_or_tl(t2, t2, t3);
tcg_gen_movi_tl(t3, 0);
tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
- tcg_gen_div_tl(cpu_LO[0], t0, t1);
- tcg_gen_rem_tl(cpu_HI[0], t0, t1);
+ tcg_gen_div_tl(cpu_LO[acc], t0, t1);
+ tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
tcg_temp_free(t3);
tcg_temp_free(t2);
}
@@ -2775,19 +2761,19 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
TCGv t2 = tcg_const_tl(0);
TCGv t3 = tcg_const_tl(1);
tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
- tcg_gen_divu_i64(cpu_LO[0], t0, t1);
- tcg_gen_remu_i64(cpu_HI[0], t0, t1);
+ tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
+ tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
tcg_temp_free(t3);
tcg_temp_free(t2);
}
opn = "ddivu";
break;
case OPC_DMULT:
- tcg_gen_muls2_i64(cpu_LO[0], cpu_HI[0], t0, t1);
+ tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
opn = "dmult";
break;
case OPC_DMULTU:
- tcg_gen_mulu2_i64(cpu_LO[0], cpu_HI[0], t0, t1);
+ tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
opn = "dmultu";
break;
#endif
@@ -2795,10 +2781,6 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
{
TCGv_i64 t2 = tcg_temp_new_i64();
TCGv_i64 t3 = tcg_temp_new_i64();
- acc = ((ctx->opcode) >> 11) & 0x03;
- if (acc != 0) {
- check_dsp(ctx);
- }
tcg_gen_ext_tl_i64(t2, t0);
tcg_gen_ext_tl_i64(t3, t1);
@@ -2819,10 +2801,6 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
{
TCGv_i64 t2 = tcg_temp_new_i64();
TCGv_i64 t3 = tcg_temp_new_i64();
- acc = ((ctx->opcode) >> 11) & 0x03;
- if (acc != 0) {
- check_dsp(ctx);
- }
tcg_gen_ext32u_tl(t0, t0);
tcg_gen_ext32u_tl(t1, t1);
@@ -2845,10 +2823,6 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
{
TCGv_i64 t2 = tcg_temp_new_i64();
TCGv_i64 t3 = tcg_temp_new_i64();
- acc = ((ctx->opcode) >> 11) & 0x03;
- if (acc != 0) {
- check_dsp(ctx);
- }
tcg_gen_ext_tl_i64(t2, t0);
tcg_gen_ext_tl_i64(t3, t1);
@@ -2869,10 +2843,6 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
{
TCGv_i64 t2 = tcg_temp_new_i64();
TCGv_i64 t3 = tcg_temp_new_i64();
- acc = ((ctx->opcode) >> 11) & 0x03;
- if (acc != 0) {
- check_dsp(ctx);
- }
tcg_gen_ext32u_tl(t0, t0);
tcg_gen_ext32u_tl(t1, t1);
@@ -10135,7 +10105,7 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
gen_logic(ctx, OPC_NOR, rx, ry, 0);
break;
case RR_MFHI:
- gen_HILO(ctx, OPC_MFHI, rx);
+ gen_HILO(ctx, OPC_MFHI, 0, rx);
break;
case RR_CNVT:
switch (cnvt_op) {
@@ -10167,7 +10137,7 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
}
break;
case RR_MFLO:
- gen_HILO(ctx, OPC_MFLO, rx);
+ gen_HILO(ctx, OPC_MFLO, 0, rx);
break;
#if defined (TARGET_MIPS64)
case RR_DSRA:
@@ -10188,33 +10158,33 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
break;
#endif
case RR_MULT:
- gen_muldiv(ctx, OPC_MULT, rx, ry);
+ gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
break;
case RR_MULTU:
- gen_muldiv(ctx, OPC_MULTU, rx, ry);
+ gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
break;
case RR_DIV:
- gen_muldiv(ctx, OPC_DIV, rx, ry);
+ gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
break;
case RR_DIVU:
- gen_muldiv(ctx, OPC_DIVU, rx, ry);
+ gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
break;
#if defined (TARGET_MIPS64)
case RR_DMULT:
check_mips_64(ctx);
- gen_muldiv(ctx, OPC_DMULT, rx, ry);
+ gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
break;
case RR_DMULTU:
check_mips_64(ctx);
- gen_muldiv(ctx, OPC_DMULTU, rx, ry);
+ gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
break;
case RR_DDIV:
check_mips_64(ctx);
- gen_muldiv(ctx, OPC_DDIV, rx, ry);
+ gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
break;
case RR_DDIVU:
check_mips_64(ctx);
- gen_muldiv(ctx, OPC_DDIVU, rx, ry);
+ gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
break;
#endif
default:
@@ -10923,11 +10893,11 @@ static void gen_pool16c_insn(DisasContext *ctx, int *is_branch)
break;
case MFHI16 + 0:
case MFHI16 + 1:
- gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
+ gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
break;
case MFLO16 + 0:
case MFLO16 + 1:
- gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
+ gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
break;
case BREAK16:
generate_exception(ctx, EXCP_BREAK);
@@ -11125,30 +11095,34 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
break;
case MULT:
mips32_op = OPC_MULT;
- goto do_muldiv;
+ goto do_mul;
case MULTU:
mips32_op = OPC_MULTU;
- goto do_muldiv;
+ goto do_mul;
case DIV:
mips32_op = OPC_DIV;
- goto do_muldiv;
+ goto do_div;
case DIVU:
mips32_op = OPC_DIVU;
- goto do_muldiv;
+ goto do_div;
+ do_div:
+ check_insn(ctx, ISA_MIPS32);
+ gen_muldiv(ctx, mips32_op, 0, rs, rt);
+ break;
case MADD:
mips32_op = OPC_MADD;
- goto do_muldiv;
+ goto do_mul;
case MADDU:
mips32_op = OPC_MADDU;
- goto do_muldiv;
+ goto do_mul;
case MSUB:
mips32_op = OPC_MSUB;
- goto do_muldiv;
+ goto do_mul;
case MSUBU:
mips32_op = OPC_MSUBU;
- do_muldiv:
+ do_mul:
check_insn(ctx, ISA_MIPS32);
- gen_muldiv(ctx, mips32_op, rs, rt);
+ gen_muldiv(ctx, mips32_op, (ctx->opcode >> 14) & 3, rs, rt);
break;
default:
goto pool32axf_invalid;
@@ -11285,18 +11259,18 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
}
break;
case 0x35:
- switch (minor) {
+ switch (minor & 3) {
case MFHI32:
- gen_HILO(ctx, OPC_MFHI, rs);
+ gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
break;
case MFLO32:
- gen_HILO(ctx, OPC_MFLO, rs);
+ gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
break;
case MTHI32:
- gen_HILO(ctx, OPC_MTHI, rs);
+ gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
break;
case MTLO32:
- gen_HILO(ctx, OPC_MTLO, rs);
+ gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
break;
default:
goto pool32axf_invalid;
@@ -14469,13 +14443,19 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
case OPC_XOR:
gen_logic(ctx, op1, rd, rs, rt);
break;
- case OPC_MULT ... OPC_DIVU:
+ case OPC_MULT:
+ case OPC_MULTU:
if (sa) {
check_insn(ctx, INSN_VR54XX);
op1 = MASK_MUL_VR54XX(ctx->opcode);
gen_mul_vr54xx(ctx, op1, rd, rs, rt);
- } else
- gen_muldiv(ctx, op1, rs, rt);
+ } else {
+ gen_muldiv(ctx, op1, rd & 3, rs, rt);
+ }
+ break;
+ case OPC_DIV:
+ case OPC_DIVU:
+ gen_muldiv(ctx, op1, 0, rs, rt);
break;
case OPC_JR ... OPC_JALR:
gen_compute_branch(ctx, op1, 4, rs, rd, sa);
@@ -14487,11 +14467,11 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
break;
case OPC_MFHI: /* Move from HI/LO */
case OPC_MFLO:
- gen_HILO(ctx, op1, rd);
+ gen_HILO(ctx, op1, rs & 3, rd);
break;
case OPC_MTHI:
case OPC_MTLO: /* Move to HI/LO */
- gen_HILO(ctx, op1, rs);
+ gen_HILO(ctx, op1, rd & 3, rs);
break;
case OPC_PMON: /* Pmon entry point, also R4010 selsl */
#ifdef MIPS_STRICT_STANDARD
@@ -14611,7 +14591,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
case OPC_DMULT ... OPC_DDIVU:
check_insn(ctx, ISA_MIPS3);
check_mips_64(ctx);
- gen_muldiv(ctx, op1, rs, rt);
+ gen_muldiv(ctx, op1, 0, rs, rt);
break;
#endif
default: /* Invalid */
@@ -14626,7 +14606,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
case OPC_MSUB ... OPC_MSUBU:
check_insn(ctx, ISA_MIPS32);
- gen_muldiv(ctx, op1, rs, rt);
+ gen_muldiv(ctx, op1, rd & 3, rs, rt);
break;
case OPC_MUL:
gen_arith(ctx, op1, rd, rs, rt);
@@ -15596,7 +15576,7 @@ gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
if (max_insns == 0)
max_insns = CF_COUNT_MASK;
LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
- gen_icount_start();
+ gen_tb_start();
while (ctx.bstate == BS_NONE) {
if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
@@ -15694,7 +15674,7 @@ gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
}
}
done_generating:
- gen_icount_end(tb, num_insns);
+ gen_tb_end(tb, num_insns);
*tcg_ctx.gen_opc_ptr = INDEX_op_end;
if (search_pc) {
j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
@@ -15964,6 +15944,14 @@ void cpu_state_reset(CPUMIPSState *env)
#if defined(CONFIG_USER_ONLY)
env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
+# ifdef TARGET_MIPS64
+ /* Enable 64-bit register mode. */
+ env->CP0_Status |= (1 << CP0St_PX);
+# endif
+# ifdef TARGET_ABI_MIPSN64
+ /* Enable 64-bit address mode. */
+ env->CP0_Status |= (1 << CP0St_UX);
+# endif
/* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
hardware registers. */
env->CP0_HWREna |= 0x0000000F;
@@ -15973,6 +15961,10 @@ void cpu_state_reset(CPUMIPSState *env)
if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
env->CP0_Status |= (1 << CP0St_MX);
}
+ /* Enable 64-bit FPU if the target cpu supports it. */
+ if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
+ env->CP0_Status |= (1 << CP0St_FR);
+ }
#else
if (env->hflags & MIPS_HFLAG_BMASK) {
/* If the exception was raised from a delay slot,
diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
index 419f007991..4cfd1c74fb 100644
--- a/target-openrisc/cpu.h
+++ b/target-openrisc/cpu.h
@@ -340,6 +340,8 @@ static inline OpenRISCCPU *openrisc_env_get_cpu(CPUOpenRISCState *env)
#define ENV_GET_CPU(e) CPU(openrisc_env_get_cpu(e))
+#define ENV_OFFSET offsetof(OpenRISCCPU, env)
+
OpenRISCCPU *cpu_openrisc_init(const char *cpu_model);
void cpu_openrisc_list(FILE *f, fprintf_function cpu_fprintf);
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index 23e853e488..0eafd0296c 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -1696,7 +1696,7 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,
max_insns = CF_COUNT_MASK;
}
- gen_icount_start();
+ gen_tb_start();
do {
check_breakpoint(cpu, dc);
@@ -1779,7 +1779,7 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,
}
}
- gen_icount_end(tb, num_insns);
+ gen_tb_end(tb, num_insns);
*tcg_ctx.gen_opc_ptr = INDEX_op_end;
if (search_pc) {
j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h
index 2b82cdbe40..4e8ceca574 100644
--- a/target-ppc/cpu-qom.h
+++ b/target-ppc/cpu-qom.h
@@ -78,7 +78,8 @@ static inline PowerPCCPU *ppc_env_get_cpu(CPUPPCState *env)
#define ENV_GET_CPU(e) CPU(ppc_env_get_cpu(e))
-PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr);
+#define ENV_OFFSET offsetof(PowerPCCPU, env)
+PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr);
#endif
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 80d5366d27..fa9e9e3857 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -9557,7 +9557,7 @@ static inline void gen_intermediate_code_internal(CPUPPCState *env,
if (max_insns == 0)
max_insns = CF_COUNT_MASK;
- gen_icount_start();
+ gen_tb_start();
/* Set env in case of segfault during code fetch */
while (ctx.exception == POWERPC_EXCP_NONE
&& tcg_ctx.gen_opc_ptr < gen_opc_end) {
@@ -9669,7 +9669,7 @@ static inline void gen_intermediate_code_internal(CPUPPCState *env,
/* Generate the return instruction */
tcg_gen_exit_tb(0);
}
- gen_icount_end(tb, num_insns);
+ gen_tb_end(tb, num_insns);
*tcg_ctx.gen_opc_ptr = INDEX_op_end;
if (unlikely(search_pc)) {
j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
diff --git a/target-s390x/cpu-qom.h b/target-s390x/cpu-qom.h
index 237184f55a..f6e514570c 100644
--- a/target-s390x/cpu-qom.h
+++ b/target-s390x/cpu-qom.h
@@ -69,5 +69,6 @@ static inline S390CPU *s390_env_get_cpu(CPUS390XState *env)
#define ENV_GET_CPU(e) CPU(s390_env_get_cpu(e))
+#define ENV_OFFSET offsetof(S390CPU, env)
#endif
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index bdf69a3c7c..88e481cdbc 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -4769,7 +4769,7 @@ static inline void gen_intermediate_code_internal(CPUS390XState *env,
max_insns = CF_COUNT_MASK;
}
- gen_icount_start();
+ gen_tb_start();
do {
if (search_pc) {
@@ -4845,7 +4845,7 @@ static inline void gen_intermediate_code_internal(CPUS390XState *env,
abort();
}
- gen_icount_end(tb, num_insns);
+ gen_tb_end(tb, num_insns);
*tcg_ctx.gen_opc_ptr = INDEX_op_end;
if (search_pc) {
j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
diff --git a/target-sh4/cpu-qom.h b/target-sh4/cpu-qom.h
index d368db1b0a..f4e8976478 100644
--- a/target-sh4/cpu-qom.h
+++ b/target-sh4/cpu-qom.h
@@ -68,5 +68,6 @@ static inline SuperHCPU *sh_env_get_cpu(CPUSH4State *env)
#define ENV_GET_CPU(e) CPU(sh_env_get_cpu(e))
+#define ENV_OFFSET offsetof(SuperHCPU, env)
#endif
diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index d255066e0a..7f300e3444 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -1959,7 +1959,7 @@ gen_intermediate_code_internal(CPUSH4State * env, TranslationBlock * tb,
max_insns = tb->cflags & CF_COUNT_MASK;
if (max_insns == 0)
max_insns = CF_COUNT_MASK;
- gen_icount_start();
+ gen_tb_start();
while (ctx.bstate == BS_NONE && tcg_ctx.gen_opc_ptr < gen_opc_end) {
if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
@@ -2029,7 +2029,7 @@ gen_intermediate_code_internal(CPUSH4State * env, TranslationBlock * tb,
}
}
- gen_icount_end(tb, num_insns);
+ gen_tb_end(tb, num_insns);
*tcg_ctx.gen_opc_ptr = INDEX_op_end;
if (search_pc) {
i = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
diff --git a/target-sparc/cpu-qom.h b/target-sparc/cpu-qom.h
index 89cd1cf2d3..efeeca0d97 100644
--- a/target-sparc/cpu-qom.h
+++ b/target-sparc/cpu-qom.h
@@ -73,5 +73,6 @@ static inline SPARCCPU *sparc_env_get_cpu(CPUSPARCState *env)
#define ENV_GET_CPU(e) CPU(sparc_env_get_cpu(e))
+#define ENV_OFFSET offsetof(SPARCCPU, env)
#endif
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 12276d5608..eb6e800977 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -5249,7 +5249,7 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb,
max_insns = tb->cflags & CF_COUNT_MASK;
if (max_insns == 0)
max_insns = CF_COUNT_MASK;
- gen_icount_start();
+ gen_tb_start();
do {
if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
@@ -5319,7 +5319,7 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb,
tcg_gen_exit_tb(0);
}
}
- gen_icount_end(tb, num_insns);
+ gen_tb_end(tb, num_insns);
*tcg_ctx.gen_opc_ptr = INDEX_op_end;
if (spc) {
j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
diff --git a/target-unicore32/cpu-qom.h b/target-unicore32/cpu-qom.h
index 625c6143db..c6590bdf01 100644
--- a/target-unicore32/cpu-qom.h
+++ b/target-unicore32/cpu-qom.h
@@ -58,5 +58,6 @@ static inline UniCore32CPU *uc32_env_get_cpu(CPUUniCore32State *env)
#define ENV_GET_CPU(e) CPU(uc32_env_get_cpu(e))
+#define ENV_OFFSET offsetof(UniCore32CPU, env)
#endif
diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c
index d5039e2093..151e35e6bb 100644
--- a/target-unicore32/translate.c
+++ b/target-unicore32/translate.c
@@ -1921,7 +1921,7 @@ static inline void gen_intermediate_code_internal(CPUUniCore32State *env,
}
#endif
- gen_icount_start();
+ gen_tb_start();
do {
if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
@@ -2041,7 +2041,7 @@ static inline void gen_intermediate_code_internal(CPUUniCore32State *env,
}
done_generating:
- gen_icount_end(tb, num_insns);
+ gen_tb_end(tb, num_insns);
*tcg_ctx.gen_opc_ptr = INDEX_op_end;
#ifdef DEBUG_DISAS
diff --git a/target-xtensa/cpu-qom.h b/target-xtensa/cpu-qom.h
index 270de16583..c78136bf72 100644
--- a/target-xtensa/cpu-qom.h
+++ b/target-xtensa/cpu-qom.h
@@ -78,5 +78,6 @@ static inline XtensaCPU *xtensa_env_get_cpu(const CPUXtensaState *env)
#define ENV_GET_CPU(e) CPU(xtensa_env_get_cpu(e))
+#define ENV_OFFSET offsetof(XtensaCPU, env)
#endif
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index 11e06a34f5..06d68dbaeb 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -2913,7 +2913,7 @@ static void gen_intermediate_code_internal(
dc.next_icount = tcg_temp_local_new_i32();
}
- gen_icount_start();
+ gen_tb_start();
if (env->singlestep_enabled && env->exception_taken) {
env->exception_taken = 0;
@@ -2991,7 +2991,7 @@ static void gen_intermediate_code_internal(
if (dc.is_jmp == DISAS_NEXT) {
gen_jumpi(&dc, dc.pc, 0);
}
- gen_icount_end(tb, insn_count);
+ gen_tb_end(tb, insn_count);
*tcg_ctx.gen_opc_ptr = INDEX_op_end;
if (search_pc) {
diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index 6d489fcc52..025af9b379 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -776,6 +776,7 @@ static void tcg_out_setcond2_i32(TCGContext *s, TCGCond cond, TCGArg ret,
break;
}
}
+#endif
static void tcg_out_addsub2(TCGContext *s, TCGArg rl, TCGArg rh,
TCGArg al, TCGArg ah, TCGArg bl, int blconst,
@@ -792,7 +793,6 @@ static void tcg_out_addsub2(TCGContext *s, TCGArg rl, TCGArg rh,
tcg_out_arithc(s, rh, ah, bh, bhconst, oph);
tcg_out_mov(s, TCG_TYPE_I32, rl, tmp);
}
-#endif
/* Generate global QEMU prologue and epilogue code */
static void tcg_target_qemu_prologue(TCGContext *s)
diff --git a/tcg/tcg.h b/tcg/tcg.h
index b195396b0f..df375cf31e 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -677,7 +677,54 @@ TCGv_i64 tcg_const_i64(int64_t val);
TCGv_i32 tcg_const_local_i32(int32_t val);
TCGv_i64 tcg_const_local_i64(int64_t val);
-/* TCG targets may use a different definition of tcg_qemu_tb_exec. */
+/**
+ * tcg_qemu_tb_exec:
+ * @env: CPUArchState * for the CPU
+ * @tb_ptr: address of generated code for the TB to execute
+ *
+ * Start executing code from a given translation block.
+ * Where translation blocks have been linked, execution
+ * may proceed from the given TB into successive ones.
+ * Control eventually returns only when some action is needed
+ * from the top-level loop: either control must pass to a TB
+ * which has not yet been directly linked, or an asynchronous
+ * event such as an interrupt needs handling.
+ *
+ * The return value is a pointer to the next TB to execute
+ * (if known; otherwise zero). This pointer is assumed to be
+ * 4-aligned, and the bottom two bits are used to return further
+ * information:
+ * 0, 1: the link between this TB and the next is via the specified
+ * TB index (0 or 1). That is, we left the TB via (the equivalent
+ * of) "goto_tb <index>". The main loop uses this to determine
+ * how to link the TB just executed to the next.
+ * 2: we are using instruction counting code generation, and we
+ * did not start executing this TB because the instruction counter
+ * would hit zero midway through it. In this case the next-TB pointer
+ * returned is the TB we were about to execute, and the caller must
+ * arrange to execute the remaining count of instructions.
+ * 3: we stopped because the CPU's exit_request flag was set
+ * (usually meaning that there is an interrupt that needs to be
+ * handled). The next-TB pointer returned is the TB we were
+ * about to execute when we noticed the pending exit request.
+ *
+ * If the bottom two bits indicate an exit-via-index then the CPU
+ * state is correctly synchronised and ready for execution of the next
+ * TB (and in particular the guest PC is the address to execute next).
+ * Otherwise, we gave up on execution of this TB before it started, and
+ * the caller must fix up the CPU state by calling cpu_pc_from_tb()
+ * with the next-TB pointer we return.
+ *
+ * Note that TCG targets may use a different definition of tcg_qemu_tb_exec
+ * to this default (which just calls the prologue.code emitted by
+ * tcg_target_qemu_prologue()).
+ */
+#define TB_EXIT_MASK 3
+#define TB_EXIT_IDX0 0
+#define TB_EXIT_IDX1 1
+#define TB_EXIT_ICOUNT_EXPIRED 2
+#define TB_EXIT_REQUESTED 3
+
#if !defined(tcg_qemu_tb_exec)
# define tcg_qemu_tb_exec(env, tb_ptr) \
((tcg_target_ulong (*)(void *, void *))tcg_ctx.code_gen_prologue)(env, \
diff --git a/tests/rtc-test.c b/tests/rtc-test.c
index c5fd042610..9ab583b860 100644
--- a/tests/rtc-test.c
+++ b/tests/rtc-test.c
@@ -565,8 +565,8 @@ int main(int argc, char **argv)
qtest_add_func("/rtc/basic/bcd-12h", basic_12h_bcd);
qtest_add_func("/rtc/set-year/20xx", set_year_20xx);
qtest_add_func("/rtc/set-year/1980", set_year_1980);
- qtest_add_func("/rtc/register_b_set_flag", register_b_set_flag);
- qtest_add_func("/rtc/fuzz-registers", fuzz_registers);
+ qtest_add_func("/rtc/misc/register_b_set_flag", register_b_set_flag);
+ qtest_add_func("/rtc/misc/fuzz-registers", fuzz_registers);
ret = g_test_run();
if (s) {
diff --git a/tests/tcg/mips/mips32-dsp/subq_s_ph.c b/tests/tcg/mips/mips32-dsp/subq_s_ph.c
index 8e36dadef9..64c89ebd51 100644
--- a/tests/tcg/mips/mips32-dsp/subq_s_ph.c
+++ b/tests/tcg/mips/mips32-dsp/subq_s_ph.c
@@ -12,7 +12,8 @@ int main()
resultdsp = 0x01;
__asm
- ("subq_s.ph %0, %2, %3\n\t"
+ ("wrdsp $0\n\t"
+ "subq_s.ph %0, %2, %3\n\t"
"rddsp %1\n\t"
: "=r"(rd), "=r"(dsp)
: "r"(rs), "r"(rt)
@@ -27,7 +28,24 @@ int main()
resultdsp = 0x01;
__asm
- ("subq_s.ph %0, %2, %3\n\t"
+ ("wrdsp $0\n\t"
+ "subq_s.ph %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rs), "r"(rt)
+ );
+ dsp = (dsp >> 20) & 0x01;
+ assert(dsp == resultdsp);
+ assert(rd == result);
+
+ rs = 0x12340000;
+ rt = 0x87658000;
+ result = 0x7FFF7FFF;
+ resultdsp = 0x01;
+
+ __asm
+ ("wrdsp $0\n\t"
+ "subq_s.ph %0, %2, %3\n\t"
"rddsp %1\n\t"
: "=r"(rd), "=r"(dsp)
: "r"(rs), "r"(rt)
diff --git a/tests/tcg/mips/mips32-dsp/subq_s_w.c b/tests/tcg/mips/mips32-dsp/subq_s_w.c
index 09022e9c85..9d456a90f4 100644
--- a/tests/tcg/mips/mips32-dsp/subq_s_w.c
+++ b/tests/tcg/mips/mips32-dsp/subq_s_w.c
@@ -12,7 +12,8 @@ int main()
resultdsp = 0x01;
__asm
- ("subq_s.w %0, %2, %3\n\t"
+ ("wrdsp $0\n\t"
+ "subq_s.w %0, %2, %3\n\t"
"rddsp %1\n\t"
: "=r"(rd), "=r"(dsp)
: "r"(rs), "r"(rt)
@@ -24,10 +25,11 @@ int main()
rs = 0x66666;
rt = 0x55555;
result = 0x11111;
- resultdsp = 0x01;
+ resultdsp = 0x0;
__asm
- ("subq_s.w %0, %2, %3\n\t"
+ ("wrdsp $0\n\t"
+ "subq_s.w %0, %2, %3\n\t"
"rddsp %1\n\t"
: "=r"(rd), "=r"(dsp)
: "r"(rs), "r"(rt)
@@ -36,23 +38,37 @@ int main()
assert(dsp == resultdsp);
assert(rd == result);
-
-#if 0
- rs = 0x35555555;
- rt = 0xf5555555;
- result = 0x80000000;
+ rs = 0x0;
+ rt = 0x80000000;
+ result = 0x7FFFFFFF;
resultdsp = 0x01;
__asm
- ("subq_s.w %0, %2, %3\n\t"
+ ("wrdsp $0\n\t"
+ "subq_s.w %0, %2, %3\n\t"
"rddsp %1\n\t"
: "=r"(rd), "=r"(dsp)
: "r"(rs), "r"(rt)
);
+ dsp = (dsp >> 20) & 0x01;
+ assert(dsp == resultdsp);
+ assert(rd == result);
+
+ rs = 0x80000000;
+ rt = 0x80000000;
+ result = 0;
+ resultdsp = 0x00;
+ __asm
+ ("wrdsp $0\n\t"
+ "subq_s.w %0, %2, %3\n\t"
+ "rddsp %1\n\t"
+ : "=r"(rd), "=r"(dsp)
+ : "r"(rs), "r"(rt)
+ );
dsp = (dsp >> 20) & 0x01;
assert(dsp == resultdsp);
assert(rd == result);
-#endif
+
return 0;
}
diff --git a/trace-events b/trace-events
index a27ae43032..3064fc7767 100644
--- a/trace-events
+++ b/trace-events
@@ -460,6 +460,7 @@ scsi_req_data(int target, int lun, int tag, int len) "target %d lun %d tag %d le
scsi_req_data_canceled(int target, int lun, int tag, int len) "target %d lun %d tag %d len %d"
scsi_req_dequeue(int target, int lun, int tag) "target %d lun %d tag %d"
scsi_req_continue(int target, int lun, int tag) "target %d lun %d tag %d"
+scsi_req_continue_canceled(int target, int lun, int tag) "target %d lun %d tag %d"
scsi_req_parsed(int target, int lun, int tag, int cmd, int mode, int xfer) "target %d lun %d tag %d command %d dir %d length %d"
scsi_req_parsed_lba(int target, int lun, int tag, int cmd, uint64_t lba) "target %d lun %d tag %d command %d lba %"PRIu64
scsi_req_parse_bad(int target, int lun, int tag, int cmd) "target %d lun %d tag %d command %d"
diff --git a/translate-all.c b/translate-all.c
index b50fb89528..90ea002935 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -1349,55 +1349,6 @@ static TranslationBlock *tb_find_pc(uintptr_t tc_ptr)
return &tcg_ctx.tb_ctx.tbs[m_max];
}
-static void tb_reset_jump_recursive(TranslationBlock *tb);
-
-static inline void tb_reset_jump_recursive2(TranslationBlock *tb, int n)
-{
- TranslationBlock *tb1, *tb_next, **ptb;
- unsigned int n1;
-
- tb1 = tb->jmp_next[n];
- if (tb1 != NULL) {
- /* find head of list */
- for (;;) {
- n1 = (uintptr_t)tb1 & 3;
- tb1 = (TranslationBlock *)((uintptr_t)tb1 & ~3);
- if (n1 == 2) {
- break;
- }
- tb1 = tb1->jmp_next[n1];
- }
- /* we are now sure now that tb jumps to tb1 */
- tb_next = tb1;
-
- /* remove tb from the jmp_first list */
- ptb = &tb_next->jmp_first;
- for (;;) {
- tb1 = *ptb;
- n1 = (uintptr_t)tb1 & 3;
- tb1 = (TranslationBlock *)((uintptr_t)tb1 & ~3);
- if (n1 == n && tb1 == tb) {
- break;
- }
- ptb = &tb1->jmp_next[n1];
- }
- *ptb = tb->jmp_next[n];
- tb->jmp_next[n] = NULL;
-
- /* suppress the jump to next tb in generated code */
- tb_reset_jump(tb, n);
-
- /* suppress jumps in the tb on which we could have jumped */
- tb_reset_jump_recursive(tb_next);
- }
-}
-
-static void tb_reset_jump_recursive(TranslationBlock *tb)
-{
- tb_reset_jump_recursive2(tb, 0);
- tb_reset_jump_recursive2(tb, 1);
-}
-
#if defined(TARGET_HAS_ICE) && !defined(CONFIG_USER_ONLY)
void tb_invalidate_phys_addr(hwaddr addr)
{
@@ -1416,26 +1367,6 @@ void tb_invalidate_phys_addr(hwaddr addr)
}
#endif /* TARGET_HAS_ICE && !defined(CONFIG_USER_ONLY) */
-void cpu_unlink_tb(CPUState *cpu)
-{
- /* FIXME: TB unchaining isn't SMP safe. For now just ignore the
- problem and hope the cpu will stop of its own accord. For userspace
- emulation this often isn't actually as bad as it sounds. Often
- signals are used primarily to interrupt blocking syscalls. */
- TranslationBlock *tb;
- static spinlock_t interrupt_lock = SPIN_LOCK_UNLOCKED;
-
- spin_lock(&interrupt_lock);
- tb = cpu->current_tb;
- /* if the cpu is currently executing code, we must unlink it and
- all the potentially executing TB */
- if (tb) {
- cpu->current_tb = NULL;
- tb_reset_jump_recursive(tb);
- }
- spin_unlock(&interrupt_lock);
-}
-
void tb_check_watchpoint(CPUArchState *env)
{
TranslationBlock *tb;
@@ -1475,7 +1406,7 @@ static void tcg_handle_interrupt(CPUArchState *env, int mask)
cpu_abort(env, "Raised interrupt while not in I/O function");
}
} else {
- cpu_unlink_tb(cpu);
+ cpu->tcg_exit_req = 1;
}
}
@@ -1626,7 +1557,7 @@ void cpu_interrupt(CPUArchState *env, int mask)
CPUState *cpu = ENV_GET_CPU(env);
env->interrupt_request |= mask;
- cpu_unlink_tb(cpu);
+ cpu->tcg_exit_req = 1;
}
/*
diff --git a/ui/console.c b/ui/console.c
index 0d95f32123..83a6fa3969 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -1739,3 +1739,10 @@ PixelFormat qemu_default_pixelformat(int bpp)
}
return pf;
}
+
+static void register_types(void)
+{
+ register_char_driver("vc", text_console_init);
+}
+
+type_init(register_types);
diff --git a/util/osdep.c b/util/osdep.c
index 5b51a0322e..bd59ac90c1 100644
--- a/util/osdep.c
+++ b/util/osdep.c
@@ -57,12 +57,18 @@ static const char *qemu_version = QEMU_VERSION;
int socket_set_cork(int fd, int v)
{
#if defined(SOL_TCP) && defined(TCP_CORK)
- return setsockopt(fd, SOL_TCP, TCP_CORK, &v, sizeof(v));
+ return qemu_setsockopt(fd, SOL_TCP, TCP_CORK, &v, sizeof(v));
#else
return 0;
#endif
}
+int socket_set_nodelay(int fd)
+{
+ int v = 1;
+ return qemu_setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &v, sizeof(v));
+}
+
int qemu_madvise(void *addr, size_t len, int advice)
{
if (advice == QEMU_MADV_INVALID) {
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index b4152fb33c..433dd6888b 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -35,7 +35,7 @@
extern int daemon(int, int);
#endif
-#if defined(__linux__) && defined(__x86_64__)
+#if defined(__linux__) && (defined(__x86_64__) || defined(__arm__))
/* Use 2 MiB alignment so transparent hugepages can be used by KVM.
Valgrind does not support alignments larger than 1 MiB,
therefore we need special code which handles running on Valgrind. */
diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
index 1350cccce3..3f122965ad 100644
--- a/util/qemu-sockets.c
+++ b/util/qemu-sockets.c
@@ -373,6 +373,10 @@ int inet_connect_opts(QemuOpts *opts, Error **errp,
}
for (e = res; e != NULL; e = e->ai_next) {
+ if (error_is_set(errp)) {
+ error_free(*errp);
+ *errp = NULL;
+ }
if (connect_state != NULL) {
connect_state->current_addr = e;
}
diff --git a/vl.c b/vl.c
index bbdbafdca6..154f7bae6a 100644
--- a/vl.c
+++ b/vl.c
@@ -119,7 +119,6 @@ int main(int argc, char **argv)
#include "hw/pcmcia.h"
#include "hw/pc.h"
#include "hw/isa.h"
-#include "char/baum.h"
#include "hw/bt.h"
#include "hw/watchdog.h"
#include "hw/smbios.h"