diff options
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); @@ -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); @@ -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; @@ -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, ...) @@ -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 = { @@ -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) { @@ -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) @@ -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; } @@ -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; +} @@ -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 */ @@ -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 @@ -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 Binary files differindex ab5dd9db6a..ec9eeb12c6 100644 --- a/pc-bios/bios.bin +++ b/pc-bios/bios.bin 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(¬ify); + } + 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) @@ -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; } @@ -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" |