Compare commits
59 Commits
master
...
stable-2.5
Author | SHA1 | Date |
---|---|---|
Michael Roth | db51dfc1fc | |
Michael S. Tsirkin | 5b7236f725 | |
Gerd Hoffmann | 0bcdb632f8 | |
Gerd Hoffmann | 706bab670b | |
Gerd Hoffmann | 44b86aa32e | |
Gerd Hoffmann | a6e5e5dd4b | |
Gerd Hoffmann | 2f2f74e87c | |
Gerd Hoffmann | 46aff2c7e9 | |
Gerd Hoffmann | 4f0323d26c | |
Michael Roth | a58047f7fb | |
Denis V. Lunev | 5f409b108f | |
Fam Zheng | 078de11898 | |
Fam Zheng | acea76c162 | |
Prasad J Pandit | 80b6e5723f | |
Prasad J Pandit | 9bddb45dbc | |
Prasad J Pandit | e3a2cdfcb5 | |
Prasad J Pandit | 4dcd2f13b1 | |
Prasad J Pandit | 38e09211b6 | |
Prasad J Pandit | d0ee85b4e4 | |
Prasad J Pandit | 4f046a6ba1 | |
P J P | b47809c6b3 | |
Wolfgang Bumiller | 24fe899c3c | |
John Snow | aaf4fb6afb | |
Greg Kurz | a2ae168821 | |
Marcel Apfelbaum | bad094d524 | |
Alberto Garcia | 4b0b1ec8e0 | |
Peter Maydell | cab1cc7245 | |
Michael S. Tsirkin | 9ae02175b4 | |
Laszlo Ersek | 30929793b0 | |
Marcel Apfelbaum | c5c9841ce8 | |
Marcel Apfelbaum | 6b62303eb8 | |
Greg Kurz | c06f342009 | |
Laszlo Ersek | cb873eaa6d | |
Jeff Cody | 4853a5a80f | |
Jeff Cody | a375e0b03e | |
Eric Blake | a38a283fc7 | |
Dr. David Alan Gilbert | 225d50fbb1 | |
Gabriel L. Somlo | 020282d3e6 | |
Halil Pasic | 091af18104 | |
Pierre Morel | d98392379a | |
Christian Borntraeger | 643c8d8ec1 | |
Gerd Hoffmann | 3ede27db32 | |
Laurent Vivier | 9849b1912f | |
Prasad J Pandit | fe90bdc25b | |
Li Zhijian | aaa5271327 | |
Li Zhijian | abda95cb01 | |
Max Reitz | 6a49a71cc6 | |
Max Reitz | e1a8a09124 | |
Prasad J Pandit | 7a2c1c8e66 | |
Marc-André Lureau | 702a8d165c | |
Marc-André Lureau | 3e96d5dcf2 | |
P J P | 16a2875735 | |
Greg Kurz | 4588b0d856 | |
Stefano Stabellini | ff083d3c3b | |
Stefano Stabellini | 4d59e78dfe | |
Peter Maydell | 52a7b27947 | |
Greg Kurz | d4aed70099 | |
P J P | 42ae4a3c61 | |
Gerd Hoffmann | 0d335804e3 |
24
block.c
24
block.c
|
@ -1976,21 +1976,25 @@ void bdrv_close_all(void)
|
|||
}
|
||||
}
|
||||
|
||||
/* Note that bs->device_list.tqe_prev is initially null,
|
||||
* and gets set to non-null by QTAILQ_INSERT_TAIL(). Establish
|
||||
* the useful invariant "bs in bdrv_states iff bs->tqe_prev" by
|
||||
* resetting it to null on remove. */
|
||||
void bdrv_device_remove(BlockDriverState *bs)
|
||||
{
|
||||
QTAILQ_REMOVE(&bdrv_states, bs, device_list);
|
||||
bs->device_list.tqe_prev = NULL;
|
||||
}
|
||||
|
||||
/* make a BlockDriverState anonymous by removing from bdrv_state and
|
||||
* graph_bdrv_state list.
|
||||
Also, NULL terminate the device_name to prevent double remove */
|
||||
void bdrv_make_anon(BlockDriverState *bs)
|
||||
{
|
||||
/*
|
||||
* Take care to remove bs from bdrv_states only when it's actually
|
||||
* in it. Note that bs->device_list.tqe_prev is initially null,
|
||||
* and gets set to non-null by QTAILQ_INSERT_TAIL(). Establish
|
||||
* the useful invariant "bs in bdrv_states iff bs->tqe_prev" by
|
||||
* resetting it to null on remove.
|
||||
*/
|
||||
/* Take care to remove bs from bdrv_states only when it's actually
|
||||
* in it. */
|
||||
if (bs->device_list.tqe_prev) {
|
||||
QTAILQ_REMOVE(&bdrv_states, bs, device_list);
|
||||
bs->device_list.tqe_prev = NULL;
|
||||
bdrv_device_remove(bs);
|
||||
}
|
||||
if (bs->node_name[0] != '\0') {
|
||||
QTAILQ_REMOVE(&graph_bdrv_states, bs, node_list);
|
||||
|
@ -2031,7 +2035,7 @@ static void change_parent_backing_link(BlockDriverState *from,
|
|||
if (!to->device_list.tqe_prev) {
|
||||
QTAILQ_INSERT_BEFORE(from, to, device_list);
|
||||
}
|
||||
QTAILQ_REMOVE(&bdrv_states, from, device_list);
|
||||
bdrv_device_remove(from);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -457,6 +457,14 @@ bool blk_dev_has_removable_media(BlockBackend *blk)
|
|||
return !blk->dev || (blk->dev_ops && blk->dev_ops->change_media_cb);
|
||||
}
|
||||
|
||||
/*
|
||||
* Does @blk's attached device model have a tray?
|
||||
*/
|
||||
bool blk_dev_has_tray(BlockBackend *blk)
|
||||
{
|
||||
return blk->dev_ops && blk->dev_ops->is_tray_open;
|
||||
}
|
||||
|
||||
/*
|
||||
* Notify @blk's attached device model of a media eject request.
|
||||
* If @force is true, the medium is about to be yanked out forcefully.
|
||||
|
@ -473,7 +481,7 @@ void blk_dev_eject_request(BlockBackend *blk, bool force)
|
|||
*/
|
||||
bool blk_dev_is_tray_open(BlockBackend *blk)
|
||||
{
|
||||
if (blk->dev_ops && blk->dev_ops->is_tray_open) {
|
||||
if (blk_dev_has_tray(blk)) {
|
||||
return blk->dev_ops->is_tray_open(blk->dev_opaque);
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -646,8 +646,9 @@ static BlockAIOCB *read_quorum_children(QuorumAIOCB *acb)
|
|||
}
|
||||
|
||||
for (i = 0; i < s->num_children; i++) {
|
||||
bdrv_aio_readv(s->children[i]->bs, acb->sector_num, &acb->qcrs[i].qiov,
|
||||
acb->nb_sectors, quorum_aio_cb, &acb->qcrs[i]);
|
||||
acb->qcrs[i].aiocb = bdrv_aio_readv(s->children[i]->bs, acb->sector_num,
|
||||
&acb->qcrs[i].qiov, acb->nb_sectors,
|
||||
quorum_aio_cb, &acb->qcrs[i]);
|
||||
}
|
||||
|
||||
return &acb->common;
|
||||
|
@ -662,9 +663,10 @@ static BlockAIOCB *read_fifo_child(QuorumAIOCB *acb)
|
|||
qemu_iovec_init(&acb->qcrs[acb->child_iter].qiov, acb->qiov->niov);
|
||||
qemu_iovec_clone(&acb->qcrs[acb->child_iter].qiov, acb->qiov,
|
||||
acb->qcrs[acb->child_iter].buf);
|
||||
bdrv_aio_readv(s->children[acb->child_iter]->bs, acb->sector_num,
|
||||
&acb->qcrs[acb->child_iter].qiov, acb->nb_sectors,
|
||||
quorum_aio_cb, &acb->qcrs[acb->child_iter]);
|
||||
acb->qcrs[acb->child_iter].aiocb =
|
||||
bdrv_aio_readv(s->children[acb->child_iter]->bs, acb->sector_num,
|
||||
&acb->qcrs[acb->child_iter].qiov, acb->nb_sectors,
|
||||
quorum_aio_cb, &acb->qcrs[acb->child_iter]);
|
||||
|
||||
return &acb->common;
|
||||
}
|
||||
|
|
|
@ -783,7 +783,6 @@ static int hdev_probe_geometry(BlockDriverState *bs, HDGeometry *geo)
|
|||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
struct hd_geometry ioctl_geo = {0};
|
||||
uint32_t blksize;
|
||||
|
||||
/* If DASD, get its geometry */
|
||||
if (check_for_dasd(s->fd) < 0) {
|
||||
|
@ -803,12 +802,6 @@ static int hdev_probe_geometry(BlockDriverState *bs, HDGeometry *geo)
|
|||
}
|
||||
geo->heads = ioctl_geo.heads;
|
||||
geo->sectors = ioctl_geo.sectors;
|
||||
if (!probe_physical_blocksize(s->fd, &blksize)) {
|
||||
/* overwrite cyls: HDIO_GETGEO result is incorrect for big drives */
|
||||
geo->cylinders = bdrv_nb_sectors(bs) / (blksize / BDRV_SECTOR_SIZE)
|
||||
/ (geo->heads * geo->sectors);
|
||||
return 0;
|
||||
}
|
||||
geo->cylinders = ioctl_geo.cylinders;
|
||||
|
||||
return 0;
|
||||
|
|
14
block/vmdk.c
14
block/vmdk.c
|
@ -570,6 +570,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
|
|||
VmdkExtent *extent;
|
||||
BDRVVmdkState *s = bs->opaque;
|
||||
int64_t l1_backup_offset = 0;
|
||||
bool compressed;
|
||||
|
||||
ret = bdrv_pread(file->bs, sizeof(magic), &header, sizeof(header));
|
||||
if (ret < 0) {
|
||||
|
@ -644,6 +645,8 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
|
|||
header = footer.header;
|
||||
}
|
||||
|
||||
compressed =
|
||||
le16_to_cpu(header.compressAlgorithm) == VMDK4_COMPRESSION_DEFLATE;
|
||||
if (le32_to_cpu(header.version) > 3) {
|
||||
char buf[64];
|
||||
snprintf(buf, sizeof(buf), "VMDK version %" PRId32,
|
||||
|
@ -651,7 +654,8 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
|
|||
error_setg(errp, QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
|
||||
bdrv_get_device_or_node_name(bs), "vmdk", buf);
|
||||
return -ENOTSUP;
|
||||
} else if (le32_to_cpu(header.version) == 3 && (flags & BDRV_O_RDWR)) {
|
||||
} else if (le32_to_cpu(header.version) == 3 && (flags & BDRV_O_RDWR) &&
|
||||
!compressed) {
|
||||
/* VMware KB 2064959 explains that version 3 added support for
|
||||
* persistent changed block tracking (CBT), and backup software can
|
||||
* read it as version=1 if it doesn't care about the changed area
|
||||
|
@ -1654,7 +1658,13 @@ static int vmdk_create_extent(const char *filename, int64_t filesize,
|
|||
}
|
||||
magic = cpu_to_be32(VMDK4_MAGIC);
|
||||
memset(&header, 0, sizeof(header));
|
||||
header.version = zeroed_grain ? 2 : 1;
|
||||
if (compress) {
|
||||
header.version = 3;
|
||||
} else if (zeroed_grain) {
|
||||
header.version = 2;
|
||||
} else {
|
||||
header.version = 1;
|
||||
}
|
||||
header.flags = VMDK4_FLAG_RGD | VMDK4_FLAG_NL_DETECT
|
||||
| (compress ? VMDK4_FLAG_COMPRESS | VMDK4_FLAG_MARKER : 0)
|
||||
| (zeroed_grain ? VMDK4_FLAG_ZERO_GRAIN : 0);
|
||||
|
|
34
blockdev.c
34
blockdev.c
|
@ -2306,6 +2306,11 @@ void qmp_blockdev_open_tray(const char *device, bool has_force, bool force,
|
|||
return;
|
||||
}
|
||||
|
||||
if (!blk_dev_has_tray(blk)) {
|
||||
/* Ignore this command on tray-less devices */
|
||||
return;
|
||||
}
|
||||
|
||||
if (blk_dev_is_tray_open(blk)) {
|
||||
return;
|
||||
}
|
||||
|
@ -2336,6 +2341,11 @@ void qmp_blockdev_close_tray(const char *device, Error **errp)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!blk_dev_has_tray(blk)) {
|
||||
/* Ignore this command on tray-less devices */
|
||||
return;
|
||||
}
|
||||
|
||||
if (!blk_dev_is_tray_open(blk)) {
|
||||
return;
|
||||
}
|
||||
|
@ -2365,7 +2375,7 @@ void qmp_x_blockdev_remove_medium(const char *device, Error **errp)
|
|||
return;
|
||||
}
|
||||
|
||||
if (has_device && !blk_dev_is_tray_open(blk)) {
|
||||
if (has_device && blk_dev_has_tray(blk) && !blk_dev_is_tray_open(blk)) {
|
||||
error_setg(errp, "Tray of device '%s' is not open", device);
|
||||
return;
|
||||
}
|
||||
|
@ -2384,12 +2394,19 @@ void qmp_x_blockdev_remove_medium(const char *device, Error **errp)
|
|||
|
||||
/* This follows the convention established by bdrv_make_anon() */
|
||||
if (bs->device_list.tqe_prev) {
|
||||
QTAILQ_REMOVE(&bdrv_states, bs, device_list);
|
||||
bs->device_list.tqe_prev = NULL;
|
||||
bdrv_device_remove(bs);
|
||||
}
|
||||
|
||||
blk_remove_bs(blk);
|
||||
|
||||
if (!blk_dev_has_tray(blk)) {
|
||||
/* For tray-less devices, blockdev-open-tray is a no-op (or may not be
|
||||
* called at all); therefore, the medium needs to be ejected here.
|
||||
* Do it after blk_remove_bs() so blk_is_inserted(blk) returns the @load
|
||||
* value passed here (i.e. false). */
|
||||
blk_dev_change_media_cb(blk, false);
|
||||
}
|
||||
|
||||
out:
|
||||
aio_context_release(aio_context);
|
||||
}
|
||||
|
@ -2415,7 +2432,7 @@ static void qmp_blockdev_insert_anon_medium(const char *device,
|
|||
return;
|
||||
}
|
||||
|
||||
if (has_device && !blk_dev_is_tray_open(blk)) {
|
||||
if (has_device && blk_dev_has_tray(blk) && !blk_dev_is_tray_open(blk)) {
|
||||
error_setg(errp, "Tray of device '%s' is not open", device);
|
||||
return;
|
||||
}
|
||||
|
@ -2428,6 +2445,15 @@ static void qmp_blockdev_insert_anon_medium(const char *device,
|
|||
blk_insert_bs(blk, bs);
|
||||
|
||||
QTAILQ_INSERT_TAIL(&bdrv_states, bs, device_list);
|
||||
|
||||
if (!blk_dev_has_tray(blk)) {
|
||||
/* For tray-less devices, blockdev-close-tray is a no-op (or may not be
|
||||
* called at all); therefore, the medium needs to be pushed into the
|
||||
* slot here.
|
||||
* Do it after blk_insert_bs() so blk_is_inserted(blk) returns the @load
|
||||
* value passed here (i.e. true). */
|
||||
blk_dev_change_media_cb(blk, true);
|
||||
}
|
||||
}
|
||||
|
||||
void qmp_x_blockdev_insert_medium(const char *device, const char *node_name,
|
||||
|
|
|
@ -4758,7 +4758,11 @@ echo "GTK GL support $gtk_gl"
|
|||
echo "GNUTLS support $gnutls"
|
||||
echo "GNUTLS hash $gnutls_hash"
|
||||
echo "libgcrypt $gcrypt"
|
||||
echo "nettle $nettle ${nettle+($nettle_version)}"
|
||||
if test "$nettle" = "yes"; then
|
||||
echo "nettle $nettle ($nettle_version)"
|
||||
else
|
||||
echo "nettle $nettle"
|
||||
fi
|
||||
echo "libtasn1 $tasn1"
|
||||
echo "VTE support $vte"
|
||||
echo "curses support $curses"
|
||||
|
|
4
cpus.c
4
cpus.c
|
@ -986,7 +986,7 @@ static void qemu_wait_io_event_common(CPUState *cpu)
|
|||
if (cpu->stop) {
|
||||
cpu->stop = false;
|
||||
cpu->stopped = true;
|
||||
qemu_cond_signal(&qemu_pause_cond);
|
||||
qemu_cond_broadcast(&qemu_pause_cond);
|
||||
}
|
||||
flush_queued_work(cpu);
|
||||
cpu->thread_kicked = false;
|
||||
|
@ -1387,7 +1387,7 @@ void cpu_stop_current(void)
|
|||
current_cpu->stop = false;
|
||||
current_cpu->stopped = true;
|
||||
cpu_exit(current_cpu);
|
||||
qemu_cond_signal(&qemu_pause_cond);
|
||||
qemu_cond_broadcast(&qemu_pause_cond);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
18
hmp.c
18
hmp.c
|
@ -1734,21 +1734,18 @@ void hmp_sendkey(Monitor *mon, const QDict *qdict)
|
|||
int has_hold_time = qdict_haskey(qdict, "hold-time");
|
||||
int hold_time = qdict_get_try_int(qdict, "hold-time", -1);
|
||||
Error *err = NULL;
|
||||
char keyname_buf[16];
|
||||
char *separator;
|
||||
int keyname_len;
|
||||
|
||||
while (1) {
|
||||
separator = strchr(keys, '-');
|
||||
keyname_len = separator ? separator - keys : strlen(keys);
|
||||
pstrcpy(keyname_buf, sizeof(keyname_buf), keys);
|
||||
|
||||
/* Be compatible with old interface, convert user inputted "<" */
|
||||
if (!strncmp(keyname_buf, "<", 1) && keyname_len == 1) {
|
||||
pstrcpy(keyname_buf, sizeof(keyname_buf), "less");
|
||||
if (keys[0] == '<' && keyname_len == 1) {
|
||||
keys = "less";
|
||||
keyname_len = 4;
|
||||
}
|
||||
keyname_buf[keyname_len] = 0;
|
||||
|
||||
keylist = g_malloc0(sizeof(*keylist));
|
||||
keylist->value = g_malloc0(sizeof(*keylist->value));
|
||||
|
@ -1761,16 +1758,17 @@ void hmp_sendkey(Monitor *mon, const QDict *qdict)
|
|||
}
|
||||
tmp = keylist;
|
||||
|
||||
if (strstart(keyname_buf, "0x", NULL)) {
|
||||
if (strstart(keys, "0x", NULL)) {
|
||||
char *endp;
|
||||
int value = strtoul(keyname_buf, &endp, 0);
|
||||
if (*endp != '\0') {
|
||||
int value = strtoul(keys, &endp, 0);
|
||||
assert(endp <= keys + keyname_len);
|
||||
if (endp != keys + keyname_len) {
|
||||
goto err_out;
|
||||
}
|
||||
keylist->value->type = KEY_VALUE_KIND_NUMBER;
|
||||
keylist->value->u.number = value;
|
||||
} else {
|
||||
int idx = index_from_key(keyname_buf);
|
||||
int idx = index_from_key(keys, keyname_len);
|
||||
if (idx == Q_KEY_CODE_MAX) {
|
||||
goto err_out;
|
||||
}
|
||||
|
@ -1792,7 +1790,7 @@ out:
|
|||
return;
|
||||
|
||||
err_out:
|
||||
monitor_printf(mon, "invalid parameter: %s\n", keyname_buf);
|
||||
monitor_printf(mon, "invalid parameter: %.*s\n", keyname_len, keys);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,6 @@ static int coroutine_enter_func(void *arg)
|
|||
void co_run_in_worker_bh(void *opaque)
|
||||
{
|
||||
Coroutine *co = opaque;
|
||||
thread_pool_submit_aio(qemu_get_aio_context()->thread_pool,
|
||||
thread_pool_submit_aio(aio_get_thread_pool(qemu_get_aio_context()),
|
||||
coroutine_enter_func, co, coroutine_enter_cb, co);
|
||||
}
|
||||
|
|
|
@ -85,8 +85,10 @@ static inline void blkif_get_x86_32_req(blkif_request_t *dst, blkif_x86_32_reque
|
|||
d->nr_sectors = s->nr_sectors;
|
||||
return;
|
||||
}
|
||||
if (n > src->nr_segments)
|
||||
n = src->nr_segments;
|
||||
/* prevent the compiler from optimizing the code and using src->nr_segments instead */
|
||||
barrier();
|
||||
if (n > dst->nr_segments)
|
||||
n = dst->nr_segments;
|
||||
for (i = 0; i < n; i++)
|
||||
dst->seg[i] = src->seg[i];
|
||||
}
|
||||
|
@ -106,8 +108,10 @@ static inline void blkif_get_x86_64_req(blkif_request_t *dst, blkif_x86_64_reque
|
|||
d->nr_sectors = s->nr_sectors;
|
||||
return;
|
||||
}
|
||||
if (n > src->nr_segments)
|
||||
n = src->nr_segments;
|
||||
/* prevent the compiler from optimizing the code and using src->nr_segments instead */
|
||||
barrier();
|
||||
if (n > dst->nr_segments)
|
||||
n = dst->nr_segments;
|
||||
for (i = 0; i < n; i++)
|
||||
dst->seg[i] = src->seg[i];
|
||||
}
|
||||
|
|
|
@ -374,6 +374,9 @@ static void uart_write(void *opaque, hwaddr offset,
|
|||
|
||||
DB_PRINT(" offset:%x data:%08x\n", (unsigned)offset, (unsigned)value);
|
||||
offset >>= 2;
|
||||
if (offset >= CADENCE_UART_R_MAX) {
|
||||
return;
|
||||
}
|
||||
switch (offset) {
|
||||
case R_IER: /* ier (wts imr) */
|
||||
s->r[R_IMR] |= value;
|
||||
|
|
|
@ -283,6 +283,21 @@ static bool machine_get_suppress_vmdesc(Object *obj, Error **errp)
|
|||
return ms->suppress_vmdesc;
|
||||
}
|
||||
|
||||
static void machine_set_enforce_config_section(Object *obj, bool value,
|
||||
Error **errp)
|
||||
{
|
||||
MachineState *ms = MACHINE(obj);
|
||||
|
||||
ms->enforce_config_section = value;
|
||||
}
|
||||
|
||||
static bool machine_get_enforce_config_section(Object *obj, Error **errp)
|
||||
{
|
||||
MachineState *ms = MACHINE(obj);
|
||||
|
||||
return ms->enforce_config_section;
|
||||
}
|
||||
|
||||
static int error_on_sysbus_device(SysBusDevice *sbdev, void *opaque)
|
||||
{
|
||||
error_report("Option '-device %s' cannot be handled by this machine",
|
||||
|
@ -437,6 +452,12 @@ static void machine_initfn(Object *obj)
|
|||
object_property_set_description(obj, "suppress-vmdesc",
|
||||
"Set on to disable self-describing migration",
|
||||
NULL);
|
||||
object_property_add_bool(obj, "enforce-config-section",
|
||||
machine_get_enforce_config_section,
|
||||
machine_set_enforce_config_section, NULL);
|
||||
object_property_set_description(obj, "enforce-config-section",
|
||||
"Set on to enforce configuration section migration",
|
||||
NULL);
|
||||
|
||||
/* Register notifier when init is done for sysbus sanity checks */
|
||||
ms->sysbus_notifier.notify = machine_init_notify;
|
||||
|
|
122
hw/display/vga.c
122
hw/display/vga.c
|
@ -140,6 +140,13 @@ static uint32_t expand4[256];
|
|||
static uint16_t expand2[256];
|
||||
static uint8_t expand4to8[16];
|
||||
|
||||
static void vbe_update_vgaregs(VGACommonState *s);
|
||||
|
||||
static inline bool vbe_enabled(VGACommonState *s)
|
||||
{
|
||||
return s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED;
|
||||
}
|
||||
|
||||
static void vga_update_memory_access(VGACommonState *s)
|
||||
{
|
||||
hwaddr base, offset, size;
|
||||
|
@ -177,6 +184,7 @@ static void vga_update_memory_access(VGACommonState *s)
|
|||
size = 0x8000;
|
||||
break;
|
||||
}
|
||||
assert(offset + size <= s->vram_size);
|
||||
memory_region_init_alias(&s->chain4_alias, memory_region_owner(&s->vram),
|
||||
"vga.chain4", &s->vram, offset, size);
|
||||
memory_region_add_subregion_overlap(s->legacy_address_space, base,
|
||||
|
@ -476,6 +484,7 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
|||
printf("vga: write SR%x = 0x%02x\n", s->sr_index, val);
|
||||
#endif
|
||||
s->sr[s->sr_index] = val & sr_mask[s->sr_index];
|
||||
vbe_update_vgaregs(s);
|
||||
if (s->sr_index == VGA_SEQ_CLOCK_MODE) {
|
||||
s->update_retrace_info(s);
|
||||
}
|
||||
|
@ -507,6 +516,7 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
|||
printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);
|
||||
#endif
|
||||
s->gr[s->gr_index] = val & gr_mask[s->gr_index];
|
||||
vbe_update_vgaregs(s);
|
||||
vga_update_memory_access(s);
|
||||
break;
|
||||
case VGA_CRT_IM:
|
||||
|
@ -525,10 +535,12 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
|||
if (s->cr_index == VGA_CRTC_OVERFLOW) {
|
||||
s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x10) |
|
||||
(val & 0x10);
|
||||
vbe_update_vgaregs(s);
|
||||
}
|
||||
return;
|
||||
}
|
||||
s->cr[s->cr_index] = val;
|
||||
vbe_update_vgaregs(s);
|
||||
|
||||
switch(s->cr_index) {
|
||||
case VGA_CRTC_H_TOTAL:
|
||||
|
@ -561,7 +573,7 @@ static void vbe_fixup_regs(VGACommonState *s)
|
|||
uint16_t *r = s->vbe_regs;
|
||||
uint32_t bits, linelength, maxy, offset;
|
||||
|
||||
if (!(r[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) {
|
||||
if (!vbe_enabled(s)) {
|
||||
/* vbe is turned off -- nothing to do */
|
||||
return;
|
||||
}
|
||||
|
@ -636,6 +648,49 @@ static void vbe_fixup_regs(VGACommonState *s)
|
|||
s->vbe_start_addr = offset / 4;
|
||||
}
|
||||
|
||||
/* we initialize the VGA graphic mode */
|
||||
static void vbe_update_vgaregs(VGACommonState *s)
|
||||
{
|
||||
int h, shift_control;
|
||||
|
||||
if (!vbe_enabled(s)) {
|
||||
/* vbe is turned off -- nothing to do */
|
||||
return;
|
||||
}
|
||||
|
||||
/* graphic mode + memory map 1 */
|
||||
s->gr[VGA_GFX_MISC] = (s->gr[VGA_GFX_MISC] & ~0x0c) | 0x04 |
|
||||
VGA_GR06_GRAPHICS_MODE;
|
||||
s->cr[VGA_CRTC_MODE] |= 3; /* no CGA modes */
|
||||
s->cr[VGA_CRTC_OFFSET] = s->vbe_line_offset >> 3;
|
||||
/* width */
|
||||
s->cr[VGA_CRTC_H_DISP] =
|
||||
(s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 3) - 1;
|
||||
/* height (only meaningful if < 1024) */
|
||||
h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1;
|
||||
s->cr[VGA_CRTC_V_DISP_END] = h;
|
||||
s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x42) |
|
||||
((h >> 7) & 0x02) | ((h >> 3) & 0x40);
|
||||
/* line compare to 1023 */
|
||||
s->cr[VGA_CRTC_LINE_COMPARE] = 0xff;
|
||||
s->cr[VGA_CRTC_OVERFLOW] |= 0x10;
|
||||
s->cr[VGA_CRTC_MAX_SCAN] |= 0x40;
|
||||
|
||||
if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
|
||||
shift_control = 0;
|
||||
s->sr[VGA_SEQ_CLOCK_MODE] &= ~8; /* no double line */
|
||||
} else {
|
||||
shift_control = 2;
|
||||
/* set chain 4 mode */
|
||||
s->sr[VGA_SEQ_MEMORY_MODE] |= VGA_SR04_CHN_4M;
|
||||
/* activate all planes */
|
||||
s->sr[VGA_SEQ_PLANE_WRITE] |= VGA_SR02_ALL_PLANES;
|
||||
}
|
||||
s->gr[VGA_GFX_MODE] = (s->gr[VGA_GFX_MODE] & ~0x60) |
|
||||
(shift_control << 5);
|
||||
s->cr[VGA_CRTC_MAX_SCAN] &= ~0x9f; /* no double scan */
|
||||
}
|
||||
|
||||
static uint32_t vbe_ioport_read_index(void *opaque, uint32_t addr)
|
||||
{
|
||||
VGACommonState *s = opaque;
|
||||
|
@ -712,13 +767,10 @@ void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
|
|||
case VBE_DISPI_INDEX_Y_OFFSET:
|
||||
s->vbe_regs[s->vbe_index] = val;
|
||||
vbe_fixup_regs(s);
|
||||
vbe_update_vgaregs(s);
|
||||
break;
|
||||
case VBE_DISPI_INDEX_BANK:
|
||||
if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
|
||||
val &= (s->vbe_bank_mask >> 2);
|
||||
} else {
|
||||
val &= s->vbe_bank_mask;
|
||||
}
|
||||
val &= s->vbe_bank_mask;
|
||||
s->vbe_regs[s->vbe_index] = val;
|
||||
s->bank_offset = (val << 16);
|
||||
vga_update_memory_access(s);
|
||||
|
@ -726,52 +778,19 @@ void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
|
|||
case VBE_DISPI_INDEX_ENABLE:
|
||||
if ((val & VBE_DISPI_ENABLED) &&
|
||||
!(s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) {
|
||||
int h, shift_control;
|
||||
|
||||
s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = 0;
|
||||
s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0;
|
||||
s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0;
|
||||
s->vbe_regs[VBE_DISPI_INDEX_ENABLE] |= VBE_DISPI_ENABLED;
|
||||
vbe_fixup_regs(s);
|
||||
vbe_update_vgaregs(s);
|
||||
|
||||
/* clear the screen */
|
||||
if (!(val & VBE_DISPI_NOCLEARMEM)) {
|
||||
memset(s->vram_ptr, 0,
|
||||
s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset);
|
||||
}
|
||||
|
||||
/* we initialize the VGA graphic mode */
|
||||
/* graphic mode + memory map 1 */
|
||||
s->gr[VGA_GFX_MISC] = (s->gr[VGA_GFX_MISC] & ~0x0c) | 0x04 |
|
||||
VGA_GR06_GRAPHICS_MODE;
|
||||
s->cr[VGA_CRTC_MODE] |= 3; /* no CGA modes */
|
||||
s->cr[VGA_CRTC_OFFSET] = s->vbe_line_offset >> 3;
|
||||
/* width */
|
||||
s->cr[VGA_CRTC_H_DISP] =
|
||||
(s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 3) - 1;
|
||||
/* height (only meaningful if < 1024) */
|
||||
h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1;
|
||||
s->cr[VGA_CRTC_V_DISP_END] = h;
|
||||
s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x42) |
|
||||
((h >> 7) & 0x02) | ((h >> 3) & 0x40);
|
||||
/* line compare to 1023 */
|
||||
s->cr[VGA_CRTC_LINE_COMPARE] = 0xff;
|
||||
s->cr[VGA_CRTC_OVERFLOW] |= 0x10;
|
||||
s->cr[VGA_CRTC_MAX_SCAN] |= 0x40;
|
||||
|
||||
if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
|
||||
shift_control = 0;
|
||||
s->sr[VGA_SEQ_CLOCK_MODE] &= ~8; /* no double line */
|
||||
} else {
|
||||
shift_control = 2;
|
||||
/* set chain 4 mode */
|
||||
s->sr[VGA_SEQ_MEMORY_MODE] |= VGA_SR04_CHN_4M;
|
||||
/* activate all planes */
|
||||
s->sr[VGA_SEQ_PLANE_WRITE] |= VGA_SR02_ALL_PLANES;
|
||||
}
|
||||
s->gr[VGA_GFX_MODE] = (s->gr[VGA_GFX_MODE] & ~0x60) |
|
||||
(shift_control << 5);
|
||||
s->cr[VGA_CRTC_MAX_SCAN] &= ~0x9f; /* no double scan */
|
||||
} else {
|
||||
s->bank_offset = 0;
|
||||
}
|
||||
|
@ -817,13 +836,21 @@ uint32_t vga_mem_readb(VGACommonState *s, hwaddr addr)
|
|||
|
||||
if (s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) {
|
||||
/* chain 4 mode : simplest access */
|
||||
assert(addr < s->vram_size);
|
||||
ret = s->vram_ptr[addr];
|
||||
} else if (s->gr[VGA_GFX_MODE] & 0x10) {
|
||||
/* odd/even mode (aka text mode mapping) */
|
||||
plane = (s->gr[VGA_GFX_PLANE_READ] & 2) | (addr & 1);
|
||||
ret = s->vram_ptr[((addr & ~1) << 1) | plane];
|
||||
addr = ((addr & ~1) << 1) | plane;
|
||||
if (addr >= s->vram_size) {
|
||||
return 0xff;
|
||||
}
|
||||
ret = s->vram_ptr[addr];
|
||||
} else {
|
||||
/* standard VGA latched access */
|
||||
if (addr * sizeof(uint32_t) >= s->vram_size) {
|
||||
return 0xff;
|
||||
}
|
||||
s->latch = ((uint32_t *)s->vram_ptr)[addr];
|
||||
|
||||
if (!(s->gr[VGA_GFX_MODE] & 0x08)) {
|
||||
|
@ -880,6 +907,7 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
|
|||
plane = addr & 3;
|
||||
mask = (1 << plane);
|
||||
if (s->sr[VGA_SEQ_PLANE_WRITE] & mask) {
|
||||
assert(addr < s->vram_size);
|
||||
s->vram_ptr[addr] = val;
|
||||
#ifdef DEBUG_VGA_MEM
|
||||
printf("vga: chain4: [0x" TARGET_FMT_plx "]\n", addr);
|
||||
|
@ -893,6 +921,9 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
|
|||
mask = (1 << plane);
|
||||
if (s->sr[VGA_SEQ_PLANE_WRITE] & mask) {
|
||||
addr = ((addr & ~1) << 1) | plane;
|
||||
if (addr >= s->vram_size) {
|
||||
return;
|
||||
}
|
||||
s->vram_ptr[addr] = val;
|
||||
#ifdef DEBUG_VGA_MEM
|
||||
printf("vga: odd/even: [0x" TARGET_FMT_plx "]\n", addr);
|
||||
|
@ -966,6 +997,9 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
|
|||
mask = s->sr[VGA_SEQ_PLANE_WRITE];
|
||||
s->plane_updated |= mask; /* only used to detect font change */
|
||||
write_mask = mask16[mask];
|
||||
if (addr * sizeof(uint32_t) >= s->vram_size) {
|
||||
return;
|
||||
}
|
||||
((uint32_t *)s->vram_ptr)[addr] =
|
||||
(((uint32_t *)s->vram_ptr)[addr] & ~write_mask) |
|
||||
(val & write_mask);
|
||||
|
@ -1044,7 +1078,7 @@ static void vga_get_offsets(VGACommonState *s,
|
|||
{
|
||||
uint32_t start_addr, line_offset, line_compare;
|
||||
|
||||
if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
|
||||
if (vbe_enabled(s)) {
|
||||
line_offset = s->vbe_line_offset;
|
||||
start_addr = s->vbe_start_addr;
|
||||
line_compare = 65535;
|
||||
|
@ -1369,7 +1403,7 @@ static int vga_get_bpp(VGACommonState *s)
|
|||
{
|
||||
int ret;
|
||||
|
||||
if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
|
||||
if (vbe_enabled(s)) {
|
||||
ret = s->vbe_regs[VBE_DISPI_INDEX_BPP];
|
||||
} else {
|
||||
ret = 0;
|
||||
|
@ -1381,7 +1415,7 @@ static void vga_get_resolution(VGACommonState *s, int *pwidth, int *pheight)
|
|||
{
|
||||
int width, height;
|
||||
|
||||
if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
|
||||
if (vbe_enabled(s)) {
|
||||
width = s->vbe_regs[VBE_DISPI_INDEX_XRES];
|
||||
height = s->vbe_regs[VBE_DISPI_INDEX_YRES];
|
||||
} else {
|
||||
|
|
|
@ -784,18 +784,20 @@ static void xenfb_invalidate(void *opaque)
|
|||
|
||||
static void xenfb_handle_events(struct XenFB *xenfb)
|
||||
{
|
||||
uint32_t prod, cons;
|
||||
uint32_t prod, cons, out_cons;
|
||||
struct xenfb_page *page = xenfb->c.page;
|
||||
|
||||
prod = page->out_prod;
|
||||
if (prod == page->out_cons)
|
||||
out_cons = page->out_cons;
|
||||
if (prod == out_cons)
|
||||
return;
|
||||
xen_rmb(); /* ensure we see ring contents up to prod */
|
||||
for (cons = page->out_cons; cons != prod; cons++) {
|
||||
for (cons = out_cons; cons != prod; cons++) {
|
||||
union xenfb_out_event *event = &XENFB_OUT_RING_REF(page, cons);
|
||||
uint8_t type = event->type;
|
||||
int x, y, w, h;
|
||||
|
||||
switch (event->type) {
|
||||
switch (type) {
|
||||
case XENFB_TYPE_UPDATE:
|
||||
if (xenfb->up_count == UP_QUEUE)
|
||||
xenfb->up_fullscreen = 1;
|
||||
|
|
|
@ -634,13 +634,18 @@ static int vapic_prepare(VAPICROMState *s)
|
|||
static void vapic_write(void *opaque, hwaddr addr, uint64_t data,
|
||||
unsigned int size)
|
||||
{
|
||||
CPUState *cs = current_cpu;
|
||||
X86CPU *cpu = X86_CPU(cs);
|
||||
CPUX86State *env = &cpu->env;
|
||||
hwaddr rom_paddr;
|
||||
VAPICROMState *s = opaque;
|
||||
X86CPU *cpu;
|
||||
CPUX86State *env;
|
||||
hwaddr rom_paddr;
|
||||
|
||||
cpu_synchronize_state(cs);
|
||||
if (!current_cpu) {
|
||||
return;
|
||||
}
|
||||
|
||||
cpu_synchronize_state(current_cpu);
|
||||
cpu = X86_CPU(current_cpu);
|
||||
env = &cpu->env;
|
||||
|
||||
/*
|
||||
* The VAPIC supports two PIO-based hypercalls, both via port 0x7E.
|
||||
|
|
|
@ -661,6 +661,10 @@ static bool ahci_map_fis_address(AHCIDevice *ad)
|
|||
|
||||
static void ahci_unmap_fis_address(AHCIDevice *ad)
|
||||
{
|
||||
if (ad->res_fis == NULL) {
|
||||
DPRINTF(ad->port_no, "Attempt to unmap NULL FIS address\n");
|
||||
return;
|
||||
}
|
||||
dma_memory_unmap(ad->hba->as, ad->res_fis, 256,
|
||||
DMA_DIRECTION_FROM_DEVICE, 256);
|
||||
ad->res_fis = NULL;
|
||||
|
@ -677,6 +681,10 @@ static bool ahci_map_clb_address(AHCIDevice *ad)
|
|||
|
||||
static void ahci_unmap_clb_address(AHCIDevice *ad)
|
||||
{
|
||||
if (ad->lst == NULL) {
|
||||
DPRINTF(ad->port_no, "Attempt to unmap NULL CLB address\n");
|
||||
return;
|
||||
}
|
||||
dma_memory_unmap(ad->hba->as, ad->lst, 1024,
|
||||
DMA_DIRECTION_FROM_DEVICE, 1024);
|
||||
ad->lst = NULL;
|
||||
|
@ -910,6 +918,7 @@ static void ncq_err(NCQTransferState *ncq_tfs)
|
|||
ide_state->error = ABRT_ERR;
|
||||
ide_state->status = READY_STAT | ERR_STAT;
|
||||
ncq_tfs->drive->port_regs.scr_err |= (1 << ncq_tfs->tag);
|
||||
ncq_tfs->used = 0;
|
||||
}
|
||||
|
||||
static void ncq_finish(NCQTransferState *ncq_tfs)
|
||||
|
|
|
@ -350,17 +350,14 @@ static void ivshmem_vector_poll(PCIDevice *dev,
|
|||
}
|
||||
}
|
||||
|
||||
static CharDriverState* create_eventfd_chr_device(void * opaque, EventNotifier *n,
|
||||
static CharDriverState* create_eventfd_chr_device(IVShmemState *s,
|
||||
EventNotifier *n,
|
||||
int vector)
|
||||
{
|
||||
/* create a event character device based on the passed eventfd */
|
||||
IVShmemState *s = opaque;
|
||||
PCIDevice *pdev = PCI_DEVICE(s);
|
||||
int eventfd = event_notifier_get_fd(n);
|
||||
CharDriverState *chr;
|
||||
|
||||
s->msi_vectors[vector].pdev = pdev;
|
||||
|
||||
chr = qemu_chr_open_eventfd(eventfd);
|
||||
|
||||
if (chr == NULL) {
|
||||
|
|
|
@ -908,7 +908,8 @@ start_xmit(E1000State *s)
|
|||
* bogus values to TDT/TDLEN.
|
||||
* there's nothing too intelligent we could do about this.
|
||||
*/
|
||||
if (s->mac_reg[TDH] == tdh_start) {
|
||||
if (s->mac_reg[TDH] == tdh_start ||
|
||||
tdh_start >= s->mac_reg[TDLEN] / sizeof(desc)) {
|
||||
DBGOUT(TXERR, "TDH wraparound @%x, TDT %x, TDLEN %x\n",
|
||||
tdh_start, s->mac_reg[TDT], s->mac_reg[TDLEN]);
|
||||
break;
|
||||
|
@ -1165,7 +1166,8 @@ e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt)
|
|||
if (++s->mac_reg[RDH] * sizeof(desc) >= s->mac_reg[RDLEN])
|
||||
s->mac_reg[RDH] = 0;
|
||||
/* see comment in start_xmit; same here */
|
||||
if (s->mac_reg[RDH] == rdh_start) {
|
||||
if (s->mac_reg[RDH] == rdh_start ||
|
||||
rdh_start >= s->mac_reg[RDLEN] / sizeof(desc)) {
|
||||
DBGOUT(RXERR, "RDH wraparound @%x, RDT %x, RDLEN %x\n",
|
||||
rdh_start, s->mac_reg[RDT], s->mac_reg[RDLEN]);
|
||||
set_ics(s, 0, E1000_ICS_RXO);
|
||||
|
|
|
@ -154,6 +154,10 @@ static int ne2000_buffer_full(NE2000State *s)
|
|||
{
|
||||
int avail, index, boundary;
|
||||
|
||||
if (s->stop <= s->start) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
index = s->curpag << 8;
|
||||
boundary = s->boundary << 8;
|
||||
if (index < boundary)
|
||||
|
@ -467,8 +471,9 @@ static inline void ne2000_mem_writel(NE2000State *s, uint32_t addr,
|
|||
uint32_t val)
|
||||
{
|
||||
addr &= ~1; /* XXX: check exact behaviour if not even */
|
||||
if (addr < 32 ||
|
||||
(addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
|
||||
if (addr < 32
|
||||
|| (addr >= NE2000_PMEM_START
|
||||
&& addr + sizeof(uint32_t) <= NE2000_MEM_SIZE)) {
|
||||
stl_le_p(s->mem + addr, val);
|
||||
}
|
||||
}
|
||||
|
@ -497,8 +502,9 @@ static inline uint32_t ne2000_mem_readw(NE2000State *s, uint32_t addr)
|
|||
static inline uint32_t ne2000_mem_readl(NE2000State *s, uint32_t addr)
|
||||
{
|
||||
addr &= ~1; /* XXX: check exact behaviour if not even */
|
||||
if (addr < 32 ||
|
||||
(addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
|
||||
if (addr < 32
|
||||
|| (addr >= NE2000_PMEM_START
|
||||
&& addr + sizeof(uint32_t) <= NE2000_MEM_SIZE)) {
|
||||
return ldl_le_p(s->mem + addr);
|
||||
} else {
|
||||
return 0xffffffff;
|
||||
|
|
|
@ -232,6 +232,9 @@ static int tx_consume(Rocker *r, DescInfo *info)
|
|||
frag_addr = rocker_tlv_get_le64(tlvs[ROCKER_TLV_TX_FRAG_ATTR_ADDR]);
|
||||
frag_len = rocker_tlv_get_le16(tlvs[ROCKER_TLV_TX_FRAG_ATTR_LEN]);
|
||||
|
||||
if (iovcnt >= ROCKER_TX_FRAGS_MAX) {
|
||||
goto err_too_many_frags;
|
||||
}
|
||||
iov[iovcnt].iov_len = frag_len;
|
||||
iov[iovcnt].iov_base = g_malloc(frag_len);
|
||||
if (!iov[iovcnt].iov_base) {
|
||||
|
@ -244,10 +247,7 @@ static int tx_consume(Rocker *r, DescInfo *info)
|
|||
err = -ROCKER_ENXIO;
|
||||
goto err_bad_io;
|
||||
}
|
||||
|
||||
if (++iovcnt > ROCKER_TX_FRAGS_MAX) {
|
||||
goto err_too_many_frags;
|
||||
}
|
||||
iovcnt++;
|
||||
}
|
||||
|
||||
if (iovcnt) {
|
||||
|
|
|
@ -300,21 +300,19 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
|
|||
BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(dev)));
|
||||
VirtioBusState *vbus = VIRTIO_BUS(qbus);
|
||||
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(vbus);
|
||||
int r, e, i;
|
||||
int r, e, i, j;
|
||||
|
||||
if (!k->set_guest_notifiers) {
|
||||
error_report("binding does not support guest notifiers");
|
||||
r = -ENOSYS;
|
||||
goto err;
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
r = vhost_net_set_vnet_endian(dev, ncs[0].peer, true);
|
||||
if (r < 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (i = 0; i < total_queues; i++) {
|
||||
vhost_net_set_vq_index(get_vhost_net(ncs[i].peer), i * 2);
|
||||
for (j = 0; j < total_queues; j++) {
|
||||
r = vhost_net_set_vnet_endian(dev, ncs[j].peer, true);
|
||||
if (r < 0) {
|
||||
goto err_endian;
|
||||
}
|
||||
vhost_net_set_vq_index(get_vhost_net(ncs[j].peer), j * 2);
|
||||
}
|
||||
|
||||
r = k->set_guest_notifiers(qbus->parent, total_queues * 2, true);
|
||||
|
@ -343,8 +341,9 @@ err_start:
|
|||
fflush(stderr);
|
||||
}
|
||||
err_endian:
|
||||
vhost_net_set_vnet_endian(dev, ncs[0].peer, false);
|
||||
err:
|
||||
while (--j >= 0) {
|
||||
vhost_net_set_vnet_endian(dev, ncs[j].peer, false);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
@ -1194,8 +1194,13 @@ static void vmxnet3_reset_mac(VMXNET3State *s)
|
|||
|
||||
static void vmxnet3_deactivate_device(VMXNET3State *s)
|
||||
{
|
||||
VMW_CBPRN("Deactivating vmxnet3...");
|
||||
s->device_active = false;
|
||||
if (s->device_active) {
|
||||
VMW_CBPRN("Deactivating vmxnet3...");
|
||||
vmxnet_tx_pkt_reset(s->tx_pkt);
|
||||
vmxnet_tx_pkt_uninit(s->tx_pkt);
|
||||
vmxnet_rx_pkt_uninit(s->rx_pkt);
|
||||
s->device_active = false;
|
||||
}
|
||||
}
|
||||
|
||||
static void vmxnet3_reset(VMXNET3State *s)
|
||||
|
@ -1204,7 +1209,6 @@ static void vmxnet3_reset(VMXNET3State *s)
|
|||
|
||||
vmxnet3_deactivate_device(s);
|
||||
vmxnet3_reset_interrupt_states(s);
|
||||
vmxnet_tx_pkt_reset(s->tx_pkt);
|
||||
s->drv_shmem = 0;
|
||||
s->tx_sop = true;
|
||||
s->skip_current_tx_pkt = false;
|
||||
|
@ -1431,6 +1435,12 @@ static void vmxnet3_activate_device(VMXNET3State *s)
|
|||
return;
|
||||
}
|
||||
|
||||
/* Verify if device is active */
|
||||
if (s->device_active) {
|
||||
VMW_CFPRN("Vmxnet3 device is active");
|
||||
return;
|
||||
}
|
||||
|
||||
vmxnet3_adjust_by_guest_type(s);
|
||||
vmxnet3_update_features(s);
|
||||
vmxnet3_update_pm_state(s);
|
||||
|
@ -1627,7 +1637,7 @@ static void vmxnet3_handle_command(VMXNET3State *s, uint64_t cmd)
|
|||
break;
|
||||
|
||||
case VMXNET3_CMD_QUIESCE_DEV:
|
||||
VMW_CBPRN("Set: VMXNET3_CMD_QUIESCE_DEV - pause the device");
|
||||
VMW_CBPRN("Set: VMXNET3_CMD_QUIESCE_DEV - deactivate the device");
|
||||
vmxnet3_deactivate_device(s);
|
||||
break;
|
||||
|
||||
|
@ -1741,7 +1751,7 @@ vmxnet3_io_bar1_write(void *opaque,
|
|||
* shared address only after we get the high part
|
||||
*/
|
||||
if (val == 0) {
|
||||
s->device_active = false;
|
||||
vmxnet3_deactivate_device(s);
|
||||
}
|
||||
s->temp_shared_guest_driver_memory = val;
|
||||
s->drv_shmem = 0;
|
||||
|
@ -2021,9 +2031,7 @@ static bool vmxnet3_peer_has_vnet_hdr(VMXNET3State *s)
|
|||
static void vmxnet3_net_uninit(VMXNET3State *s)
|
||||
{
|
||||
g_free(s->mcast_list);
|
||||
vmxnet_tx_pkt_reset(s->tx_pkt);
|
||||
vmxnet_tx_pkt_uninit(s->tx_pkt);
|
||||
vmxnet_rx_pkt_uninit(s->rx_pkt);
|
||||
vmxnet3_deactivate_device(s);
|
||||
qemu_del_nic(s->nic);
|
||||
}
|
||||
|
||||
|
|
|
@ -270,7 +270,8 @@ static int fw_cfg_select(FWCfgState *s, uint16_t key)
|
|||
static uint8_t fw_cfg_read(FWCfgState *s)
|
||||
{
|
||||
int arch = !!(s->cur_entry & FW_CFG_ARCH_LOCAL);
|
||||
FWCfgEntry *e = &s->entries[arch][s->cur_entry & FW_CFG_ENTRY_MASK];
|
||||
FWCfgEntry *e = (s->cur_entry == FW_CFG_INVALID) ? NULL :
|
||||
&s->entries[arch][s->cur_entry & FW_CFG_ENTRY_MASK];
|
||||
uint8_t ret;
|
||||
|
||||
if (s->cur_entry == FW_CFG_INVALID || !e->data || s->cur_offset >= e->len)
|
||||
|
@ -338,7 +339,8 @@ static void fw_cfg_dma_transfer(FWCfgState *s)
|
|||
}
|
||||
|
||||
arch = !!(s->cur_entry & FW_CFG_ARCH_LOCAL);
|
||||
e = &s->entries[arch][s->cur_entry & FW_CFG_ENTRY_MASK];
|
||||
e = (s->cur_entry == FW_CFG_INVALID) ? NULL :
|
||||
&s->entries[arch][s->cur_entry & FW_CFG_ENTRY_MASK];
|
||||
|
||||
if (dma.control & FW_CFG_DMA_CTL_READ) {
|
||||
read = 1;
|
||||
|
@ -780,17 +782,19 @@ FWCfgState *fw_cfg_init_io_dma(uint32_t iobase, uint32_t dma_iobase,
|
|||
DeviceState *dev;
|
||||
FWCfgState *s;
|
||||
uint32_t version = FW_CFG_VERSION;
|
||||
bool dma_enabled = dma_iobase && dma_as;
|
||||
bool dma_requested = dma_iobase && dma_as;
|
||||
|
||||
dev = qdev_create(NULL, TYPE_FW_CFG_IO);
|
||||
qdev_prop_set_uint32(dev, "iobase", iobase);
|
||||
qdev_prop_set_uint32(dev, "dma_iobase", dma_iobase);
|
||||
qdev_prop_set_bit(dev, "dma_enabled", dma_enabled);
|
||||
if (!dma_requested) {
|
||||
qdev_prop_set_bit(dev, "dma_enabled", false);
|
||||
}
|
||||
|
||||
fw_cfg_init1(dev);
|
||||
s = FW_CFG(dev);
|
||||
|
||||
if (dma_enabled) {
|
||||
if (s->dma_enabled) {
|
||||
/* 64 bits for the address field */
|
||||
s->dma_as = dma_as;
|
||||
s->dma_addr = 0;
|
||||
|
@ -816,11 +820,13 @@ FWCfgState *fw_cfg_init_mem_wide(hwaddr ctl_addr,
|
|||
SysBusDevice *sbd;
|
||||
FWCfgState *s;
|
||||
uint32_t version = FW_CFG_VERSION;
|
||||
bool dma_enabled = dma_addr && dma_as;
|
||||
bool dma_requested = dma_addr && dma_as;
|
||||
|
||||
dev = qdev_create(NULL, TYPE_FW_CFG_MEM);
|
||||
qdev_prop_set_uint32(dev, "data_width", data_width);
|
||||
qdev_prop_set_bit(dev, "dma_enabled", dma_enabled);
|
||||
if (!dma_requested) {
|
||||
qdev_prop_set_bit(dev, "dma_enabled", false);
|
||||
}
|
||||
|
||||
fw_cfg_init1(dev);
|
||||
|
||||
|
@ -830,7 +836,7 @@ FWCfgState *fw_cfg_init_mem_wide(hwaddr ctl_addr,
|
|||
|
||||
s = FW_CFG(dev);
|
||||
|
||||
if (dma_enabled) {
|
||||
if (s->dma_enabled) {
|
||||
s->dma_as = dma_as;
|
||||
s->dma_addr = 0;
|
||||
sysbus_mmio_map(sbd, 2, dma_addr);
|
||||
|
@ -875,7 +881,7 @@ static Property fw_cfg_io_properties[] = {
|
|||
DEFINE_PROP_UINT32("iobase", FWCfgIoState, iobase, -1),
|
||||
DEFINE_PROP_UINT32("dma_iobase", FWCfgIoState, dma_iobase, -1),
|
||||
DEFINE_PROP_BOOL("dma_enabled", FWCfgIoState, parent_obj.dma_enabled,
|
||||
false),
|
||||
true),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
|
@ -915,7 +921,7 @@ static const TypeInfo fw_cfg_io_info = {
|
|||
static Property fw_cfg_mem_properties[] = {
|
||||
DEFINE_PROP_UINT32("data_width", FWCfgMemState, data_width, -1),
|
||||
DEFINE_PROP_BOOL("dma_enabled", FWCfgMemState, parent_obj.dma_enabled,
|
||||
false),
|
||||
true),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
|
|
|
@ -2327,6 +2327,7 @@ static void spapr_compat_2_3(Object *obj)
|
|||
{
|
||||
savevm_skip_section_footers();
|
||||
global_state_set_optional();
|
||||
savevm_skip_configuration();
|
||||
}
|
||||
|
||||
static void spapr_compat_2_2(Object *obj)
|
||||
|
|
|
@ -701,7 +701,7 @@ int css_do_csch(SubchDev *sch)
|
|||
|
||||
/* Trigger the clear function. */
|
||||
s->ctrl &= ~(SCSW_CTRL_MASK_FCTL | SCSW_CTRL_MASK_ACTL);
|
||||
s->ctrl |= SCSW_FCTL_CLEAR_FUNC | SCSW_FCTL_CLEAR_FUNC;
|
||||
s->ctrl |= SCSW_FCTL_CLEAR_FUNC | SCSW_ACTL_CLEAR_PEND;
|
||||
|
||||
do_subchannel_work(sch, NULL);
|
||||
ret = 0;
|
||||
|
|
|
@ -718,7 +718,7 @@ static int megasas_ctrl_get_info(MegasasState *s, MegasasCmd *cmd)
|
|||
BusChild *kid;
|
||||
int num_pd_disks = 0;
|
||||
|
||||
memset(&info, 0x0, cmd->iov_size);
|
||||
memset(&info, 0x0, dcmd_size);
|
||||
if (cmd->iov_size < dcmd_size) {
|
||||
trace_megasas_dcmd_invalid_xfer_len(cmd->index, cmd->iov_size,
|
||||
dcmd_size);
|
||||
|
|
|
@ -128,9 +128,16 @@ static void do_token_setup(USBDevice *s, USBPacket *p)
|
|||
}
|
||||
|
||||
usb_packet_copy(p, s->setup_buf, p->iov.size);
|
||||
s->setup_index = 0;
|
||||
p->actual_length = 0;
|
||||
s->setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6];
|
||||
s->setup_index = 0;
|
||||
if (s->setup_len > sizeof(s->data_buf)) {
|
||||
fprintf(stderr,
|
||||
"usb_generic_handle_packet: ctrl buffer too small (%d > %zu)\n",
|
||||
s->setup_len, sizeof(s->data_buf));
|
||||
p->status = USB_RET_STALL;
|
||||
return;
|
||||
}
|
||||
|
||||
request = (s->setup_buf[0] << 8) | s->setup_buf[1];
|
||||
value = (s->setup_buf[3] << 8) | s->setup_buf[2];
|
||||
|
@ -151,13 +158,6 @@ static void do_token_setup(USBDevice *s, USBPacket *p)
|
|||
}
|
||||
s->setup_state = SETUP_STATE_DATA;
|
||||
} else {
|
||||
if (s->setup_len > sizeof(s->data_buf)) {
|
||||
fprintf(stderr,
|
||||
"usb_generic_handle_packet: ctrl buffer too small (%d > %zu)\n",
|
||||
s->setup_len, sizeof(s->data_buf));
|
||||
p->status = USB_RET_STALL;
|
||||
return;
|
||||
}
|
||||
if (s->setup_len == 0)
|
||||
s->setup_state = SETUP_STATE_ACK;
|
||||
else
|
||||
|
@ -176,7 +176,7 @@ static void do_token_in(USBDevice *s, USBPacket *p)
|
|||
request = (s->setup_buf[0] << 8) | s->setup_buf[1];
|
||||
value = (s->setup_buf[3] << 8) | s->setup_buf[2];
|
||||
index = (s->setup_buf[5] << 8) | s->setup_buf[4];
|
||||
|
||||
|
||||
switch(s->setup_state) {
|
||||
case SETUP_STATE_ACK:
|
||||
if (!(s->setup_buf[0] & USB_DIR_IN)) {
|
||||
|
|
|
@ -653,7 +653,8 @@ typedef struct USBNetState {
|
|||
|
||||
static int is_rndis(USBNetState *s)
|
||||
{
|
||||
return s->dev.config->bConfigurationValue == DEV_RNDIS_CONFIG_VALUE;
|
||||
return s->dev.config ?
|
||||
s->dev.config->bConfigurationValue == DEV_RNDIS_CONFIG_VALUE : 0;
|
||||
}
|
||||
|
||||
static int ndis_query(USBNetState *s, uint32_t oid,
|
||||
|
@ -914,8 +915,9 @@ static int rndis_query_response(USBNetState *s,
|
|||
|
||||
bufoffs = le32_to_cpu(buf->InformationBufferOffset) + 8;
|
||||
buflen = le32_to_cpu(buf->InformationBufferLength);
|
||||
if (bufoffs + buflen > length)
|
||||
if (buflen > length || bufoffs >= length || bufoffs + buflen > length) {
|
||||
return USB_RET_STALL;
|
||||
}
|
||||
|
||||
infobuflen = ndis_query(s, le32_to_cpu(buf->OID),
|
||||
bufoffs + (uint8_t *) buf, buflen, infobuf,
|
||||
|
@ -960,8 +962,9 @@ static int rndis_set_response(USBNetState *s,
|
|||
|
||||
bufoffs = le32_to_cpu(buf->InformationBufferOffset) + 8;
|
||||
buflen = le32_to_cpu(buf->InformationBufferLength);
|
||||
if (bufoffs + buflen > length)
|
||||
if (buflen > length || bufoffs >= length || bufoffs + buflen > length) {
|
||||
return USB_RET_STALL;
|
||||
}
|
||||
|
||||
ret = ndis_set(s, le32_to_cpu(buf->OID),
|
||||
bufoffs + (uint8_t *) buf, buflen);
|
||||
|
@ -1211,8 +1214,9 @@ static void usb_net_handle_dataout(USBNetState *s, USBPacket *p)
|
|||
if (le32_to_cpu(msg->MessageType) == RNDIS_PACKET_MSG) {
|
||||
uint32_t offs = 8 + le32_to_cpu(msg->DataOffset);
|
||||
uint32_t size = le32_to_cpu(msg->DataLength);
|
||||
if (offs + size <= len)
|
||||
if (offs < len && size < len && offs + size <= len) {
|
||||
qemu_send_packet(qemu_get_queue(s->nic), s->out_buf + offs, size);
|
||||
}
|
||||
}
|
||||
s->out_ptr -= len;
|
||||
memmove(s->out_buf, &s->out_buf[len], s->out_ptr);
|
||||
|
|
|
@ -865,6 +865,7 @@ void ehci_reset(void *opaque)
|
|||
s->usbsts = USBSTS_HALT;
|
||||
s->usbsts_pending = 0;
|
||||
s->usbsts_frindex = 0;
|
||||
ehci_update_irq(s);
|
||||
|
||||
s->astate = EST_INACTIVE;
|
||||
s->pstate = EST_INACTIVE;
|
||||
|
@ -1404,21 +1405,23 @@ static int ehci_process_itd(EHCIState *ehci,
|
|||
if (itd->transact[i] & ITD_XACT_ACTIVE) {
|
||||
pg = get_field(itd->transact[i], ITD_XACT_PGSEL);
|
||||
off = itd->transact[i] & ITD_XACT_OFFSET_MASK;
|
||||
ptr1 = (itd->bufptr[pg] & ITD_BUFPTR_MASK);
|
||||
ptr2 = (itd->bufptr[pg+1] & ITD_BUFPTR_MASK);
|
||||
len = get_field(itd->transact[i], ITD_XACT_LENGTH);
|
||||
|
||||
if (len > max * mult) {
|
||||
len = max * mult;
|
||||
}
|
||||
|
||||
if (len > BUFF_SIZE) {
|
||||
if (len > BUFF_SIZE || pg > 6) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ptr1 = (itd->bufptr[pg] & ITD_BUFPTR_MASK);
|
||||
qemu_sglist_init(&ehci->isgl, ehci->device, 2, ehci->as);
|
||||
if (off + len > 4096) {
|
||||
/* transfer crosses page border */
|
||||
if (pg == 6) {
|
||||
return -1; /* avoid page pg + 1 */
|
||||
}
|
||||
ptr2 = (itd->bufptr[pg + 1] & ITD_BUFPTR_MASK);
|
||||
uint32_t len2 = off + len - 4096;
|
||||
uint32_t len1 = len - len2;
|
||||
qemu_sglist_add(&ehci->isgl, ptr1 + off, len1);
|
||||
|
@ -2000,6 +2003,7 @@ static int ehci_state_writeback(EHCIQueue *q)
|
|||
static void ehci_advance_state(EHCIState *ehci, int async)
|
||||
{
|
||||
EHCIQueue *q = NULL;
|
||||
int itd_count = 0;
|
||||
int again;
|
||||
|
||||
do {
|
||||
|
@ -2024,10 +2028,12 @@ static void ehci_advance_state(EHCIState *ehci, int async)
|
|||
|
||||
case EST_FETCHITD:
|
||||
again = ehci_state_fetchitd(ehci, async);
|
||||
itd_count++;
|
||||
break;
|
||||
|
||||
case EST_FETCHSITD:
|
||||
again = ehci_state_fetchsitd(ehci, async);
|
||||
itd_count++;
|
||||
break;
|
||||
|
||||
case EST_ADVANCEQUEUE:
|
||||
|
@ -2076,7 +2082,8 @@ static void ehci_advance_state(EHCIState *ehci, int async)
|
|||
break;
|
||||
}
|
||||
|
||||
if (again < 0) {
|
||||
if (again < 0 || itd_count > 16) {
|
||||
/* TODO: notify guest (raise HSE irq?) */
|
||||
fprintf(stderr, "processing error - resetting ehci HC\n");
|
||||
ehci_reset(ehci);
|
||||
again = 0;
|
||||
|
|
|
@ -612,6 +612,25 @@ static int vhost_user_migration_done(struct vhost_dev *dev, char* mac_addr)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static bool vhost_user_can_merge(struct vhost_dev *dev,
|
||||
uint64_t start1, uint64_t size1,
|
||||
uint64_t start2, uint64_t size2)
|
||||
{
|
||||
ram_addr_t ram_addr;
|
||||
int mfd, rfd;
|
||||
MemoryRegion *mr;
|
||||
|
||||
mr = qemu_ram_addr_from_host((void *)(uintptr_t)start1, &ram_addr);
|
||||
assert(mr);
|
||||
mfd = qemu_get_ram_fd(ram_addr);
|
||||
|
||||
mr = qemu_ram_addr_from_host((void *)(uintptr_t)start2, &ram_addr);
|
||||
assert(mr);
|
||||
rfd = qemu_get_ram_fd(ram_addr);
|
||||
|
||||
return mfd == rfd;
|
||||
}
|
||||
|
||||
const VhostOps user_ops = {
|
||||
.backend_type = VHOST_BACKEND_TYPE_USER,
|
||||
.vhost_backend_init = vhost_user_init,
|
||||
|
@ -634,4 +653,5 @@ const VhostOps user_ops = {
|
|||
.vhost_set_vring_enable = vhost_user_set_vring_enable,
|
||||
.vhost_requires_shm_log = vhost_user_requires_shm_log,
|
||||
.vhost_migration_done = vhost_user_migration_done,
|
||||
.vhost_backend_can_merge = vhost_user_can_merge,
|
||||
};
|
||||
|
|
|
@ -259,6 +259,13 @@ static void vhost_dev_assign_memory(struct vhost_dev *dev,
|
|||
continue;
|
||||
}
|
||||
|
||||
if (dev->vhost_ops->vhost_backend_can_merge &&
|
||||
!dev->vhost_ops->vhost_backend_can_merge(dev, uaddr, size,
|
||||
reg->userspace_addr,
|
||||
reg->memory_size)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (merged) {
|
||||
--to;
|
||||
assert(to >= 0);
|
||||
|
|
|
@ -59,30 +59,33 @@ typedef struct VirtioBusClass VirtioPCIBusClass;
|
|||
#define VIRTIO_PCI_BUS_CLASS(klass) \
|
||||
OBJECT_CLASS_CHECK(VirtioPCIBusClass, klass, TYPE_VIRTIO_PCI_BUS)
|
||||
|
||||
enum {
|
||||
VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION_BIT,
|
||||
VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT,
|
||||
VIRTIO_PCI_FLAG_DISABLE_LEGACY_BIT,
|
||||
VIRTIO_PCI_FLAG_DISABLE_MODERN_BIT,
|
||||
VIRTIO_PCI_FLAG_MIGRATE_EXTRA_BIT,
|
||||
VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY_BIT,
|
||||
VIRTIO_PCI_FLAG_DISABLE_PCIE_BIT,
|
||||
};
|
||||
|
||||
/* Need to activate work-arounds for buggy guests at vmstate load. */
|
||||
#define VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION_BIT 0
|
||||
#define VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION \
|
||||
(1 << VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION_BIT)
|
||||
|
||||
/* Performance improves when virtqueue kick processing is decoupled from the
|
||||
* vcpu thread using ioeventfd for some devices. */
|
||||
#define VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT 1
|
||||
#define VIRTIO_PCI_FLAG_USE_IOEVENTFD (1 << VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT)
|
||||
|
||||
/* virtio version flags */
|
||||
#define VIRTIO_PCI_FLAG_DISABLE_LEGACY_BIT 2
|
||||
#define VIRTIO_PCI_FLAG_DISABLE_MODERN_BIT 3
|
||||
#define VIRTIO_PCI_FLAG_DISABLE_PCIE_BIT 4
|
||||
#define VIRTIO_PCI_FLAG_DISABLE_LEGACY (1 << VIRTIO_PCI_FLAG_DISABLE_LEGACY_BIT)
|
||||
#define VIRTIO_PCI_FLAG_DISABLE_MODERN (1 << VIRTIO_PCI_FLAG_DISABLE_MODERN_BIT)
|
||||
#define VIRTIO_PCI_FLAG_DISABLE_PCIE (1 << VIRTIO_PCI_FLAG_DISABLE_PCIE_BIT)
|
||||
|
||||
/* migrate extra state */
|
||||
#define VIRTIO_PCI_FLAG_MIGRATE_EXTRA_BIT 4
|
||||
#define VIRTIO_PCI_FLAG_MIGRATE_EXTRA (1 << VIRTIO_PCI_FLAG_MIGRATE_EXTRA_BIT)
|
||||
|
||||
/* have pio notification for modern device ? */
|
||||
#define VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY_BIT 5
|
||||
#define VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY \
|
||||
(1 << VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY_BIT)
|
||||
|
||||
|
|
|
@ -196,6 +196,7 @@ int bdrv_create(BlockDriver *drv, const char* filename,
|
|||
int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp);
|
||||
BlockDriverState *bdrv_new_root(void);
|
||||
BlockDriverState *bdrv_new(void);
|
||||
void bdrv_device_remove(BlockDriverState *bs);
|
||||
void bdrv_make_anon(BlockDriverState *bs);
|
||||
void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old);
|
||||
void bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top);
|
||||
|
|
|
@ -686,6 +686,7 @@ void blk_set_bs(BlockBackend *blk, BlockDriverState *bs);
|
|||
|
||||
void blk_dev_change_media_cb(BlockBackend *blk, bool load);
|
||||
bool blk_dev_has_removable_media(BlockBackend *blk);
|
||||
bool blk_dev_has_tray(BlockBackend *blk);
|
||||
void blk_dev_eject_request(BlockBackend *blk, bool force);
|
||||
bool blk_dev_is_tray_open(BlockBackend *blk);
|
||||
bool blk_dev_is_medium_locked(BlockBackend *blk);
|
||||
|
|
|
@ -124,6 +124,7 @@ struct MachineState {
|
|||
char *firmware;
|
||||
bool iommu;
|
||||
bool suppress_vmdesc;
|
||||
bool enforce_config_section;
|
||||
|
||||
ram_addr_t ram_size;
|
||||
ram_addr_t maxram_size;
|
||||
|
|
|
@ -18,6 +18,14 @@
|
|||
.driver = "virtio-pci",\
|
||||
.property = "migrate-extra",\
|
||||
.value = "off",\
|
||||
},{\
|
||||
.driver = "fw_cfg_mem",\
|
||||
.property = "dma_enabled",\
|
||||
.value = "off",\
|
||||
},{\
|
||||
.driver = "fw_cfg_io",\
|
||||
.property = "dma_enabled",\
|
||||
.value = "off",\
|
||||
},
|
||||
|
||||
#define HW_COMPAT_2_3 \
|
||||
|
|
|
@ -70,6 +70,9 @@ typedef int (*vhost_set_vring_enable_op)(struct vhost_dev *dev,
|
|||
typedef bool (*vhost_requires_shm_log_op)(struct vhost_dev *dev);
|
||||
typedef int (*vhost_migration_done_op)(struct vhost_dev *dev,
|
||||
char *mac_addr);
|
||||
typedef bool (*vhost_backend_can_merge_op)(struct vhost_dev *dev,
|
||||
uint64_t start1, uint64_t size1,
|
||||
uint64_t start2, uint64_t size2);
|
||||
|
||||
typedef struct VhostOps {
|
||||
VhostBackendType backend_type;
|
||||
|
@ -97,6 +100,7 @@ typedef struct VhostOps {
|
|||
vhost_set_vring_enable_op vhost_set_vring_enable;
|
||||
vhost_requires_shm_log_op vhost_requires_shm_log;
|
||||
vhost_migration_done_op vhost_migration_done;
|
||||
vhost_backend_can_merge_op vhost_backend_can_merge;
|
||||
} VhostOps;
|
||||
|
||||
extern const VhostOps user_ops;
|
||||
|
|
|
@ -433,7 +433,7 @@ static inline int vnc_display_pw_expire(const char *id, time_t expires)
|
|||
void curses_display_init(DisplayState *ds, int full_screen);
|
||||
|
||||
/* input.c */
|
||||
int index_from_key(const char *key);
|
||||
int index_from_key(const char *key, size_t key_length);
|
||||
|
||||
/* gtk.c */
|
||||
void early_gtk_display_init(int opengl);
|
||||
|
|
|
@ -878,13 +878,19 @@ bool qemu_savevm_state_blocked(Error **errp)
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool enforce_config_section(void)
|
||||
{
|
||||
MachineState *machine = MACHINE(qdev_get_machine());
|
||||
return machine->enforce_config_section;
|
||||
}
|
||||
|
||||
void qemu_savevm_state_header(QEMUFile *f)
|
||||
{
|
||||
trace_savevm_state_header();
|
||||
qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
|
||||
qemu_put_be32(f, QEMU_VM_FILE_VERSION);
|
||||
|
||||
if (!savevm_state.skip_configuration) {
|
||||
if (!savevm_state.skip_configuration || enforce_config_section()) {
|
||||
qemu_put_byte(f, QEMU_VM_CONFIGURATION);
|
||||
vmstate_save_state(f, &vmstate_configuration, &savevm_state, 0);
|
||||
}
|
||||
|
@ -1839,7 +1845,7 @@ int qemu_loadvm_state(QEMUFile *f)
|
|||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (!savevm_state.skip_configuration) {
|
||||
if (!savevm_state.skip_configuration || enforce_config_section()) {
|
||||
if (qemu_get_byte(f) != QEMU_VM_CONFIGURATION) {
|
||||
error_report("Configuration section missing");
|
||||
return -EINVAL;
|
||||
|
|
|
@ -59,6 +59,11 @@ void net_checksum_calculate(uint8_t *data, int length)
|
|||
int hlen, plen, proto, csum_offset;
|
||||
uint16_t csum;
|
||||
|
||||
/* Ensure data has complete L2 & L3 headers. */
|
||||
if (length < 14 + 20) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((data[14] & 0xf0) != 0x40)
|
||||
return; /* not IPv4 */
|
||||
hlen = (data[14] & 0x0f) * 4;
|
||||
|
@ -76,8 +81,9 @@ void net_checksum_calculate(uint8_t *data, int length)
|
|||
return;
|
||||
}
|
||||
|
||||
if (plen < csum_offset+2)
|
||||
return;
|
||||
if (plen < csum_offset + 2 || 14 + hlen + plen > length) {
|
||||
return;
|
||||
}
|
||||
|
||||
data[14+hlen+csum_offset] = 0;
|
||||
data[14+hlen+csum_offset+1] = 0;
|
||||
|
|
|
@ -329,6 +329,13 @@ static void filter_dump_instance_init(Object *obj)
|
|||
file_dump_set_filename, NULL);
|
||||
}
|
||||
|
||||
static void filter_dump_instance_finalize(Object *obj)
|
||||
{
|
||||
NetFilterDumpState *nfds = FILTER_DUMP(obj);
|
||||
|
||||
g_free(nfds->filename);
|
||||
}
|
||||
|
||||
static void filter_dump_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
NetFilterClass *nfc = NETFILTER_CLASS(oc);
|
||||
|
@ -343,6 +350,7 @@ static const TypeInfo filter_dump_info = {
|
|||
.parent = TYPE_NETFILTER,
|
||||
.class_init = filter_dump_class_init,
|
||||
.instance_init = filter_dump_instance_init,
|
||||
.instance_finalize = filter_dump_instance_finalize,
|
||||
.instance_size = sizeof(NetFilterDumpState),
|
||||
};
|
||||
|
||||
|
|
|
@ -204,6 +204,7 @@ static void netfilter_finalize(Object *obj)
|
|||
if (nf->netdev && !QTAILQ_EMPTY(&nf->netdev->filters)) {
|
||||
QTAILQ_REMOVE(&nf->netdev->filters, nf, next);
|
||||
}
|
||||
g_free(nf->netdev_id);
|
||||
}
|
||||
|
||||
static void netfilter_class_init(ObjectClass *oc, void *data)
|
||||
|
|
|
@ -2048,8 +2048,7 @@
|
|||
# respond to the eject request
|
||||
# - if the BlockBackend denoted by @device does not have a guest device attached
|
||||
# to it
|
||||
# - if the guest device does not have an actual tray and is empty, for instance
|
||||
# for floppy disk drives
|
||||
# - if the guest device does not have an actual tray
|
||||
#
|
||||
# @device: block device name
|
||||
#
|
||||
|
|
|
@ -29,6 +29,15 @@ typedef QTAILQ_HEAD(QStack, QStackEntry) QStack;
|
|||
struct QmpOutputVisitor
|
||||
{
|
||||
Visitor visitor;
|
||||
/* FIXME: we are abusing stack to hold two separate pieces of
|
||||
* information: the current root object in slot 0, and the stack
|
||||
* of N objects still being built in slots 1 through N (for N+1
|
||||
* slots in use). Worse, our behavior is inconsistent:
|
||||
* qmp_output_add_obj() visiting two top-level scalars in a row
|
||||
* discards the first in favor of the second, but visiting two
|
||||
* top-level objects in a row tries to append the second object
|
||||
* into the first (since the first object was placed in the stack
|
||||
* in both slot 0 and 1, but only popped from slot 1). */
|
||||
QStack stack;
|
||||
};
|
||||
|
||||
|
@ -41,10 +50,12 @@ static QmpOutputVisitor *to_qov(Visitor *v)
|
|||
return container_of(v, QmpOutputVisitor, visitor);
|
||||
}
|
||||
|
||||
/* Push @value onto the stack of current QObjects being built */
|
||||
static void qmp_output_push_obj(QmpOutputVisitor *qov, QObject *value)
|
||||
{
|
||||
QStackEntry *e = g_malloc0(sizeof(*e));
|
||||
|
||||
assert(value);
|
||||
e->value = value;
|
||||
if (qobject_type(e->value) == QTYPE_QLIST) {
|
||||
e->is_list_head = true;
|
||||
|
@ -52,44 +63,53 @@ static void qmp_output_push_obj(QmpOutputVisitor *qov, QObject *value)
|
|||
QTAILQ_INSERT_HEAD(&qov->stack, e, node);
|
||||
}
|
||||
|
||||
/* Pop a value off the stack of QObjects being built, and return it. */
|
||||
static QObject *qmp_output_pop(QmpOutputVisitor *qov)
|
||||
{
|
||||
QStackEntry *e = QTAILQ_FIRST(&qov->stack);
|
||||
QObject *value;
|
||||
|
||||
assert(e);
|
||||
QTAILQ_REMOVE(&qov->stack, e, node);
|
||||
value = e->value;
|
||||
assert(value);
|
||||
g_free(e);
|
||||
return value;
|
||||
}
|
||||
|
||||
/* Grab the root QObject, if any */
|
||||
static QObject *qmp_output_first(QmpOutputVisitor *qov)
|
||||
{
|
||||
QStackEntry *e = QTAILQ_LAST(&qov->stack, QStack);
|
||||
|
||||
/*
|
||||
* FIXME Wrong, because qmp_output_get_qobject() will increment
|
||||
* the refcnt *again*. We need to think through how visitors
|
||||
* handle null.
|
||||
*/
|
||||
if (!e) {
|
||||
return qnull();
|
||||
/* No root */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
assert(e->value);
|
||||
return e->value;
|
||||
}
|
||||
|
||||
/* Peek at the top of the stack of QObjects being built.
|
||||
* The stack must not be empty. */
|
||||
static QObject *qmp_output_last(QmpOutputVisitor *qov)
|
||||
{
|
||||
QStackEntry *e = QTAILQ_FIRST(&qov->stack);
|
||||
|
||||
assert(e && e->value);
|
||||
return e->value;
|
||||
}
|
||||
|
||||
/* Add @value to the current QObject being built.
|
||||
* If the stack is visiting a dictionary or list, @value is now owned
|
||||
* by that container. Otherwise, @value is now the root. */
|
||||
static void qmp_output_add_obj(QmpOutputVisitor *qov, const char *name,
|
||||
QObject *value)
|
||||
{
|
||||
QObject *cur;
|
||||
|
||||
if (QTAILQ_EMPTY(&qov->stack)) {
|
||||
/* Stack was empty, track this object as root */
|
||||
qmp_output_push_obj(qov, value);
|
||||
return;
|
||||
}
|
||||
|
@ -98,13 +118,17 @@ static void qmp_output_add_obj(QmpOutputVisitor *qov, const char *name,
|
|||
|
||||
switch (qobject_type(cur)) {
|
||||
case QTYPE_QDICT:
|
||||
assert(name);
|
||||
qdict_put_obj(qobject_to_qdict(cur), name, value);
|
||||
break;
|
||||
case QTYPE_QLIST:
|
||||
qlist_append_obj(qobject_to_qlist(cur), value);
|
||||
break;
|
||||
default:
|
||||
/* The previous root was a scalar, replace it with a new root */
|
||||
/* FIXME this is abusing the stack; see comment above */
|
||||
qobject_decref(qmp_output_pop(qov));
|
||||
assert(QTAILQ_EMPTY(&qov->stack));
|
||||
qmp_output_push_obj(qov, value);
|
||||
break;
|
||||
}
|
||||
|
@ -198,11 +222,14 @@ static void qmp_output_type_any(Visitor *v, QObject **obj, const char *name,
|
|||
qmp_output_add_obj(qov, name, *obj);
|
||||
}
|
||||
|
||||
/* Finish building, and return the root object. Will not be NULL. */
|
||||
QObject *qmp_output_get_qobject(QmpOutputVisitor *qov)
|
||||
{
|
||||
QObject *obj = qmp_output_first(qov);
|
||||
if (obj) {
|
||||
qobject_incref(obj);
|
||||
} else {
|
||||
obj = qnull();
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,8 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
|
|||
" igd-passthru=on|off controls IGD GFX passthrough support (default=off)\n"
|
||||
" aes-key-wrap=on|off controls support for AES key wrapping (default=on)\n"
|
||||
" dea-key-wrap=on|off controls support for DEA key wrapping (default=on)\n"
|
||||
" suppress-vmdesc=on|off disables self-describing migration (default=off)\n",
|
||||
" suppress-vmdesc=on|off disables self-describing migration (default=off)\n"
|
||||
" enforce-config-section=on|off enforce configuration section migration (default=off)\n",
|
||||
QEMU_ARCH_ALL)
|
||||
STEXI
|
||||
@item -machine [type=]@var{name}[,prop=@var{value}[,...]]
|
||||
|
|
|
@ -150,6 +150,7 @@ typedef struct ARMCPU {
|
|||
uint32_t id_mmfr1;
|
||||
uint32_t id_mmfr2;
|
||||
uint32_t id_mmfr3;
|
||||
uint32_t id_mmfr4;
|
||||
uint32_t id_isar0;
|
||||
uint32_t id_isar1;
|
||||
uint32_t id_isar2;
|
||||
|
|
|
@ -4092,12 +4092,14 @@ void register_cp_regs_for_features(ARMCPU *cpu)
|
|||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 5,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = cpu->id_isar5 },
|
||||
/* 6..7 are as yet unallocated and must RAZ */
|
||||
{ .name = "ID_ISAR6", .cp = 15, .crn = 0, .crm = 2,
|
||||
.opc1 = 0, .opc2 = 6, .access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = 0 },
|
||||
{ .name = "ID_ISAR7", .cp = 15, .crn = 0, .crm = 2,
|
||||
.opc1 = 0, .opc2 = 7, .access = PL1_R, .type = ARM_CP_CONST,
|
||||
{ .name = "ID_MMFR4", .state = ARM_CP_STATE_BOTH,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 6,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = cpu->id_mmfr4 },
|
||||
/* 7 is as yet unallocated and must RAZ */
|
||||
{ .name = "ID_ISAR7_RESERVED", .state = ARM_CP_STATE_BOTH,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 7,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = 0 },
|
||||
REGINFO_SENTINEL
|
||||
};
|
||||
|
@ -4151,7 +4153,11 @@ void register_cp_regs_for_features(ARMCPU *cpu)
|
|||
define_arm_cp_regs(cpu, not_v7_cp_reginfo);
|
||||
}
|
||||
if (arm_feature(env, ARM_FEATURE_V8)) {
|
||||
/* AArch64 ID registers, which all have impdef reset values */
|
||||
/* AArch64 ID registers, which all have impdef reset values.
|
||||
* Note that within the ID register ranges the unused slots
|
||||
* must all RAZ, not UNDEF; future architecture versions may
|
||||
* define new registers here.
|
||||
*/
|
||||
ARMCPRegInfo v8_idregs[] = {
|
||||
{ .name = "ID_AA64PFR0_EL1", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 0,
|
||||
|
@ -4161,6 +4167,30 @@ void register_cp_regs_for_features(ARMCPU *cpu)
|
|||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 1,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = cpu->id_aa64pfr1},
|
||||
{ .name = "ID_AA64PFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 2,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = 0 },
|
||||
{ .name = "ID_AA64PFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 3,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = 0 },
|
||||
{ .name = "ID_AA64PFR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 4,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = 0 },
|
||||
{ .name = "ID_AA64PFR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 5,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = 0 },
|
||||
{ .name = "ID_AA64PFR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 6,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = 0 },
|
||||
{ .name = "ID_AA64PFR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 7,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = 0 },
|
||||
{ .name = "ID_AA64DFR0_EL1", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 0,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
|
@ -4174,6 +4204,14 @@ void register_cp_regs_for_features(ARMCPU *cpu)
|
|||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 1,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = cpu->id_aa64dfr1 },
|
||||
{ .name = "ID_AA64DFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 2,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = 0 },
|
||||
{ .name = "ID_AA64DFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 3,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = 0 },
|
||||
{ .name = "ID_AA64AFR0_EL1", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 4,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
|
@ -4182,6 +4220,14 @@ void register_cp_regs_for_features(ARMCPU *cpu)
|
|||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 5,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = cpu->id_aa64afr1 },
|
||||
{ .name = "ID_AA64AFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 6,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = 0 },
|
||||
{ .name = "ID_AA64AFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 7,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = 0 },
|
||||
{ .name = "ID_AA64ISAR0_EL1", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 0,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
|
@ -4190,6 +4236,30 @@ void register_cp_regs_for_features(ARMCPU *cpu)
|
|||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 1,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = cpu->id_aa64isar1 },
|
||||
{ .name = "ID_AA64ISAR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 2,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = 0 },
|
||||
{ .name = "ID_AA64ISAR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 3,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = 0 },
|
||||
{ .name = "ID_AA64ISAR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 4,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = 0 },
|
||||
{ .name = "ID_AA64ISAR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 5,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = 0 },
|
||||
{ .name = "ID_AA64ISAR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 6,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = 0 },
|
||||
{ .name = "ID_AA64ISAR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 7,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = 0 },
|
||||
{ .name = "ID_AA64MMFR0_EL1", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
|
@ -4198,6 +4268,30 @@ void register_cp_regs_for_features(ARMCPU *cpu)
|
|||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 1,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = cpu->id_aa64mmfr1 },
|
||||
{ .name = "ID_AA64MMFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 2,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = 0 },
|
||||
{ .name = "ID_AA64MMFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 3,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = 0 },
|
||||
{ .name = "ID_AA64MMFR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 4,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = 0 },
|
||||
{ .name = "ID_AA64MMFR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 5,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = 0 },
|
||||
{ .name = "ID_AA64MMFR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 6,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = 0 },
|
||||
{ .name = "ID_AA64MMFR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 7,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = 0 },
|
||||
{ .name = "MVFR0_EL1", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 0,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
|
@ -4210,6 +4304,26 @@ void register_cp_regs_for_features(ARMCPU *cpu)
|
|||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 2,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = cpu->mvfr2 },
|
||||
{ .name = "MVFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 3,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = 0 },
|
||||
{ .name = "MVFR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 4,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = 0 },
|
||||
{ .name = "MVFR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 5,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = 0 },
|
||||
{ .name = "MVFR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 6,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = 0 },
|
||||
{ .name = "MVFR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 7,
|
||||
.access = PL1_R, .type = ARM_CP_CONST,
|
||||
.resetvalue = 0 },
|
||||
REGINFO_SENTINEL
|
||||
};
|
||||
/* RVBAR_EL1 is only implemented if EL1 is the highest EL */
|
||||
|
|
|
@ -601,6 +601,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
|
|||
if (cpu->hyperv_crash && has_msr_hv_crash) {
|
||||
c->edx |= HV_X64_GUEST_CRASH_MSR_AVAILABLE;
|
||||
}
|
||||
c->edx |= HV_X64_CPU_DYNAMIC_PARTITIONING_AVAILABLE;
|
||||
if (cpu->hyperv_reset && has_msr_hv_reset) {
|
||||
c->eax |= HV_X64_MSR_RESET_AVAILABLE;
|
||||
}
|
||||
|
|
|
@ -650,8 +650,13 @@ static int kvm_put_fp(CPUState *cs)
|
|||
for (i = 0; i < 32; i++) {
|
||||
uint64_t vsr[2];
|
||||
|
||||
#ifdef HOST_WORDS_BIGENDIAN
|
||||
vsr[0] = float64_val(env->fpr[i]);
|
||||
vsr[1] = env->vsr[i];
|
||||
#else
|
||||
vsr[0] = env->vsr[i];
|
||||
vsr[1] = float64_val(env->fpr[i]);
|
||||
#endif
|
||||
reg.addr = (uintptr_t) &vsr;
|
||||
reg.id = vsx ? KVM_REG_PPC_VSR(i) : KVM_REG_PPC_FPR(i);
|
||||
|
||||
|
@ -721,10 +726,17 @@ static int kvm_get_fp(CPUState *cs)
|
|||
vsx ? "VSR" : "FPR", i, strerror(errno));
|
||||
return ret;
|
||||
} else {
|
||||
#ifdef HOST_WORDS_BIGENDIAN
|
||||
env->fpr[i] = vsr[0];
|
||||
if (vsx) {
|
||||
env->vsr[i] = vsr[1];
|
||||
}
|
||||
#else
|
||||
env->fpr[i] = vsr[1];
|
||||
if (vsx) {
|
||||
env->vsr[i] = vsr[0];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -616,7 +616,8 @@ static void ioinst_handle_chsc_sei(ChscReq *req, ChscResp *res)
|
|||
(*res_flags) &= ~0x80;
|
||||
}
|
||||
} else {
|
||||
res->code = cpu_to_be16(0x0004);
|
||||
res->code = cpu_to_be16(0x0005);
|
||||
res->len = cpu_to_be16(CHSC_MIN_RESP_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
#!/bin/bash
|
||||
# Check live snapshot, followed by active commit, and another snapshot.
|
||||
#
|
||||
# This test is to catch the error case of BZ #1300209:
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1300209
|
||||
#
|
||||
# Copyright (C) 2016 Red Hat, Inc.
|
||||
#
|
||||
# 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/>.
|
||||
#
|
||||
|
||||
# creator
|
||||
owner=jcody@redhat.com
|
||||
|
||||
seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
status=1 # failure is the default!
|
||||
|
||||
TMP_SNAP1=${TEST_DIR}/tmp.qcow2
|
||||
TMP_SNAP2=${TEST_DIR}/tmp2.qcow2
|
||||
|
||||
_cleanup()
|
||||
{
|
||||
_cleanup_qemu
|
||||
rm -f "${TEST_IMG}" "${TMP_SNAP1}" "${TMP_SNAP2}"
|
||||
}
|
||||
|
||||
trap "_cleanup; exit \$status" 0 1 2 3 15
|
||||
|
||||
# get standard environment, filters and checks
|
||||
. ./common.rc
|
||||
. ./common.filter
|
||||
. ./common.qemu
|
||||
|
||||
_supported_fmt qcow2
|
||||
_supported_proto file
|
||||
_supported_os Linux
|
||||
|
||||
size=512M
|
||||
|
||||
_make_test_img $size
|
||||
|
||||
echo
|
||||
echo === Launching QEMU ===
|
||||
echo
|
||||
|
||||
qemu_comm_method="qmp"
|
||||
_launch_qemu -drive file="${TEST_IMG}",if=virtio
|
||||
h=$QEMU_HANDLE
|
||||
|
||||
|
||||
echo
|
||||
echo === Performing Live Snapshot 1 ===
|
||||
echo
|
||||
|
||||
_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" "return"
|
||||
|
||||
|
||||
# First live snapshot, new overlay as active layer
|
||||
_send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot-sync',
|
||||
'arguments': {
|
||||
'device': 'virtio0',
|
||||
'snapshot-file':'${TMP_SNAP1}',
|
||||
'format': 'qcow2'
|
||||
}
|
||||
}" "return"
|
||||
|
||||
echo
|
||||
echo === Performing block-commit on active layer ===
|
||||
echo
|
||||
|
||||
# Block commit on active layer, push the new overlay into base
|
||||
_send_qemu_cmd $h "{ 'execute': 'block-commit',
|
||||
'arguments': {
|
||||
'device': 'virtio0'
|
||||
}
|
||||
}" "READY"
|
||||
|
||||
_send_qemu_cmd $h "{ 'execute': 'block-job-complete',
|
||||
'arguments': {
|
||||
'device': 'virtio0'
|
||||
}
|
||||
}" "COMPLETED"
|
||||
|
||||
echo
|
||||
echo === Performing Live Snapshot 2 ===
|
||||
echo
|
||||
|
||||
# New live snapshot, new overlays as active layer
|
||||
_send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot-sync',
|
||||
'arguments': {
|
||||
'device': 'virtio0',
|
||||
'snapshot-file':'${TMP_SNAP2}',
|
||||
'format': 'qcow2'
|
||||
}
|
||||
}" "return"
|
||||
|
||||
# success, all done
|
||||
echo "*** done"
|
||||
rm -f $seq.full
|
||||
status=0
|
|
@ -0,0 +1,24 @@
|
|||
QA output created by 144
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=536870912
|
||||
|
||||
=== Launching QEMU ===
|
||||
|
||||
|
||||
=== Performing Live Snapshot 1 ===
|
||||
|
||||
{"return": {}}
|
||||
Formatting 'TEST_DIR/tmp.qcow2', fmt=qcow2 size=536870912 backing_file=TEST_DIR/t.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16
|
||||
{"return": {}}
|
||||
|
||||
=== Performing block-commit on active layer ===
|
||||
|
||||
{"return": {}}
|
||||
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "virtio0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
|
||||
{"return": {}}
|
||||
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "virtio0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
|
||||
|
||||
=== Performing Live Snapshot 2 ===
|
||||
|
||||
Formatting 'TEST_DIR/tmp2.qcow2', fmt=qcow2 size=536870912 backing_file=TEST_DIR/t.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16
|
||||
{"return": {}}
|
||||
*** done
|
|
@ -140,3 +140,4 @@
|
|||
137 rw auto
|
||||
138 rw auto quick
|
||||
139 rw auto quick
|
||||
144 rw auto quick
|
||||
|
|
|
@ -461,6 +461,8 @@ static void test_visitor_out_empty(TestOutputVisitorData *data,
|
|||
|
||||
arg = qmp_output_get_qobject(data->qov);
|
||||
g_assert(qobject_type(arg) == QTYPE_QNULL);
|
||||
/* Check that qnull reference counting is sane */
|
||||
g_assert(arg->refcnt == 2);
|
||||
qobject_decref(arg);
|
||||
}
|
||||
|
||||
|
|
|
@ -57,12 +57,13 @@ struct QEMUPutLEDEntry {
|
|||
static QTAILQ_HEAD(, QEMUPutLEDEntry) led_handlers =
|
||||
QTAILQ_HEAD_INITIALIZER(led_handlers);
|
||||
|
||||
int index_from_key(const char *key)
|
||||
int index_from_key(const char *key, size_t key_length)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; QKeyCode_lookup[i] != NULL; i++) {
|
||||
if (!strcmp(key, QKeyCode_lookup[i])) {
|
||||
if (!strncmp(key, QKeyCode_lookup[i], key_length) &&
|
||||
!QKeyCode_lookup[i][key_length]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
37
vl.c
37
vl.c
|
@ -2757,6 +2757,31 @@ static const QEMUOption *lookup_opt(int argc, char **argv,
|
|||
return popt;
|
||||
}
|
||||
|
||||
static void set_machine_options(MachineClass **machine_class)
|
||||
{
|
||||
const char *optarg;
|
||||
QemuOpts *opts;
|
||||
Location loc;
|
||||
|
||||
loc_push_none(&loc);
|
||||
|
||||
opts = qemu_get_machine_opts();
|
||||
qemu_opts_loc_restore(opts);
|
||||
|
||||
optarg = qemu_opt_get(opts, "type");
|
||||
if (optarg) {
|
||||
*machine_class = machine_parse(optarg);
|
||||
}
|
||||
|
||||
if (*machine_class == NULL) {
|
||||
error_report("No machine specified, and there is no default");
|
||||
error_printf("Use -machine help to list supported machines\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
loc_pop(&loc);
|
||||
}
|
||||
|
||||
static int machine_set_property(void *opaque,
|
||||
const char *name, const char *value,
|
||||
Error **errp)
|
||||
|
@ -4025,17 +4050,7 @@ int main(int argc, char **argv, char **envp)
|
|||
|
||||
replay_configure(icount_opts);
|
||||
|
||||
opts = qemu_get_machine_opts();
|
||||
optarg = qemu_opt_get(opts, "type");
|
||||
if (optarg) {
|
||||
machine_class = machine_parse(optarg);
|
||||
}
|
||||
|
||||
if (machine_class == NULL) {
|
||||
error_report("No machine specified, and there is no default");
|
||||
error_printf("Use -machine help to list supported machines\n");
|
||||
exit(1);
|
||||
}
|
||||
set_machine_options(&machine_class);
|
||||
|
||||
set_memory_options(&ram_slots, &maxram_size, machine_class);
|
||||
|
||||
|
|
Loading…
Reference in New Issue