Compare commits
79 Commits
v2.1.0-rc2
...
v2.1.0
Author | SHA1 | Date | |
---|---|---|---|
|
541bbb07eb | ||
|
d24e780427 | ||
|
1373e140f0 | ||
|
8a2ca741ab | ||
|
1d80eb7a68 | ||
|
41892faf89 | ||
|
04d1d6613f | ||
|
f47337cb91 | ||
|
868270f23d | ||
|
18045fb9f4 | ||
|
093a35e5fc | ||
|
133a2da488 | ||
|
cb348985ab | ||
|
41a1a9c42c | ||
|
62eb3b9a34 | ||
|
07fb61760c | ||
|
acd727e7cb | ||
|
f45c56e016 | ||
|
2f47b403bd | ||
|
c60a57ff49 | ||
|
62c339c527 | ||
|
7f0b2ff724 | ||
|
6365828003 | ||
|
07535a8902 | ||
|
3b25748663 | ||
|
032baddea3 | ||
|
db52658b38 | ||
|
5e255004f5 | ||
|
f8ecd94501 | ||
|
1454ac68af | ||
|
a537d373b9 | ||
|
cf679caf91 | ||
|
f368c33d5a | ||
|
ef493d5c29 | ||
|
3afca1d6d4 | ||
|
3a18d44983 | ||
|
e206ad4833 | ||
|
b64c670f1d | ||
|
713e8a1022 | ||
|
25af8e6b61 | ||
|
dc54e25253 | ||
|
6886867e98 | ||
|
35858955e6 | ||
|
b0ddb8bf6b | ||
|
147fc41973 | ||
|
50a2c45da9 | ||
|
748bfb4eee | ||
|
7a46d042e0 | ||
|
13a439ec40 | ||
|
b9b45b4a88 | ||
|
37cbfcce14 | ||
|
b847ae2d60 | ||
|
a9dd38db68 | ||
|
b739ef05db | ||
|
fa666c10f2 | ||
|
108e4c3871 | ||
|
bb2eb1892d | ||
|
f9e13f8fd8 | ||
|
f52b768782 | ||
|
e0097ea371 | ||
|
8283c5c316 | ||
|
df26a35025 | ||
|
3baca89139 | ||
|
12ac6d3db7 | ||
|
4d121a5498 | ||
|
cd98639f67 | ||
|
d6970e3b00 | ||
|
f69a28051f | ||
|
5734d031aa | ||
|
af52fe862f | ||
|
231f6927c8 | ||
|
104369c8c7 | ||
|
57d84cf353 | ||
|
79fe16c048 | ||
|
b4bda1ae57 | ||
|
0e3cd8334a | ||
|
75902802c2 | ||
|
faab459797 | ||
|
4ec6ee5ace |
@@ -861,7 +861,7 @@ static bool block_is_active(void *opaque)
|
||||
return block_mig_state.blk_enable == 1;
|
||||
}
|
||||
|
||||
SaveVMHandlers savevm_block_handlers = {
|
||||
static SaveVMHandlers savevm_block_handlers = {
|
||||
.set_params = block_set_params,
|
||||
.save_live_setup = block_save_setup,
|
||||
.save_live_iterate = block_save_iterate,
|
||||
|
33
block.c
33
block.c
@@ -508,19 +508,24 @@ int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int bdrv_refresh_limits(BlockDriverState *bs)
|
||||
void bdrv_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||
{
|
||||
BlockDriver *drv = bs->drv;
|
||||
Error *local_err = NULL;
|
||||
|
||||
memset(&bs->bl, 0, sizeof(bs->bl));
|
||||
|
||||
if (!drv) {
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Take some limits from the children as a default */
|
||||
if (bs->file) {
|
||||
bdrv_refresh_limits(bs->file);
|
||||
bdrv_refresh_limits(bs->file, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
bs->bl.opt_transfer_length = bs->file->bl.opt_transfer_length;
|
||||
bs->bl.opt_mem_alignment = bs->file->bl.opt_mem_alignment;
|
||||
} else {
|
||||
@@ -528,7 +533,11 @@ int bdrv_refresh_limits(BlockDriverState *bs)
|
||||
}
|
||||
|
||||
if (bs->backing_hd) {
|
||||
bdrv_refresh_limits(bs->backing_hd);
|
||||
bdrv_refresh_limits(bs->backing_hd, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
bs->bl.opt_transfer_length =
|
||||
MAX(bs->bl.opt_transfer_length,
|
||||
bs->backing_hd->bl.opt_transfer_length);
|
||||
@@ -539,10 +548,8 @@ int bdrv_refresh_limits(BlockDriverState *bs)
|
||||
|
||||
/* Then let the driver override it */
|
||||
if (drv->bdrv_refresh_limits) {
|
||||
return drv->bdrv_refresh_limits(bs);
|
||||
drv->bdrv_refresh_limits(bs, errp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -993,7 +1000,13 @@ static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file,
|
||||
goto free_and_fail;
|
||||
}
|
||||
|
||||
bdrv_refresh_limits(bs);
|
||||
bdrv_refresh_limits(bs, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
ret = -EINVAL;
|
||||
goto free_and_fail;
|
||||
}
|
||||
|
||||
assert(bdrv_opt_mem_align(bs) != 0);
|
||||
assert((bs->request_alignment != 0) || bs->sg);
|
||||
return 0;
|
||||
@@ -1154,7 +1167,7 @@ void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd)
|
||||
bdrv_op_unblock(bs->backing_hd, BLOCK_OP_TYPE_COMMIT,
|
||||
bs->backing_blocker);
|
||||
out:
|
||||
bdrv_refresh_limits(bs);
|
||||
bdrv_refresh_limits(bs, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1778,7 +1791,7 @@ void bdrv_reopen_commit(BDRVReopenState *reopen_state)
|
||||
BDRV_O_CACHE_WB);
|
||||
reopen_state->bs->read_only = !(reopen_state->flags & BDRV_O_RDWR);
|
||||
|
||||
bdrv_refresh_limits(reopen_state->bs);
|
||||
bdrv_refresh_limits(reopen_state->bs, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -1450,7 +1450,7 @@ static void iscsi_close(BlockDriverState *bs)
|
||||
memset(iscsilun, 0, sizeof(IscsiLun));
|
||||
}
|
||||
|
||||
static int iscsi_refresh_limits(BlockDriverState *bs)
|
||||
static void iscsi_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||
{
|
||||
IscsiLun *iscsilun = bs->opaque;
|
||||
|
||||
@@ -1475,7 +1475,6 @@ static int iscsi_refresh_limits(BlockDriverState *bs)
|
||||
}
|
||||
bs->bl.opt_transfer_length = sector_lun2qemu(iscsilun->bl.opt_xfer_len,
|
||||
iscsilun);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Since iscsi_open() ignores bdrv_flags, there is nothing to do here in
|
||||
|
@@ -210,20 +210,31 @@ static void GCC_FMT_ATTR(3, 4) report_unsupported(BlockDriverState *bs,
|
||||
static void report_unsupported_feature(BlockDriverState *bs,
|
||||
Error **errp, Qcow2Feature *table, uint64_t mask)
|
||||
{
|
||||
char *features = g_strdup("");
|
||||
char *old;
|
||||
|
||||
while (table && table->name[0] != '\0') {
|
||||
if (table->type == QCOW2_FEAT_TYPE_INCOMPATIBLE) {
|
||||
if (mask & (1 << table->bit)) {
|
||||
report_unsupported(bs, errp, "%.46s", table->name);
|
||||
mask &= ~(1 << table->bit);
|
||||
if (mask & (1ULL << table->bit)) {
|
||||
old = features;
|
||||
features = g_strdup_printf("%s%s%.46s", old, *old ? ", " : "",
|
||||
table->name);
|
||||
g_free(old);
|
||||
mask &= ~(1ULL << table->bit);
|
||||
}
|
||||
}
|
||||
table++;
|
||||
}
|
||||
|
||||
if (mask) {
|
||||
report_unsupported(bs, errp, "Unknown incompatible feature: %" PRIx64,
|
||||
mask);
|
||||
old = features;
|
||||
features = g_strdup_printf("%s%sUnknown incompatible feature: %" PRIx64,
|
||||
old, *old ? ", " : "", mask);
|
||||
g_free(old);
|
||||
}
|
||||
|
||||
report_unsupported(bs, errp, "%s", features);
|
||||
g_free(features);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -855,13 +866,11 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int qcow2_refresh_limits(BlockDriverState *bs)
|
||||
static void qcow2_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||
{
|
||||
BDRVQcowState *s = bs->opaque;
|
||||
|
||||
bs->bl.write_zeroes_alignment = s->cluster_sectors;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qcow2_set_key(BlockDriverState *bs, const char *key)
|
||||
|
@@ -528,13 +528,11 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bdrv_qed_refresh_limits(BlockDriverState *bs)
|
||||
static void bdrv_qed_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||
{
|
||||
BDRVQEDState *s = bs->opaque;
|
||||
|
||||
bs->bl.write_zeroes_alignment = s->header.cluster_size >> BDRV_SECTOR_BITS;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We have nothing to do for QED reopen, stubs just return
|
||||
|
@@ -221,7 +221,7 @@ static int raw_normalize_devicepath(const char **filename)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void raw_probe_alignment(BlockDriverState *bs)
|
||||
static void raw_probe_alignment(BlockDriverState *bs, int fd, Error **errp)
|
||||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
char *buf;
|
||||
@@ -240,24 +240,24 @@ static void raw_probe_alignment(BlockDriverState *bs)
|
||||
s->buf_align = 0;
|
||||
|
||||
#ifdef BLKSSZGET
|
||||
if (ioctl(s->fd, BLKSSZGET, §or_size) >= 0) {
|
||||
if (ioctl(fd, BLKSSZGET, §or_size) >= 0) {
|
||||
bs->request_alignment = sector_size;
|
||||
}
|
||||
#endif
|
||||
#ifdef DKIOCGETBLOCKSIZE
|
||||
if (ioctl(s->fd, DKIOCGETBLOCKSIZE, §or_size) >= 0) {
|
||||
if (ioctl(fd, DKIOCGETBLOCKSIZE, §or_size) >= 0) {
|
||||
bs->request_alignment = sector_size;
|
||||
}
|
||||
#endif
|
||||
#ifdef DIOCGSECTORSIZE
|
||||
if (ioctl(s->fd, DIOCGSECTORSIZE, §or_size) >= 0) {
|
||||
if (ioctl(fd, DIOCGSECTORSIZE, §or_size) >= 0) {
|
||||
bs->request_alignment = sector_size;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_XFS
|
||||
if (s->is_xfs) {
|
||||
struct dioattr da;
|
||||
if (xfsctl(NULL, s->fd, XFS_IOC_DIOINFO, &da) >= 0) {
|
||||
if (xfsctl(NULL, fd, XFS_IOC_DIOINFO, &da) >= 0) {
|
||||
bs->request_alignment = da.d_miniosz;
|
||||
/* The kernel returns wrong information for d_mem */
|
||||
/* s->buf_align = da.d_mem; */
|
||||
@@ -270,7 +270,7 @@ static void raw_probe_alignment(BlockDriverState *bs)
|
||||
size_t align;
|
||||
buf = qemu_memalign(MAX_BLOCKSIZE, 2 * MAX_BLOCKSIZE);
|
||||
for (align = 512; align <= MAX_BLOCKSIZE; align <<= 1) {
|
||||
if (pread(s->fd, buf + align, MAX_BLOCKSIZE, 0) >= 0) {
|
||||
if (pread(fd, buf + align, MAX_BLOCKSIZE, 0) >= 0) {
|
||||
s->buf_align = align;
|
||||
break;
|
||||
}
|
||||
@@ -282,13 +282,18 @@ static void raw_probe_alignment(BlockDriverState *bs)
|
||||
size_t align;
|
||||
buf = qemu_memalign(s->buf_align, MAX_BLOCKSIZE);
|
||||
for (align = 512; align <= MAX_BLOCKSIZE; align <<= 1) {
|
||||
if (pread(s->fd, buf, align, 0) >= 0) {
|
||||
if (pread(fd, buf, align, 0) >= 0) {
|
||||
bs->request_alignment = align;
|
||||
break;
|
||||
}
|
||||
}
|
||||
qemu_vfree(buf);
|
||||
}
|
||||
|
||||
if (!s->buf_align || !bs->request_alignment) {
|
||||
error_setg(errp, "Could not find working O_DIRECT alignment. "
|
||||
"Try cache.direct=off.");
|
||||
}
|
||||
}
|
||||
|
||||
static void raw_parse_flags(int bdrv_flags, int *open_flags)
|
||||
@@ -505,6 +510,7 @@ static int raw_reopen_prepare(BDRVReopenState *state,
|
||||
BDRVRawState *s;
|
||||
BDRVRawReopenState *raw_s;
|
||||
int ret = 0;
|
||||
Error *local_err = NULL;
|
||||
|
||||
assert(state != NULL);
|
||||
assert(state->bs != NULL);
|
||||
@@ -577,6 +583,19 @@ static int raw_reopen_prepare(BDRVReopenState *state,
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fail already reopen_prepare() if we can't get a working O_DIRECT
|
||||
* alignment with the new fd. */
|
||||
if (raw_s->fd != -1) {
|
||||
raw_probe_alignment(state->bs, raw_s->fd, &local_err);
|
||||
if (local_err) {
|
||||
qemu_close(raw_s->fd);
|
||||
raw_s->fd = -1;
|
||||
error_propagate(errp, local_err);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -615,14 +634,12 @@ static void raw_reopen_abort(BDRVReopenState *state)
|
||||
state->opaque = NULL;
|
||||
}
|
||||
|
||||
static int raw_refresh_limits(BlockDriverState *bs)
|
||||
static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
|
||||
raw_probe_alignment(bs);
|
||||
raw_probe_alignment(bs, s->fd, errp);
|
||||
bs->bl.opt_mem_alignment = s->buf_align;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t handle_aiocb_ioctl(RawPosixAIOData *aiocb)
|
||||
|
@@ -94,10 +94,9 @@ static int raw_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||
return bdrv_get_info(bs->file, bdi);
|
||||
}
|
||||
|
||||
static int raw_refresh_limits(BlockDriverState *bs)
|
||||
static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||
{
|
||||
bs->bl = bs->file->bl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int raw_truncate(BlockDriverState *bs, int64_t offset)
|
||||
|
@@ -76,7 +76,7 @@ static void close_unused_images(BlockDriverState *top, BlockDriverState *base,
|
||||
bdrv_unref(unused);
|
||||
}
|
||||
|
||||
bdrv_refresh_limits(top);
|
||||
bdrv_refresh_limits(top, NULL);
|
||||
}
|
||||
|
||||
static void coroutine_fn stream_run(void *opaque)
|
||||
|
@@ -938,7 +938,7 @@ fail:
|
||||
}
|
||||
|
||||
|
||||
static int vmdk_refresh_limits(BlockDriverState *bs)
|
||||
static void vmdk_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||
{
|
||||
BDRVVmdkState *s = bs->opaque;
|
||||
int i;
|
||||
@@ -950,8 +950,6 @@ static int vmdk_refresh_limits(BlockDriverState *bs)
|
||||
s->extents[i].cluster_sectors);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_whole_cluster(BlockDriverState *bs,
|
||||
|
@@ -243,6 +243,19 @@ Data:
|
||||
"timestamp": { "seconds": 1368697518, "microseconds": 326866 } }
|
||||
}
|
||||
|
||||
POWERDOWN
|
||||
---------
|
||||
|
||||
Emitted when the Virtual Machine is powered down through the power
|
||||
control system, such as via ACPI.
|
||||
|
||||
Data: None.
|
||||
|
||||
Example:
|
||||
|
||||
{ "event": "POWERDOWN",
|
||||
"timestamp": { "seconds": 1267040730, "microseconds": 682951 } }
|
||||
|
||||
QUORUM_FAILURE
|
||||
--------------
|
||||
|
||||
@@ -285,7 +298,7 @@ Example:
|
||||
RESET
|
||||
-----
|
||||
|
||||
Emitted when the Virtual Machine is reseted.
|
||||
Emitted when the Virtual Machine is reset.
|
||||
|
||||
Data: None.
|
||||
|
||||
@@ -325,7 +338,8 @@ Example:
|
||||
SHUTDOWN
|
||||
--------
|
||||
|
||||
Emitted when the Virtual Machine is powered down.
|
||||
Emitted when the Virtual Machine has shut down, indicating that qemu
|
||||
is about to exit.
|
||||
|
||||
Data: None.
|
||||
|
||||
@@ -337,10 +351,10 @@ Example:
|
||||
Note: If the command-line option "-no-shutdown" has been specified, a STOP
|
||||
event will eventually follow the SHUTDOWN event.
|
||||
|
||||
SPICE_CONNECTED, SPICE_DISCONNECTED
|
||||
-----------------------------------
|
||||
SPICE_CONNECTED
|
||||
---------------
|
||||
|
||||
Emitted when a SPICE client connects or disconnects.
|
||||
Emitted when a SPICE client connects.
|
||||
|
||||
Data:
|
||||
|
||||
@@ -362,11 +376,36 @@ Example:
|
||||
"client": {"port": "52873", "family": "ipv4", "host": "127.0.0.1"}
|
||||
}}
|
||||
|
||||
SPICE_DISCONNECTED
|
||||
------------------
|
||||
|
||||
Emitted when a SPICE client disconnects.
|
||||
|
||||
Data:
|
||||
|
||||
- "server": Server information (json-object)
|
||||
- "host": IP address (json-string)
|
||||
- "port": port number (json-string)
|
||||
- "family": address family (json-string, "ipv4" or "ipv6")
|
||||
- "client": Client information (json-object)
|
||||
- "host": IP address (json-string)
|
||||
- "port": port number (json-string)
|
||||
- "family": address family (json-string, "ipv4" or "ipv6")
|
||||
|
||||
Example:
|
||||
|
||||
{ "timestamp": {"seconds": 1290688046, "microseconds": 388707},
|
||||
"event": "SPICE_DISCONNECTED",
|
||||
"data": {
|
||||
"server": { "port": "5920", "family": "ipv4", "host": "127.0.0.1"},
|
||||
"client": {"port": "52873", "family": "ipv4", "host": "127.0.0.1"}
|
||||
}}
|
||||
|
||||
SPICE_INITIALIZED
|
||||
-----------------
|
||||
|
||||
Emitted after initial handshake and authentication takes place (if any)
|
||||
and the SPICE channel is up'n'running
|
||||
and the SPICE channel is up and running
|
||||
|
||||
Data:
|
||||
|
||||
@@ -399,6 +438,19 @@ Example:
|
||||
"channel-id": 0, "tls": true}
|
||||
}}
|
||||
|
||||
SPICE_MIGRATE_COMPLETED
|
||||
-----------------------
|
||||
|
||||
Emitted when SPICE migration has completed
|
||||
|
||||
Data: None.
|
||||
|
||||
Example:
|
||||
|
||||
{ "timestamp": {"seconds": 1290688046, "microseconds": 417172},
|
||||
"event": "SPICE_MIGRATE_COMPLETED" }
|
||||
|
||||
|
||||
STOP
|
||||
----
|
||||
|
||||
@@ -527,6 +579,22 @@ Example:
|
||||
"host": "127.0.0.1", "sasl_username": "luiz" } },
|
||||
"timestamp": { "seconds": 1263475302, "microseconds": 150772 } }
|
||||
|
||||
VSERPORT_CHANGE
|
||||
---------------
|
||||
|
||||
Emitted when the guest opens or closes a virtio-serial port.
|
||||
|
||||
Data:
|
||||
|
||||
- "id": device identifier of the virtio-serial port (json-string)
|
||||
- "open": true if the guest has opened the virtio-serial port (json-bool)
|
||||
|
||||
Example:
|
||||
|
||||
{ "event": "VSERPORT_CHANGE",
|
||||
"data": { "id": "channel0", "open": true },
|
||||
"timestamp": { "seconds": 1401385907, "microseconds": 422329 } }
|
||||
|
||||
WAKEUP
|
||||
------
|
||||
|
||||
|
20
exec.c
20
exec.c
@@ -1568,8 +1568,7 @@ static void notdirty_mem_write(void *opaque, hwaddr ram_addr,
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
cpu_physical_memory_set_dirty_flag(ram_addr, DIRTY_MEMORY_MIGRATION);
|
||||
cpu_physical_memory_set_dirty_flag(ram_addr, DIRTY_MEMORY_VGA);
|
||||
cpu_physical_memory_set_dirty_range_nocode(ram_addr, size);
|
||||
/* we remove the notdirty callback only if the code has been
|
||||
flushed */
|
||||
if (!cpu_physical_memory_is_clean(ram_addr)) {
|
||||
@@ -1978,8 +1977,7 @@ static void invalidate_and_set_dirty(hwaddr addr,
|
||||
/* invalidate code */
|
||||
tb_invalidate_phys_page_range(addr, addr + length, 0);
|
||||
/* set dirty bit */
|
||||
cpu_physical_memory_set_dirty_flag(addr, DIRTY_MEMORY_VGA);
|
||||
cpu_physical_memory_set_dirty_flag(addr, DIRTY_MEMORY_MIGRATION);
|
||||
cpu_physical_memory_set_dirty_range_nocode(addr, length);
|
||||
}
|
||||
xen_modified_memory(addr, length);
|
||||
}
|
||||
@@ -2335,15 +2333,7 @@ void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len,
|
||||
mr = qemu_ram_addr_from_host(buffer, &addr1);
|
||||
assert(mr != NULL);
|
||||
if (is_write) {
|
||||
while (access_len) {
|
||||
unsigned l;
|
||||
l = TARGET_PAGE_SIZE;
|
||||
if (l > access_len)
|
||||
l = access_len;
|
||||
invalidate_and_set_dirty(addr1, l);
|
||||
addr1 += l;
|
||||
access_len -= l;
|
||||
}
|
||||
invalidate_and_set_dirty(addr1, access_len);
|
||||
}
|
||||
if (xen_enabled()) {
|
||||
xen_invalidate_map_cache_entry(buffer);
|
||||
@@ -2581,9 +2571,7 @@ void stl_phys_notdirty(AddressSpace *as, hwaddr addr, uint32_t val)
|
||||
/* invalidate code */
|
||||
tb_invalidate_phys_page_range(addr1, addr1 + 4, 0);
|
||||
/* set dirty bit */
|
||||
cpu_physical_memory_set_dirty_flag(addr1,
|
||||
DIRTY_MEMORY_MIGRATION);
|
||||
cpu_physical_memory_set_dirty_flag(addr1, DIRTY_MEMORY_VGA);
|
||||
cpu_physical_memory_set_dirty_range_nocode(addr1, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -232,11 +232,11 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
|
||||
|
||||
acpi_gpe_init(&pm->acpi_regs, ICH9_PMIO_GPE0_LEN);
|
||||
memory_region_init_io(&pm->io_gpe, OBJECT(lpc_pci), &ich9_gpe_ops, pm,
|
||||
"apci-gpe0", ICH9_PMIO_GPE0_LEN);
|
||||
"acpi-gpe0", ICH9_PMIO_GPE0_LEN);
|
||||
memory_region_add_subregion(&pm->io, ICH9_PMIO_GPE0_STS, &pm->io_gpe);
|
||||
|
||||
memory_region_init_io(&pm->io_smi, OBJECT(lpc_pci), &ich9_smi_ops, pm,
|
||||
"apci-smi", 8);
|
||||
"acpi-smi", 8);
|
||||
memory_region_add_subregion(&pm->io, ICH9_PMIO_SMI_EN, &pm->io_smi);
|
||||
|
||||
pm->irq = sci_irq;
|
||||
|
@@ -104,7 +104,7 @@ static const MemMapEntry a15memmap[] = {
|
||||
[VIRT_GIC_DIST] = { 0x8000000, 0x10000 },
|
||||
[VIRT_GIC_CPU] = { 0x8010000, 0x10000 },
|
||||
[VIRT_UART] = { 0x9000000, 0x1000 },
|
||||
[VIRT_RTC] = { 0x90010000, 0x1000 },
|
||||
[VIRT_RTC] = { 0x9010000, 0x1000 },
|
||||
[VIRT_MMIO] = { 0xa000000, 0x200 },
|
||||
/* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
|
||||
/* 0x10000000 .. 0x40000000 reserved for PCI */
|
||||
|
@@ -175,8 +175,10 @@ static void uart_send_breaks(UartState *s)
|
||||
{
|
||||
int break_enabled = 1;
|
||||
|
||||
qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_BREAK,
|
||||
&break_enabled);
|
||||
if (s->chr) {
|
||||
qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_BREAK,
|
||||
&break_enabled);
|
||||
}
|
||||
}
|
||||
|
||||
static void uart_parameters_setup(UartState *s)
|
||||
@@ -227,7 +229,9 @@ static void uart_parameters_setup(UartState *s)
|
||||
|
||||
packet_size += ssp.data_bits + ssp.stop_bits;
|
||||
s->char_tx_time = (get_ticks_per_sec() / ssp.speed) * packet_size;
|
||||
qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
|
||||
if (s->chr) {
|
||||
qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
|
||||
}
|
||||
}
|
||||
|
||||
static int uart_can_receive(void *opaque)
|
||||
@@ -295,6 +299,7 @@ static gboolean cadence_uart_xmit(GIOChannel *chan, GIOCondition cond,
|
||||
/* instant drain the fifo when there's no back-end */
|
||||
if (!s->chr) {
|
||||
s->tx_count = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!s->tx_count) {
|
||||
@@ -375,7 +380,9 @@ static void uart_read_rx_fifo(UartState *s, uint32_t *c)
|
||||
*c = s->rx_fifo[rx_rpos];
|
||||
s->rx_count--;
|
||||
|
||||
qemu_chr_accept_input(s->chr);
|
||||
if (s->chr) {
|
||||
qemu_chr_accept_input(s->chr);
|
||||
}
|
||||
} else {
|
||||
*c = 0;
|
||||
}
|
||||
|
@@ -797,10 +797,18 @@ static void add_port(VirtIOSerial *vser, uint32_t port_id)
|
||||
static void remove_port(VirtIOSerial *vser, uint32_t port_id)
|
||||
{
|
||||
VirtIOSerialPort *port;
|
||||
unsigned int i;
|
||||
|
||||
i = port_id / 32;
|
||||
vser->ports_map[i] &= ~(1U << (port_id % 32));
|
||||
/*
|
||||
* Don't mark port 0 removed -- we explicitly reserve it for
|
||||
* backward compat with older guests, ensure a virtconsole device
|
||||
* unplug retains the reservation.
|
||||
*/
|
||||
if (port_id) {
|
||||
unsigned int i;
|
||||
|
||||
i = port_id / 32;
|
||||
vser->ports_map[i] &= ~(1U << (port_id % 32));
|
||||
}
|
||||
|
||||
port = find_port_by_id(vser, port_id);
|
||||
/*
|
||||
|
@@ -239,11 +239,11 @@ static void machine_initfn(Object *obj)
|
||||
{
|
||||
object_property_add_str(obj, "accel",
|
||||
machine_get_accel, machine_set_accel, NULL);
|
||||
object_property_add_bool(obj, "kernel_irqchip",
|
||||
object_property_add_bool(obj, "kernel-irqchip",
|
||||
machine_get_kernel_irqchip,
|
||||
machine_set_kernel_irqchip,
|
||||
NULL);
|
||||
object_property_add(obj, "kvm_shadow_mem", "int",
|
||||
object_property_add(obj, "kvm-shadow-mem", "int",
|
||||
machine_get_kvm_shadow_mem,
|
||||
machine_set_kvm_shadow_mem,
|
||||
NULL, NULL, NULL);
|
||||
@@ -257,11 +257,11 @@ static void machine_initfn(Object *obj)
|
||||
machine_get_dtb, machine_set_dtb, NULL);
|
||||
object_property_add_str(obj, "dumpdtb",
|
||||
machine_get_dumpdtb, machine_set_dumpdtb, NULL);
|
||||
object_property_add(obj, "phandle_start", "int",
|
||||
object_property_add(obj, "phandle-start", "int",
|
||||
machine_get_phandle_start,
|
||||
machine_set_phandle_start,
|
||||
NULL, NULL, NULL);
|
||||
object_property_add_str(obj, "dt_compatible",
|
||||
object_property_add_str(obj, "dt-compatible",
|
||||
machine_get_dt_compatible,
|
||||
machine_set_dt_compatible,
|
||||
NULL);
|
||||
|
@@ -25,7 +25,9 @@
|
||||
#include <glib.h>
|
||||
#include "qemu-common.h"
|
||||
#include "qemu/bitmap.h"
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/range.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "hw/pci/pci.h"
|
||||
#include "qom/cpu.h"
|
||||
#include "hw/i386/pc.h"
|
||||
@@ -52,6 +54,16 @@
|
||||
#include "qapi/qmp/qint.h"
|
||||
#include "qom/qom-qobject.h"
|
||||
|
||||
/* These are used to size the ACPI tables for -M pc-i440fx-1.7 and
|
||||
* -M pc-i440fx-2.0. Even if the actual amount of AML generated grows
|
||||
* a little bit, there should be plenty of free space since the DSDT
|
||||
* shrunk by ~1.5k between QEMU 2.0 and QEMU 2.1.
|
||||
*/
|
||||
#define ACPI_BUILD_LEGACY_CPU_AML_SIZE 97
|
||||
#define ACPI_BUILD_ALIGN_SIZE 0x1000
|
||||
|
||||
#define ACPI_BUILD_TABLE_SIZE 0x20000
|
||||
|
||||
typedef struct AcpiCpuInfo {
|
||||
DECLARE_BITMAP(found_cpus, ACPI_CPU_HOTPLUG_ID_LIMIT);
|
||||
} AcpiCpuInfo;
|
||||
@@ -64,6 +76,7 @@ typedef struct AcpiMcfgInfo {
|
||||
typedef struct AcpiPmInfo {
|
||||
bool s3_disabled;
|
||||
bool s4_disabled;
|
||||
bool pcihp_bridge_en;
|
||||
uint8_t s4_val;
|
||||
uint16_t sci_int;
|
||||
uint8_t acpi_enable_cmd;
|
||||
@@ -85,6 +98,7 @@ typedef struct AcpiBuildPciBusHotplugState {
|
||||
GArray *device_table;
|
||||
GArray *notify_table;
|
||||
struct AcpiBuildPciBusHotplugState *parent;
|
||||
bool pcihp_bridge_en;
|
||||
} AcpiBuildPciBusHotplugState;
|
||||
|
||||
static void acpi_get_dsdt(AcpiMiscInfo *info)
|
||||
@@ -188,6 +202,9 @@ static void acpi_get_pm_info(AcpiPmInfo *pm)
|
||||
NULL);
|
||||
pm->gpe0_blk_len = object_property_get_int(obj, ACPI_PM_PROP_GPE0_BLK_LEN,
|
||||
NULL);
|
||||
pm->pcihp_bridge_en =
|
||||
object_property_get_bool(obj, "acpi-pci-hotplug-with-bridge-support",
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void acpi_get_misc_info(AcpiMiscInfo *info)
|
||||
@@ -768,11 +785,13 @@ static void acpi_set_pci_info(void)
|
||||
}
|
||||
|
||||
static void build_pci_bus_state_init(AcpiBuildPciBusHotplugState *state,
|
||||
AcpiBuildPciBusHotplugState *parent)
|
||||
AcpiBuildPciBusHotplugState *parent,
|
||||
bool pcihp_bridge_en)
|
||||
{
|
||||
state->parent = parent;
|
||||
state->device_table = build_alloc_array();
|
||||
state->notify_table = build_alloc_array();
|
||||
state->pcihp_bridge_en = pcihp_bridge_en;
|
||||
}
|
||||
|
||||
static void build_pci_bus_state_cleanup(AcpiBuildPciBusHotplugState *state)
|
||||
@@ -786,7 +805,7 @@ static void *build_pci_bus_begin(PCIBus *bus, void *parent_state)
|
||||
AcpiBuildPciBusHotplugState *parent = parent_state;
|
||||
AcpiBuildPciBusHotplugState *child = g_malloc(sizeof *child);
|
||||
|
||||
build_pci_bus_state_init(child, parent);
|
||||
build_pci_bus_state_init(child, parent, parent->pcihp_bridge_en);
|
||||
|
||||
return child;
|
||||
}
|
||||
@@ -807,6 +826,14 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state)
|
||||
GArray *method;
|
||||
bool bus_hotplug_support = false;
|
||||
|
||||
/*
|
||||
* Skip bridge subtree creation if bridge hotplug is disabled
|
||||
* to make acpi tables compatible with legacy machine types.
|
||||
*/
|
||||
if (!child->pcihp_bridge_en && bus->parent_dev) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (bus->parent_dev) {
|
||||
op = 0x82; /* DeviceOp */
|
||||
build_append_nameseg(bus_table, "S%.02X_",
|
||||
@@ -844,6 +871,7 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state)
|
||||
PCIDeviceClass *pc;
|
||||
PCIDevice *pdev = bus->devices[i];
|
||||
int slot = PCI_SLOT(i);
|
||||
bool bridge_in_acpi;
|
||||
|
||||
if (!pdev) {
|
||||
continue;
|
||||
@@ -853,7 +881,13 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state)
|
||||
pc = PCI_DEVICE_GET_CLASS(pdev);
|
||||
dc = DEVICE_GET_CLASS(pdev);
|
||||
|
||||
if (pc->class_id == PCI_CLASS_BRIDGE_ISA || pc->is_bridge) {
|
||||
/* When hotplug for bridges is enabled, bridges are
|
||||
* described in ACPI separately (see build_pci_bus_end).
|
||||
* In this case they aren't themselves hot-pluggable.
|
||||
*/
|
||||
bridge_in_acpi = pc->is_bridge && child->pcihp_bridge_en;
|
||||
|
||||
if (pc->class_id == PCI_CLASS_BRIDGE_ISA || bridge_in_acpi) {
|
||||
set_bit(slot, slot_device_system);
|
||||
}
|
||||
|
||||
@@ -865,7 +899,7 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state)
|
||||
}
|
||||
}
|
||||
|
||||
if (!dc->hotpluggable || pc->is_bridge) {
|
||||
if (!dc->hotpluggable || bridge_in_acpi) {
|
||||
clear_bit(slot, slot_hotplug_enable);
|
||||
}
|
||||
}
|
||||
@@ -1130,7 +1164,7 @@ build_ssdt(GArray *table_data, GArray *linker,
|
||||
bus = PCI_HOST_BRIDGE(pci_host)->bus;
|
||||
}
|
||||
|
||||
build_pci_bus_state_init(&hotplug_state, NULL);
|
||||
build_pci_bus_state_init(&hotplug_state, NULL, pm->pcihp_bridge_en);
|
||||
|
||||
if (bus) {
|
||||
/* Scan all PCI buses. Generate tables to support hotplug. */
|
||||
@@ -1440,13 +1474,14 @@ static
|
||||
void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
|
||||
{
|
||||
GArray *table_offsets;
|
||||
unsigned facs, dsdt, rsdt;
|
||||
unsigned facs, ssdt, dsdt, rsdt;
|
||||
AcpiCpuInfo cpu;
|
||||
AcpiPmInfo pm;
|
||||
AcpiMiscInfo misc;
|
||||
AcpiMcfgInfo mcfg;
|
||||
PcPciInfo pci;
|
||||
uint8_t *u;
|
||||
size_t aml_len = 0;
|
||||
|
||||
acpi_get_cpu_info(&cpu);
|
||||
acpi_get_pm_info(&pm);
|
||||
@@ -1474,13 +1509,20 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
|
||||
dsdt = tables->table_data->len;
|
||||
build_dsdt(tables->table_data, tables->linker, &misc);
|
||||
|
||||
/* Count the size of the DSDT and SSDT, we will need it for legacy
|
||||
* sizing of ACPI tables.
|
||||
*/
|
||||
aml_len += tables->table_data->len - dsdt;
|
||||
|
||||
/* ACPI tables pointed to by RSDT */
|
||||
acpi_add_table(table_offsets, tables->table_data);
|
||||
build_fadt(tables->table_data, tables->linker, &pm, facs, dsdt);
|
||||
|
||||
ssdt = tables->table_data->len;
|
||||
acpi_add_table(table_offsets, tables->table_data);
|
||||
build_ssdt(tables->table_data, tables->linker, &cpu, &pm, &misc, &pci,
|
||||
guest_info);
|
||||
aml_len += tables->table_data->len - ssdt;
|
||||
|
||||
acpi_add_table(table_offsets, tables->table_data);
|
||||
build_madt(tables->table_data, tables->linker, &cpu, guest_info);
|
||||
@@ -1513,14 +1555,53 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
|
||||
/* RSDP is in FSEG memory, so allocate it separately */
|
||||
build_rsdp(tables->rsdp, tables->linker, rsdt);
|
||||
|
||||
/* We'll expose it all to Guest so align size to reduce
|
||||
/* We'll expose it all to Guest so we want to reduce
|
||||
* chance of size changes.
|
||||
* RSDP is small so it's easy to keep it immutable, no need to
|
||||
* bother with alignment.
|
||||
*
|
||||
* We used to align the tables to 4k, but of course this would
|
||||
* too simple to be enough. 4k turned out to be too small an
|
||||
* alignment very soon, and in fact it is almost impossible to
|
||||
* keep the table size stable for all (max_cpus, max_memory_slots)
|
||||
* combinations. So the table size is always 64k for pc-i440fx-2.1
|
||||
* and we give an error if the table grows beyond that limit.
|
||||
*
|
||||
* We still have the problem of migrating from "-M pc-i440fx-2.0". For
|
||||
* that, we exploit the fact that QEMU 2.1 generates _smaller_ tables
|
||||
* than 2.0 and we can always pad the smaller tables with zeros. We can
|
||||
* then use the exact size of the 2.0 tables.
|
||||
*
|
||||
* All this is for PIIX4, since QEMU 2.0 didn't support Q35 migration.
|
||||
*/
|
||||
acpi_align_size(tables->table_data, 0x1000);
|
||||
if (guest_info->legacy_acpi_table_size) {
|
||||
/* Subtracting aml_len gives the size of fixed tables. Then add the
|
||||
* size of the PIIX4 DSDT/SSDT in QEMU 2.0.
|
||||
*/
|
||||
int legacy_aml_len =
|
||||
guest_info->legacy_acpi_table_size +
|
||||
ACPI_BUILD_LEGACY_CPU_AML_SIZE * max_cpus;
|
||||
int legacy_table_size =
|
||||
ROUND_UP(tables->table_data->len - aml_len + legacy_aml_len,
|
||||
ACPI_BUILD_ALIGN_SIZE);
|
||||
if (tables->table_data->len > legacy_table_size) {
|
||||
/* Should happen only with PCI bridges and -M pc-i440fx-2.0. */
|
||||
error_report("Warning: migration may not work.");
|
||||
}
|
||||
g_array_set_size(tables->table_data, legacy_table_size);
|
||||
} else {
|
||||
/* Make sure we have a buffer in case we need to resize the tables. */
|
||||
if (tables->table_data->len > ACPI_BUILD_TABLE_SIZE / 2) {
|
||||
/* As of QEMU 2.1, this fires with 160 VCPUs and 255 memory slots. */
|
||||
error_report("Warning: ACPI tables are larger than 64k.");
|
||||
error_report("Warning: migration may not work.");
|
||||
error_report("Warning: please remove CPUs, NUMA nodes, "
|
||||
"memory slots or PCI bridges.");
|
||||
}
|
||||
acpi_align_size(tables->table_data, ACPI_BUILD_TABLE_SIZE);
|
||||
}
|
||||
|
||||
acpi_align_size(tables->linker, 0x1000);
|
||||
acpi_align_size(tables->linker, ACPI_BUILD_ALIGN_SIZE);
|
||||
|
||||
/* Cleanup memory that's no longer used. */
|
||||
g_array_free(table_offsets, true);
|
||||
|
@@ -181,57 +181,45 @@ DefinitionBlock (
|
||||
|
||||
Scope(\_SB) {
|
||||
Scope(PCI0) {
|
||||
Name(_PRT, Package() {
|
||||
/* PCI IRQ routing table, example from ACPI 2.0a specification,
|
||||
section 6.2.8.1 */
|
||||
/* Note: we provide the same info as the PCI routing
|
||||
table of the Bochs BIOS */
|
||||
Method (_PRT, 0) {
|
||||
Store(Package(128) {}, Local0)
|
||||
Store(Zero, Local1)
|
||||
While(LLess(Local1, 128)) {
|
||||
// slot = pin >> 2
|
||||
Store(ShiftRight(Local1, 2), Local2)
|
||||
|
||||
#define prt_slot(nr, lnk0, lnk1, lnk2, lnk3) \
|
||||
Package() { nr##ffff, 0, lnk0, 0 }, \
|
||||
Package() { nr##ffff, 1, lnk1, 0 }, \
|
||||
Package() { nr##ffff, 2, lnk2, 0 }, \
|
||||
Package() { nr##ffff, 3, lnk3, 0 }
|
||||
// lnk = (slot + pin) & 3
|
||||
Store(And(Add(Local1, Local2), 3), Local3)
|
||||
If (LEqual(Local3, 0)) {
|
||||
Store(Package(4) { Zero, Zero, LNKD, Zero }, Local4)
|
||||
}
|
||||
If (LEqual(Local3, 1)) {
|
||||
// device 1 is the power-management device, needs SCI
|
||||
If (LEqual(Local1, 4)) {
|
||||
Store(Package(4) { Zero, Zero, LNKS, Zero }, Local4)
|
||||
} Else {
|
||||
Store(Package(4) { Zero, Zero, LNKA, Zero }, Local4)
|
||||
}
|
||||
}
|
||||
If (LEqual(Local3, 2)) {
|
||||
Store(Package(4) { Zero, Zero, LNKB, Zero }, Local4)
|
||||
}
|
||||
If (LEqual(Local3, 3)) {
|
||||
Store(Package(4) { Zero, Zero, LNKC, Zero }, Local4)
|
||||
}
|
||||
|
||||
#define prt_slot0(nr) prt_slot(nr, LNKD, LNKA, LNKB, LNKC)
|
||||
#define prt_slot1(nr) prt_slot(nr, LNKA, LNKB, LNKC, LNKD)
|
||||
#define prt_slot2(nr) prt_slot(nr, LNKB, LNKC, LNKD, LNKA)
|
||||
#define prt_slot3(nr) prt_slot(nr, LNKC, LNKD, LNKA, LNKB)
|
||||
// Complete the interrupt routing entry:
|
||||
// Package(4) { 0x[slot]FFFF, [pin], [link], 0) }
|
||||
|
||||
prt_slot0(0x0000),
|
||||
/* Device 1 is power mgmt device, and can only use irq 9 */
|
||||
prt_slot(0x0001, LNKS, LNKB, LNKC, LNKD),
|
||||
prt_slot2(0x0002),
|
||||
prt_slot3(0x0003),
|
||||
prt_slot0(0x0004),
|
||||
prt_slot1(0x0005),
|
||||
prt_slot2(0x0006),
|
||||
prt_slot3(0x0007),
|
||||
prt_slot0(0x0008),
|
||||
prt_slot1(0x0009),
|
||||
prt_slot2(0x000a),
|
||||
prt_slot3(0x000b),
|
||||
prt_slot0(0x000c),
|
||||
prt_slot1(0x000d),
|
||||
prt_slot2(0x000e),
|
||||
prt_slot3(0x000f),
|
||||
prt_slot0(0x0010),
|
||||
prt_slot1(0x0011),
|
||||
prt_slot2(0x0012),
|
||||
prt_slot3(0x0013),
|
||||
prt_slot0(0x0014),
|
||||
prt_slot1(0x0015),
|
||||
prt_slot2(0x0016),
|
||||
prt_slot3(0x0017),
|
||||
prt_slot0(0x0018),
|
||||
prt_slot1(0x0019),
|
||||
prt_slot2(0x001a),
|
||||
prt_slot3(0x001b),
|
||||
prt_slot0(0x001c),
|
||||
prt_slot1(0x001d),
|
||||
prt_slot2(0x001e),
|
||||
prt_slot3(0x001f),
|
||||
})
|
||||
Store(Or(ShiftLeft(Local2, 16), 0xFFFF), Index(Local4, 0))
|
||||
Store(And(Local1, 3), Index(Local4, 1))
|
||||
Store(Local4, Index(Local0, Local1))
|
||||
|
||||
Increment(Local1)
|
||||
}
|
||||
|
||||
Return(Local0)
|
||||
}
|
||||
}
|
||||
|
||||
Field(PCI0.ISA.P40C, ByteAcc, NoLock, Preserve) {
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -14,10 +14,8 @@
|
||||
*/
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "qemu/host-utils.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "sysemu/kvm.h"
|
||||
#include "sysemu/cpus.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "hw/kvm/clock.h"
|
||||
|
||||
@@ -36,48 +34,6 @@ typedef struct KVMClockState {
|
||||
bool clock_valid;
|
||||
} KVMClockState;
|
||||
|
||||
struct pvclock_vcpu_time_info {
|
||||
uint32_t version;
|
||||
uint32_t pad0;
|
||||
uint64_t tsc_timestamp;
|
||||
uint64_t system_time;
|
||||
uint32_t tsc_to_system_mul;
|
||||
int8_t tsc_shift;
|
||||
uint8_t flags;
|
||||
uint8_t pad[2];
|
||||
} __attribute__((__packed__)); /* 32 bytes */
|
||||
|
||||
static uint64_t kvmclock_current_nsec(KVMClockState *s)
|
||||
{
|
||||
CPUState *cpu = first_cpu;
|
||||
CPUX86State *env = cpu->env_ptr;
|
||||
hwaddr kvmclock_struct_pa = env->system_time_msr & ~1ULL;
|
||||
uint64_t migration_tsc = env->tsc;
|
||||
struct pvclock_vcpu_time_info time;
|
||||
uint64_t delta;
|
||||
uint64_t nsec_lo;
|
||||
uint64_t nsec_hi;
|
||||
uint64_t nsec;
|
||||
|
||||
if (!(env->system_time_msr & 1ULL)) {
|
||||
/* KVM clock not active */
|
||||
return 0;
|
||||
}
|
||||
|
||||
cpu_physical_memory_read(kvmclock_struct_pa, &time, sizeof(time));
|
||||
|
||||
assert(time.tsc_timestamp <= migration_tsc);
|
||||
delta = migration_tsc - time.tsc_timestamp;
|
||||
if (time.tsc_shift < 0) {
|
||||
delta >>= -time.tsc_shift;
|
||||
} else {
|
||||
delta <<= time.tsc_shift;
|
||||
}
|
||||
|
||||
mulu64(&nsec_lo, &nsec_hi, delta, time.tsc_to_system_mul);
|
||||
nsec = (nsec_lo >> 32) | (nsec_hi << 32);
|
||||
return nsec + time.system_time;
|
||||
}
|
||||
|
||||
static void kvmclock_vm_state_change(void *opaque, int running,
|
||||
RunState state)
|
||||
@@ -89,15 +45,9 @@ static void kvmclock_vm_state_change(void *opaque, int running,
|
||||
|
||||
if (running) {
|
||||
struct kvm_clock_data data;
|
||||
uint64_t time_at_migration = kvmclock_current_nsec(s);
|
||||
|
||||
s->clock_valid = false;
|
||||
|
||||
/* We can't rely on the migrated clock value, just discard it */
|
||||
if (time_at_migration) {
|
||||
s->clock = time_at_migration;
|
||||
}
|
||||
|
||||
data.clock = s->clock;
|
||||
data.flags = 0;
|
||||
ret = kvm_vm_ioctl(kvm_state, KVM_SET_CLOCK, &data);
|
||||
@@ -125,8 +75,6 @@ static void kvmclock_vm_state_change(void *opaque, int running,
|
||||
if (s->clock_valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
cpu_synchronize_all_states();
|
||||
ret = kvm_vm_ioctl(kvm_state, KVM_GET_CLOCK, &data);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "KVM_GET_CLOCK failed: %s\n", strerror(ret));
|
||||
|
@@ -61,6 +61,7 @@ static const int ide_irq[MAX_IDE_BUS] = { 14, 15 };
|
||||
|
||||
static bool has_pci_info;
|
||||
static bool has_acpi_build = true;
|
||||
static int legacy_acpi_table_size;
|
||||
static bool smbios_defaults = true;
|
||||
static bool smbios_legacy_mode;
|
||||
/* Make sure that guest addresses aligned at 1Gbyte boundaries get mapped to
|
||||
@@ -114,7 +115,7 @@ static void pc_init1(MachineState *machine,
|
||||
lowmem = 0xe0000000;
|
||||
}
|
||||
|
||||
/* Handle the machine opt max-ram-below-4g. It is basicly doing
|
||||
/* Handle the machine opt max-ram-below-4g. It is basically doing
|
||||
* min(qemu limit, user limit).
|
||||
*/
|
||||
if (lowmem > pc_machine->max_ram_below_4g) {
|
||||
@@ -163,6 +164,7 @@ static void pc_init1(MachineState *machine,
|
||||
guest_info = pc_guest_info_init(below_4g_mem_size, above_4g_mem_size);
|
||||
|
||||
guest_info->has_acpi_build = has_acpi_build;
|
||||
guest_info->legacy_acpi_table_size = legacy_acpi_table_size;
|
||||
|
||||
guest_info->has_pci_info = has_pci_info;
|
||||
guest_info->isapc_ram_fw = !pci_enabled;
|
||||
@@ -297,6 +299,23 @@ static void pc_init_pci(MachineState *machine)
|
||||
|
||||
static void pc_compat_2_0(MachineState *machine)
|
||||
{
|
||||
/* This value depends on the actual DSDT and SSDT compiled into
|
||||
* the source QEMU; unfortunately it depends on the binary and
|
||||
* not on the machine type, so we cannot make pc-i440fx-1.7 work on
|
||||
* both QEMU 1.7 and QEMU 2.0.
|
||||
*
|
||||
* Large variations cause migration to fail for more than one
|
||||
* consecutive value of the "-smp" maxcpus option.
|
||||
*
|
||||
* For small variations of the kind caused by different iasl versions,
|
||||
* the 4k rounding usually leaves slack. However, there could be still
|
||||
* one or two values that break. For QEMU 1.7 and QEMU 2.0 the
|
||||
* slack is only ~10 bytes before one "-smp maxcpus" value breaks!
|
||||
*
|
||||
* 6652 is valid for QEMU 2.0, the right value for pc-i440fx-1.7 on
|
||||
* QEMU 1.7 it is 6414. For RHEL/CentOS 7.0 it is 6418.
|
||||
*/
|
||||
legacy_acpi_table_size = 6652;
|
||||
smbios_legacy_mode = true;
|
||||
has_reserved_memory = false;
|
||||
}
|
||||
@@ -307,6 +326,7 @@ static void pc_compat_1_7(MachineState *machine)
|
||||
smbios_defaults = false;
|
||||
gigabyte_align = false;
|
||||
option_rom_has_mr = true;
|
||||
legacy_acpi_table_size = 6414;
|
||||
x86_cpu_compat_disable_kvm_features(FEAT_1_ECX, CPUID_EXT_X2APIC);
|
||||
}
|
||||
|
||||
@@ -386,19 +406,10 @@ static void pc_init_pci_1_2(MachineState *machine)
|
||||
pc_init_pci(machine);
|
||||
}
|
||||
|
||||
/* PC init function for pc-0.10 to pc-0.13, and reused by xenfv */
|
||||
/* PC init function for pc-0.10 to pc-0.13 */
|
||||
static void pc_init_pci_no_kvmclock(MachineState *machine)
|
||||
{
|
||||
has_pci_info = false;
|
||||
has_acpi_build = false;
|
||||
smbios_defaults = false;
|
||||
gigabyte_align = false;
|
||||
smbios_legacy_mode = true;
|
||||
has_reserved_memory = false;
|
||||
option_rom_has_mr = true;
|
||||
rom_file_has_mr = false;
|
||||
x86_cpu_compat_disable_kvm_features(FEAT_KVM, KVM_FEATURE_PV_EOI);
|
||||
enable_compat_apic_id_mode();
|
||||
pc_compat_1_2(machine);
|
||||
pc_init1(machine, 1, 0);
|
||||
}
|
||||
|
||||
|
@@ -103,7 +103,7 @@ static void pc_q35_init(MachineState *machine)
|
||||
lowmem = 0xb0000000;
|
||||
}
|
||||
|
||||
/* Handle the machine opt max-ram-below-4g. It is basicly doing
|
||||
/* Handle the machine opt max-ram-below-4g. It is basically doing
|
||||
* min(qemu limit, user limit).
|
||||
*/
|
||||
if (lowmem > pc_machine->max_ram_below_4g) {
|
||||
@@ -155,6 +155,11 @@ static void pc_q35_init(MachineState *machine)
|
||||
guest_info->has_acpi_build = has_acpi_build;
|
||||
guest_info->has_reserved_memory = has_reserved_memory;
|
||||
|
||||
/* Migration was not supported in 2.0 for Q35, so do not bother
|
||||
* with this hack (see hw/i386/acpi-build.c).
|
||||
*/
|
||||
guest_info->legacy_acpi_table_size = 0;
|
||||
|
||||
if (smbios_defaults) {
|
||||
MachineClass *mc = MACHINE_GET_CLASS(machine);
|
||||
/* These values are guest ABI, do not change */
|
||||
|
@@ -67,6 +67,7 @@ static const VMStateDescription vmstate_imx_ccm = {
|
||||
VMSTATE_UINT32(pmcr0, IMXCCMState),
|
||||
VMSTATE_UINT32(pmcr1, IMXCCMState),
|
||||
VMSTATE_UINT32(pll_refclk_freq, IMXCCMState),
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
.post_load = imx_ccm_post_load,
|
||||
};
|
||||
|
@@ -204,8 +204,9 @@ static void ppc_core99_init(MachineState *machine)
|
||||
memory_region_add_subregion(get_system_memory(), 0, ram);
|
||||
|
||||
/* allocate and load BIOS */
|
||||
memory_region_allocate_system_memory(bios, NULL, "ppc_core99.bios",
|
||||
BIOS_SIZE);
|
||||
memory_region_init_ram(bios, NULL, "ppc_core99.bios", BIOS_SIZE);
|
||||
vmstate_register_ram_global(bios);
|
||||
|
||||
if (bios_name == NULL)
|
||||
bios_name = PROM_FILENAME;
|
||||
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
|
||||
|
@@ -135,8 +135,9 @@ static void ppc_heathrow_init(MachineState *machine)
|
||||
memory_region_add_subregion(sysmem, 0, ram);
|
||||
|
||||
/* allocate and load BIOS */
|
||||
memory_region_allocate_system_memory(bios, NULL, "ppc_heathrow.bios",
|
||||
BIOS_SIZE);
|
||||
memory_region_init_ram(bios, NULL, "ppc_heathrow.bios", BIOS_SIZE);
|
||||
vmstate_register_ram_global(bios);
|
||||
|
||||
if (bios_name == NULL)
|
||||
bios_name = PROM_FILENAME;
|
||||
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
|
||||
|
@@ -214,7 +214,8 @@ static void ref405ep_init(MachineState *machine)
|
||||
33333333, &pic, kernel_filename == NULL ? 0 : 1);
|
||||
/* allocate SRAM */
|
||||
sram_size = 512 * 1024;
|
||||
memory_region_allocate_system_memory(sram, NULL, "ef405ep.sram", sram_size);
|
||||
memory_region_init_ram(sram, NULL, "ef405ep.sram", sram_size);
|
||||
vmstate_register_ram_global(sram);
|
||||
memory_region_add_subregion(sysmem, 0xFFF00000, sram);
|
||||
/* allocate and load BIOS */
|
||||
#ifdef DEBUG_BOARD_INIT
|
||||
@@ -245,8 +246,9 @@ static void ref405ep_init(MachineState *machine)
|
||||
printf("Load BIOS from file\n");
|
||||
#endif
|
||||
bios = g_new(MemoryRegion, 1);
|
||||
memory_region_allocate_system_memory(bios, NULL, "ef405ep.bios",
|
||||
BIOS_SIZE);
|
||||
memory_region_init_ram(bios, NULL, "ef405ep.bios", BIOS_SIZE);
|
||||
vmstate_register_ram_global(bios);
|
||||
|
||||
if (bios_name == NULL)
|
||||
bios_name = BIOS_FILENAME;
|
||||
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
|
||||
@@ -508,6 +510,7 @@ static void taihu_405ep_init(MachineState *machine)
|
||||
MemoryRegion *sysmem = get_system_memory();
|
||||
MemoryRegion *bios;
|
||||
MemoryRegion *ram_memories = g_malloc(2 * sizeof(*ram_memories));
|
||||
MemoryRegion *ram = g_malloc0(sizeof(*ram));
|
||||
hwaddr ram_bases[2], ram_sizes[2];
|
||||
long bios_size;
|
||||
target_ulong kernel_base, initrd_base;
|
||||
@@ -517,15 +520,20 @@ static void taihu_405ep_init(MachineState *machine)
|
||||
DriveInfo *dinfo;
|
||||
|
||||
/* RAM is soldered to the board so the size cannot be changed */
|
||||
memory_region_allocate_system_memory(&ram_memories[0], NULL,
|
||||
"taihu_405ep.ram-0", 0x04000000);
|
||||
ram_size = 0x08000000;
|
||||
memory_region_allocate_system_memory(ram, NULL, "taihu_405ep.ram",
|
||||
ram_size);
|
||||
|
||||
ram_bases[0] = 0;
|
||||
ram_sizes[0] = 0x04000000;
|
||||
memory_region_allocate_system_memory(&ram_memories[1], NULL,
|
||||
"taihu_405ep.ram-1", 0x04000000);
|
||||
memory_region_init_alias(&ram_memories[0], NULL,
|
||||
"taihu_405ep.ram-0", ram, ram_bases[0],
|
||||
ram_sizes[0]);
|
||||
ram_bases[1] = 0x04000000;
|
||||
ram_sizes[1] = 0x04000000;
|
||||
ram_size = 0x08000000;
|
||||
memory_region_init_alias(&ram_memories[1], NULL,
|
||||
"taihu_405ep.ram-1", ram, ram_bases[1],
|
||||
ram_sizes[1]);
|
||||
#ifdef DEBUG_BOARD_INIT
|
||||
printf("%s: register cpu\n", __func__);
|
||||
#endif
|
||||
@@ -564,8 +572,8 @@ static void taihu_405ep_init(MachineState *machine)
|
||||
if (bios_name == NULL)
|
||||
bios_name = BIOS_FILENAME;
|
||||
bios = g_new(MemoryRegion, 1);
|
||||
memory_region_allocate_system_memory(bios, NULL, "taihu_405ep.bios",
|
||||
BIOS_SIZE);
|
||||
memory_region_init_ram(bios, NULL, "taihu_405ep.bios", BIOS_SIZE);
|
||||
vmstate_register_ram_global(bios);
|
||||
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
|
||||
if (filename) {
|
||||
bios_size = load_image(filename, memory_region_get_ram_ptr(bios));
|
||||
|
@@ -974,8 +974,8 @@ static void ppc405_ocm_init(CPUPPCState *env)
|
||||
|
||||
ocm = g_malloc0(sizeof(ppc405_ocm_t));
|
||||
/* XXX: Size is 4096 or 0x04000000 */
|
||||
memory_region_allocate_system_memory(&ocm->isarc_ram, NULL, "ppc405.ocm",
|
||||
4096);
|
||||
memory_region_init_ram(&ocm->isarc_ram, NULL, "ppc405.ocm", 4096);
|
||||
vmstate_register_ram_global(&ocm->isarc_ram);
|
||||
memory_region_init_alias(&ocm->dsarc_ram, NULL, "ppc405.dsarc", &ocm->isarc_ram,
|
||||
0, 4096);
|
||||
qemu_register_reset(&ocm_reset, ocm);
|
||||
|
@@ -683,28 +683,20 @@ ram_addr_t ppc4xx_sdram_adjust(ram_addr_t ram_size, int nr_banks,
|
||||
hwaddr ram_sizes[],
|
||||
const unsigned int sdram_bank_sizes[])
|
||||
{
|
||||
MemoryRegion *ram = g_malloc0(sizeof(*ram));
|
||||
ram_addr_t size_left = ram_size;
|
||||
ram_addr_t base = 0;
|
||||
unsigned int bank_size;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
for (i = 0; i < nr_banks; i++) {
|
||||
for (j = 0; sdram_bank_sizes[j] != 0; j++) {
|
||||
unsigned int bank_size = sdram_bank_sizes[j];
|
||||
|
||||
bank_size = sdram_bank_sizes[j];
|
||||
if (bank_size <= size_left) {
|
||||
char name[32];
|
||||
snprintf(name, sizeof(name), "ppc4xx.sdram%d", i);
|
||||
memory_region_allocate_system_memory(&ram_memories[i], NULL,
|
||||
name, bank_size);
|
||||
ram_bases[i] = base;
|
||||
ram_sizes[i] = bank_size;
|
||||
base += bank_size;
|
||||
size_left -= bank_size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!size_left) {
|
||||
/* No need to use the remaining banks. */
|
||||
break;
|
||||
@@ -712,9 +704,31 @@ ram_addr_t ppc4xx_sdram_adjust(ram_addr_t ram_size, int nr_banks,
|
||||
}
|
||||
|
||||
ram_size -= size_left;
|
||||
if (size_left)
|
||||
if (size_left) {
|
||||
printf("Truncating memory to %d MiB to fit SDRAM controller limits.\n",
|
||||
(int)(ram_size >> 20));
|
||||
}
|
||||
|
||||
memory_region_allocate_system_memory(ram, NULL, "ppc4xx.sdram", ram_size);
|
||||
|
||||
size_left = ram_size;
|
||||
for (i = 0; i < nr_banks && size_left; i++) {
|
||||
for (j = 0; sdram_bank_sizes[j] != 0; j++) {
|
||||
bank_size = sdram_bank_sizes[j];
|
||||
|
||||
if (bank_size <= size_left) {
|
||||
char name[32];
|
||||
snprintf(name, sizeof(name), "ppc4xx.sdram%d", i);
|
||||
memory_region_init_alias(&ram_memories[i], NULL, name, ram,
|
||||
base, bank_size);
|
||||
ram_bases[i] = base;
|
||||
ram_sizes[i] = bank_size;
|
||||
base += bank_size;
|
||||
size_left -= bank_size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ram_size;
|
||||
}
|
||||
|
@@ -1090,7 +1090,7 @@ static const VMStateDescription vmstate_usb_mtp = {
|
||||
};
|
||||
|
||||
static Property mtp_properties[] = {
|
||||
DEFINE_PROP_STRING("root", MTPState, root),
|
||||
DEFINE_PROP_STRING("x-root", MTPState, root),
|
||||
DEFINE_PROP_STRING("desc", MTPState, desc),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
@@ -2021,7 +2021,7 @@ static const VMStateDescription vmstate_ohci_eof_timer = {
|
||||
},
|
||||
};
|
||||
|
||||
const VMStateDescription vmstate_ohci_state = {
|
||||
static const VMStateDescription vmstate_ohci_state = {
|
||||
.name = "ohci-core",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
|
@@ -3737,6 +3737,7 @@ static const VMStateDescription vmstate_xhci_event = {
|
||||
VMSTATE_UINT32(flags, XHCIEvent),
|
||||
VMSTATE_UINT8(slotid, XHCIEvent),
|
||||
VMSTATE_UINT8(epid, XHCIEvent),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -216,7 +216,11 @@ static int vhost_user_call(struct vhost_dev *dev, unsigned long int request,
|
||||
case VHOST_SET_MEM_TABLE:
|
||||
for (i = 0; i < dev->mem->nregions; ++i) {
|
||||
struct vhost_memory_region *reg = dev->mem->regions + i;
|
||||
fd = qemu_get_ram_fd(reg->guest_phys_addr);
|
||||
ram_addr_t ram_addr;
|
||||
|
||||
assert((uintptr_t)reg->userspace_addr == reg->userspace_addr);
|
||||
qemu_ram_addr_from_host((void *)(uintptr_t)reg->userspace_addr, &ram_addr);
|
||||
fd = qemu_get_ram_fd(ram_addr);
|
||||
if (fd > 0) {
|
||||
msg.memory.regions[fd_num].userspace_addr = reg->userspace_addr;
|
||||
msg.memory.regions[fd_num].memory_size = reg->memory_size;
|
||||
|
@@ -181,7 +181,13 @@ static void virtio_rng_device_realize(DeviceState *dev, Error **errp)
|
||||
|
||||
vrng->vq = virtio_add_queue(vdev, 8, handle_input);
|
||||
|
||||
assert(vrng->conf.max_bytes <= INT64_MAX);
|
||||
/* Workaround: Property parsing does not enforce unsigned integers,
|
||||
* So this is a hack to reject such numbers. */
|
||||
if (vrng->conf.max_bytes > INT64_MAX) {
|
||||
error_set(errp, QERR_INVALID_PARAMETER_VALUE, "max-bytes",
|
||||
"a non-negative integer below 2^63");
|
||||
return;
|
||||
}
|
||||
vrng->quota_remaining = vrng->conf.max_bytes;
|
||||
|
||||
vrng->rate_limit_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL,
|
||||
|
@@ -278,7 +278,7 @@ int bdrv_truncate(BlockDriverState *bs, int64_t offset);
|
||||
int64_t bdrv_getlength(BlockDriverState *bs);
|
||||
int64_t bdrv_get_allocated_file_size(BlockDriverState *bs);
|
||||
void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr);
|
||||
int bdrv_refresh_limits(BlockDriverState *bs);
|
||||
void bdrv_refresh_limits(BlockDriverState *bs, Error **errp);
|
||||
int bdrv_commit(BlockDriverState *bs);
|
||||
int bdrv_commit_all(void);
|
||||
int bdrv_change_backing_file(BlockDriverState *bs,
|
||||
|
@@ -240,7 +240,7 @@ struct BlockDriver {
|
||||
int (*bdrv_debug_resume)(BlockDriverState *bs, const char *tag);
|
||||
bool (*bdrv_debug_is_suspended)(BlockDriverState *bs, const char *tag);
|
||||
|
||||
int (*bdrv_refresh_limits)(BlockDriverState *bs);
|
||||
void (*bdrv_refresh_limits)(BlockDriverState *bs, Error **errp);
|
||||
|
||||
/*
|
||||
* Returns 1 if newly created images are guaranteed to contain only
|
||||
|
@@ -71,6 +71,17 @@ static inline void cpu_physical_memory_set_dirty_flag(ram_addr_t addr,
|
||||
set_bit(addr >> TARGET_PAGE_BITS, ram_list.dirty_memory[client]);
|
||||
}
|
||||
|
||||
static inline void cpu_physical_memory_set_dirty_range_nocode(ram_addr_t start,
|
||||
ram_addr_t length)
|
||||
{
|
||||
unsigned long end, page;
|
||||
|
||||
end = TARGET_PAGE_ALIGN(start + length) >> TARGET_PAGE_BITS;
|
||||
page = start >> TARGET_PAGE_BITS;
|
||||
bitmap_set(ram_list.dirty_memory[DIRTY_MEMORY_MIGRATION], page, end - page);
|
||||
bitmap_set(ram_list.dirty_memory[DIRTY_MEMORY_VGA], page, end - page);
|
||||
}
|
||||
|
||||
static inline void cpu_physical_memory_set_dirty_range(ram_addr_t start,
|
||||
ram_addr_t length)
|
||||
{
|
||||
|
@@ -94,6 +94,7 @@ struct PcGuestInfo {
|
||||
uint64_t *node_mem;
|
||||
uint64_t *node_cpu;
|
||||
FWCfgState *fw_cfg;
|
||||
int legacy_acpi_table_size;
|
||||
bool has_acpi_build;
|
||||
bool has_reserved_memory;
|
||||
};
|
||||
|
@@ -153,7 +153,7 @@
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* Definitions for arbitary-precision modules (only valid after */
|
||||
/* Definitions for arbitrary-precision modules (only valid after */
|
||||
/* decNumber.h has been included) */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
|
@@ -2077,12 +2077,13 @@ void kvm_remove_all_breakpoints(CPUState *cpu)
|
||||
{
|
||||
struct kvm_sw_breakpoint *bp, *next;
|
||||
KVMState *s = cpu->kvm_state;
|
||||
CPUState *tmpcpu;
|
||||
|
||||
QTAILQ_FOREACH_SAFE(bp, &s->kvm_sw_breakpoints, entry, next) {
|
||||
if (kvm_arch_remove_sw_breakpoint(cpu, bp) != 0) {
|
||||
/* Try harder to find a CPU that currently sees the breakpoint. */
|
||||
CPU_FOREACH(cpu) {
|
||||
if (kvm_arch_remove_sw_breakpoint(cpu, bp) == 0) {
|
||||
CPU_FOREACH(tmpcpu) {
|
||||
if (kvm_arch_remove_sw_breakpoint(tmpcpu, bp) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@@ -282,6 +282,7 @@ static SlirpState *slirp_lookup(Monitor *mon, const char *vlan,
|
||||
NetClientState *nc;
|
||||
nc = net_hub_find_client_by_name(strtol(vlan, NULL, 0), stack);
|
||||
if (!nc) {
|
||||
monitor_printf(mon, "unrecognized (vlan-id, stackname) pair\n");
|
||||
return NULL;
|
||||
}
|
||||
if (strcmp(nc->model, "user")) {
|
||||
|
53
po/de_DE.po
53
po/de_DE.po
@@ -6,7 +6,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: QEMU 1.4.50\n"
|
||||
"Report-Msgid-Bugs-To: qemu-devel@nongnu.org\n"
|
||||
"POT-Creation-Date: 2013-07-05 22:36+0200\n"
|
||||
"POT-Creation-Date: 2014-07-17 20:39+0200\n"
|
||||
"PO-Revision-Date: 2012-02-28 16:00+0100\n"
|
||||
"Last-Translator: Kevin Wolf <kwolf@redhat.com>\n"
|
||||
"Language-Team: Deutsch <de@li.org>\n"
|
||||
@@ -16,49 +16,70 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n!=1);\n"
|
||||
|
||||
#: ui/gtk.c:214
|
||||
#: ui/gtk.c:321
|
||||
msgid " - Press Ctrl+Alt+G to release grab"
|
||||
msgstr " - Strg+Alt+G drücken, um Eingabegeräte freizugeben"
|
||||
|
||||
#: ui/gtk.c:218
|
||||
#: ui/gtk.c:325
|
||||
msgid " [Paused]"
|
||||
msgstr " [Angehalten]"
|
||||
|
||||
#: ui/gtk.c:1318
|
||||
#: ui/gtk.c:1601
|
||||
msgid "_Pause"
|
||||
msgstr "_Angehalten"
|
||||
|
||||
#: ui/gtk.c:1324
|
||||
#: ui/gtk.c:1607
|
||||
msgid "_Reset"
|
||||
msgstr "_Reset"
|
||||
|
||||
#: ui/gtk.c:1327
|
||||
#: ui/gtk.c:1610
|
||||
msgid "Power _Down"
|
||||
msgstr "_Herunterfahren"
|
||||
|
||||
#: ui/gtk.c:1381
|
||||
#: ui/gtk.c:1616
|
||||
msgid "_Quit"
|
||||
msgstr "_Beenden"
|
||||
|
||||
#: ui/gtk.c:1692
|
||||
msgid "_Fullscreen"
|
||||
msgstr "_Vollbild"
|
||||
|
||||
#: ui/gtk.c:1702
|
||||
msgid "Zoom _In"
|
||||
msgstr "_Heranzoomen"
|
||||
|
||||
#: ui/gtk.c:1709
|
||||
msgid "Zoom _Out"
|
||||
msgstr "_Wegzoomen"
|
||||
|
||||
#: ui/gtk.c:1716
|
||||
msgid "Best _Fit"
|
||||
msgstr "_Einpassen"
|
||||
|
||||
#: ui/gtk.c:1723
|
||||
msgid "Zoom To _Fit"
|
||||
msgstr "Auf _Fenstergröße skalieren"
|
||||
|
||||
#: ui/gtk.c:1387
|
||||
#: ui/gtk.c:1729
|
||||
msgid "Grab On _Hover"
|
||||
msgstr "Tastatur _automatisch einfangen"
|
||||
|
||||
#: ui/gtk.c:1390
|
||||
#: ui/gtk.c:1732
|
||||
msgid "_Grab Input"
|
||||
msgstr "_Eingabegeräte einfangen"
|
||||
|
||||
#: ui/gtk.c:1416
|
||||
#: ui/gtk.c:1761
|
||||
msgid "Show _Tabs"
|
||||
msgstr "_Tableiste anzeigen"
|
||||
msgstr "Reiter anzeigen"
|
||||
|
||||
#: ui/gtk.c:1430
|
||||
#: ui/gtk.c:1764
|
||||
msgid "Detach Tab"
|
||||
msgstr "Reiter abtrennen"
|
||||
|
||||
#: ui/gtk.c:1778
|
||||
msgid "_Machine"
|
||||
msgstr "_Maschine"
|
||||
|
||||
#: ui/gtk.c:1435
|
||||
#: ui/gtk.c:1783
|
||||
msgid "_View"
|
||||
msgstr "_Ansicht"
|
||||
|
||||
#~ msgid "_File"
|
||||
#~ msgstr "_Datei"
|
||||
|
56
po/fr_FR.po
56
po/fr_FR.po
@@ -1,13 +1,13 @@
|
||||
# French translation for QEMU.
|
||||
# This file is put in the public domain.
|
||||
#
|
||||
# Aurelien Jarno <aurelien@aurel32.net>, 2013.
|
||||
# Aurelien Jarno <aurelien@aurel32.net>, 2013, 2014.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: QEMU 1.4.50\n"
|
||||
"Report-Msgid-Bugs-To: qemu-devel@nongnu.org\n"
|
||||
"POT-Creation-Date: 2013-07-05 22:36+0200\n"
|
||||
"PO-Revision-Date: 2013-03-31 19:39+0200\n"
|
||||
"POT-Creation-Date: 2014-07-28 23:14+0200\n"
|
||||
"PO-Revision-Date: 2014-07-28 23:25+0200\n"
|
||||
"Last-Translator: Aurelien Jarno <aurelien@aurel32.net>\n"
|
||||
"Language-Team: French <FR@li.org>\n"
|
||||
"Language: fr\n"
|
||||
@@ -17,46 +17,70 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Lokalize 1.4\n"
|
||||
|
||||
#: ui/gtk.c:214
|
||||
#: ui/gtk.c:321
|
||||
msgid " - Press Ctrl+Alt+G to release grab"
|
||||
msgstr "- Appuyer sur Ctrl+Alt+G pour arrêter la capture"
|
||||
|
||||
#: ui/gtk.c:218
|
||||
#: ui/gtk.c:325
|
||||
msgid " [Paused]"
|
||||
msgstr " [En pause]"
|
||||
|
||||
#: ui/gtk.c:1318
|
||||
#: ui/gtk.c:1601
|
||||
msgid "_Pause"
|
||||
msgstr "_Pause"
|
||||
|
||||
#: ui/gtk.c:1324
|
||||
#: ui/gtk.c:1607
|
||||
msgid "_Reset"
|
||||
msgstr "_Réinitialiser"
|
||||
|
||||
#: ui/gtk.c:1327
|
||||
#: ui/gtk.c:1610
|
||||
msgid "Power _Down"
|
||||
msgstr "_Éteindre"
|
||||
|
||||
#: ui/gtk.c:1381
|
||||
msgid "Zoom To _Fit"
|
||||
msgstr "Zoomer pour _ajuster"
|
||||
#: ui/gtk.c:1616
|
||||
msgid "_Quit"
|
||||
msgstr "_Quitter"
|
||||
|
||||
#: ui/gtk.c:1387
|
||||
#: ui/gtk.c:1692
|
||||
msgid "_Fullscreen"
|
||||
msgstr "Mode _plein écran"
|
||||
|
||||
#: ui/gtk.c:1702
|
||||
msgid "Zoom _In"
|
||||
msgstr "Zoom _avant"
|
||||
|
||||
#: ui/gtk.c:1709
|
||||
msgid "Zoom _Out"
|
||||
msgstr "_Zoom arrière"
|
||||
|
||||
#: ui/gtk.c:1716
|
||||
msgid "Best _Fit"
|
||||
msgstr "Zoom _idéal"
|
||||
|
||||
#: ui/gtk.c:1723
|
||||
msgid "Zoom To _Fit"
|
||||
msgstr "Zoomer pour a_juster"
|
||||
|
||||
#: ui/gtk.c:1729
|
||||
msgid "Grab On _Hover"
|
||||
msgstr "Capturer en _survolant"
|
||||
|
||||
#: ui/gtk.c:1390
|
||||
#: ui/gtk.c:1732
|
||||
msgid "_Grab Input"
|
||||
msgstr "_Capturer les entrées"
|
||||
|
||||
#: ui/gtk.c:1416
|
||||
#: ui/gtk.c:1761
|
||||
msgid "Show _Tabs"
|
||||
msgstr "Montrer les _onglets"
|
||||
|
||||
#: ui/gtk.c:1430
|
||||
#: ui/gtk.c:1764
|
||||
msgid "Detach Tab"
|
||||
msgstr "_Détacher l'onglet"
|
||||
|
||||
#: ui/gtk.c:1778
|
||||
msgid "_Machine"
|
||||
msgstr "_Machine"
|
||||
|
||||
#: ui/gtk.c:1435
|
||||
#: ui/gtk.c:1783
|
||||
msgid "_View"
|
||||
msgstr "_Vue"
|
||||
|
65
po/it.po
65
po/it.po
@@ -1,13 +1,13 @@
|
||||
# Italian translation for QEMU.
|
||||
# This file is put in the public domain.
|
||||
# Paolo Bonzini <pbonzini@redhat.com>, 2012.
|
||||
# Paolo Bonzini <pbonzini@redhat.com>, 2012-2014.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: QEMU 1.4.50\n"
|
||||
"Report-Msgid-Bugs-To: qemu-devel@nongnu.org\n"
|
||||
"POT-Creation-Date: 2013-07-05 22:36+0200\n"
|
||||
"PO-Revision-Date: 2012-02-27 08:23+0100\n"
|
||||
"POT-Creation-Date: 2014-07-29 08:14+0200\n"
|
||||
"PO-Revision-Date: 2014-07-29 08:25+0200\n"
|
||||
"Last-Translator: Paolo Bonzini <pbonzini@redhat.com>\n"
|
||||
"Language-Team: Italian <it@li.org>\n"
|
||||
"Language: it\n"
|
||||
@@ -16,49 +16,66 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
|
||||
#: ui/gtk.c:214
|
||||
#: ui/gtk.c:321
|
||||
msgid " - Press Ctrl+Alt+G to release grab"
|
||||
msgstr ""
|
||||
msgstr " - Premere Ctrl+Alt+G per rilasciare l'input"
|
||||
|
||||
#: ui/gtk.c:218
|
||||
#: ui/gtk.c:325
|
||||
msgid " [Paused]"
|
||||
msgstr ""
|
||||
msgstr " [Pausa]"
|
||||
|
||||
#: ui/gtk.c:1318
|
||||
#: ui/gtk.c:1601
|
||||
msgid "_Pause"
|
||||
msgstr ""
|
||||
msgstr "_Pausa"
|
||||
|
||||
#: ui/gtk.c:1324
|
||||
#: ui/gtk.c:1607
|
||||
msgid "_Reset"
|
||||
msgstr ""
|
||||
msgstr "_Reset"
|
||||
|
||||
#: ui/gtk.c:1327
|
||||
#: ui/gtk.c:1610
|
||||
msgid "Power _Down"
|
||||
msgstr ""
|
||||
msgstr "_Spegni"
|
||||
|
||||
#: ui/gtk.c:1381
|
||||
#: ui/gtk.c:1616
|
||||
msgid "_Quit"
|
||||
msgstr "_Esci"
|
||||
|
||||
#: ui/gtk.c:1702
|
||||
msgid "Zoom _In"
|
||||
msgstr "_Aumenta zoom"
|
||||
|
||||
#: ui/gtk.c:1709
|
||||
msgid "Zoom _Out"
|
||||
msgstr "_Riduci zoom"
|
||||
|
||||
#: ui/gtk.c:1716
|
||||
msgid "Best _Fit"
|
||||
msgstr "A_nnulla zoom"
|
||||
|
||||
#: ui/gtk.c:1723
|
||||
msgid "Zoom To _Fit"
|
||||
msgstr "Adatta alla _finestra"
|
||||
|
||||
#: ui/gtk.c:1387
|
||||
#: ui/gtk.c:1729
|
||||
msgid "Grab On _Hover"
|
||||
msgstr "Cattura _automatica input"
|
||||
|
||||
#: ui/gtk.c:1390
|
||||
#: ui/gtk.c:1732
|
||||
msgid "_Grab Input"
|
||||
msgstr "_Cattura input"
|
||||
|
||||
#: ui/gtk.c:1416
|
||||
#: ui/gtk.c:1761
|
||||
msgid "Show _Tabs"
|
||||
msgstr "Mostra _tab"
|
||||
|
||||
#: ui/gtk.c:1430
|
||||
msgid "_Machine"
|
||||
msgstr ""
|
||||
#: ui/gtk.c:1764
|
||||
msgid "Detach Tab"
|
||||
msgstr "_Sposta in una nuova finestra"
|
||||
|
||||
#: ui/gtk.c:1435
|
||||
#: ui/gtk.c:1778
|
||||
msgid "_Machine"
|
||||
msgstr "_Macchina virtuale"
|
||||
|
||||
#: ui/gtk.c:1783
|
||||
msgid "_View"
|
||||
msgstr "_Visualizza"
|
||||
|
||||
#~ msgid "_File"
|
||||
#~ msgstr "_File"
|
||||
|
@@ -1168,6 +1168,9 @@ static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
|
||||
static GSource *pty_chr_add_watch(CharDriverState *chr, GIOCondition cond)
|
||||
{
|
||||
PtyCharDriver *s = chr->opaque;
|
||||
if (!s->connected) {
|
||||
return NULL;
|
||||
}
|
||||
return g_io_create_watch(s->fd, cond);
|
||||
}
|
||||
|
||||
@@ -3664,6 +3667,10 @@ int qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond,
|
||||
}
|
||||
|
||||
src = s->chr_add_watch(s, cond);
|
||||
if (!src) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
g_source_set_callback(src, (GSourceFunc)func, user_data, NULL);
|
||||
tag = g_source_attach(src, NULL);
|
||||
g_source_unref(src);
|
||||
|
@@ -1205,9 +1205,16 @@ In order to check that the user mode network is working, you can ping
|
||||
the address 10.0.2.2 and verify that you got an address in the range
|
||||
10.0.2.x from the QEMU virtual DHCP server.
|
||||
|
||||
Note that @code{ping} is not supported reliably to the internet as it
|
||||
would require root privileges. It means you can only ping the local
|
||||
router (10.0.2.2).
|
||||
Note that ICMP traffic in general does not work with user mode networking.
|
||||
@code{ping}, aka. ICMP echo, to the local router (10.0.2.2) shall work,
|
||||
however. If you're using QEMU on Linux >= 3.0, it can use unprivileged ICMP
|
||||
ping sockets to allow @code{ping} to the Internet. The host admin has to set
|
||||
the ping_group_range in order to grant access to those sockets. To allow ping
|
||||
for GID 100 (usually users group):
|
||||
|
||||
@example
|
||||
echo 100 100 > /proc/sys/net/ipv4/ping_group_range
|
||||
@end example
|
||||
|
||||
When using the built-in TFTP server, the router is also the TFTP
|
||||
server.
|
||||
|
@@ -246,7 +246,6 @@ static int read_password(char *buf, int buf_size)
|
||||
if (errno == EAGAIN || errno == EINTR) {
|
||||
continue;
|
||||
} else {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
} else if (ret == 0) {
|
||||
|
@@ -1437,7 +1437,7 @@ DEF("net", HAS_ARG, QEMU_OPTION_net,
|
||||
"-net l2tpv3[,vlan=n][,name=str],src=srcaddr,dst=dstaddr[,srcport=srcport][,dstport=dstport],txsession=txsession[,rxsession=rxsession][,ipv6=on/off][,udp=on/off][,cookie64=on/off][,counter][,pincounter][,txcookie=txcookie][,rxcookie=rxcookie][,offset=offset]\n"
|
||||
" connect the VLAN to an Ethernet over L2TPv3 pseudowire\n"
|
||||
" Linux kernel 3.3+ as well as most routers can talk\n"
|
||||
" L2TPv3. This transport allows to connect a VM to a VM,\n"
|
||||
" L2TPv3. This transport allows connecting a VM to a VM,\n"
|
||||
" VM to a router and even VM to Host. It is a nearly-universal\n"
|
||||
" standard (RFC3391). Note - this implementation uses static\n"
|
||||
" pre-configured tunnels (same as the Linux kernel).\n"
|
||||
|
@@ -643,7 +643,7 @@ typedef enum {
|
||||
FSFREEZE_HOOK_FREEZE,
|
||||
} FsfreezeHookArg;
|
||||
|
||||
const char *fsfreeze_hook_arg_string[] = {
|
||||
static const char *fsfreeze_hook_arg_string[] = {
|
||||
"thaw",
|
||||
"freeze",
|
||||
};
|
||||
|
@@ -79,6 +79,18 @@ def check_fields_match(name, s_field, d_field):
|
||||
|
||||
return False
|
||||
|
||||
def get_changed_sec_name(sec):
|
||||
# Section names can change -- see commit 292b1634 for an example.
|
||||
changes = {
|
||||
"ICH9 LPC": "ICH9-LPC",
|
||||
}
|
||||
|
||||
for item in changes:
|
||||
if item == sec:
|
||||
return changes[item]
|
||||
if changes[item] == sec:
|
||||
return item
|
||||
return ""
|
||||
|
||||
def exists_in_substruct(fields, item):
|
||||
# Some QEMU versions moved a few fields inside a substruct. This
|
||||
@@ -314,13 +326,18 @@ def main():
|
||||
dest_data = temp
|
||||
|
||||
for sec in src_data:
|
||||
if not sec in dest_data:
|
||||
print "Section \"" + sec + "\" does not exist in dest"
|
||||
bump_taint()
|
||||
continue
|
||||
dest_sec = sec
|
||||
if not dest_sec in dest_data:
|
||||
# Either the section name got changed, or the section
|
||||
# doesn't exist in dest.
|
||||
dest_sec = get_changed_sec_name(sec)
|
||||
if not dest_sec in dest_data:
|
||||
print "Section \"" + sec + "\" does not exist in dest"
|
||||
bump_taint()
|
||||
continue
|
||||
|
||||
s = src_data[sec]
|
||||
d = dest_data[sec]
|
||||
d = dest_data[dest_sec]
|
||||
|
||||
if sec == "vmschkmachine":
|
||||
check_machine_type(s, d)
|
||||
|
@@ -750,7 +750,8 @@ do_check_protect_pse36:
|
||||
/* the page can be put in the TLB */
|
||||
prot = PAGE_READ;
|
||||
if (!(ptep & PG_NX_MASK) &&
|
||||
!((env->cr[4] & CR4_SMEP_MASK) && (ptep & PG_USER_MASK))) {
|
||||
(mmu_idx == MMU_USER_IDX ||
|
||||
!((env->cr[4] & CR4_SMEP_MASK) && (ptep & PG_USER_MASK)))) {
|
||||
prot |= PAGE_EXEC;
|
||||
}
|
||||
if (pte & PG_DIRTY_MASK) {
|
||||
|
@@ -15300,6 +15300,9 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
|
||||
gen_load_gpr(t1, rs);
|
||||
|
||||
gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
|
||||
|
||||
tcg_temp_free(t0);
|
||||
tcg_temp_free(t1);
|
||||
break;
|
||||
}
|
||||
default: /* Invalid */
|
||||
|
@@ -141,6 +141,8 @@ check-qtest-i386-y += tests/i440fx-test$(EXESUF)
|
||||
check-qtest-i386-y += tests/fw_cfg-test$(EXESUF)
|
||||
check-qtest-i386-y += tests/blockdev-test$(EXESUF)
|
||||
check-qtest-i386-y += tests/qdev-monitor-test$(EXESUF)
|
||||
check-qtest-i386-y += tests/wdt_ib700-test$(EXESUF)
|
||||
gcov-files-i386-y += hw/watchdog/watchdog.c hw/watchdog/wdt_ib700.c
|
||||
check-qtest-i386-y += $(check-qtest-pci-y)
|
||||
gcov-files-i386-y += $(gcov-files-pci-y)
|
||||
check-qtest-i386-y += tests/vmxnet3-test$(EXESUF)
|
||||
@@ -311,6 +313,7 @@ tests/pcnet-test$(EXESUF): tests/pcnet-test.o
|
||||
tests/eepro100-test$(EXESUF): tests/eepro100-test.o
|
||||
tests/vmxnet3-test$(EXESUF): tests/vmxnet3-test.o
|
||||
tests/ne2000-test$(EXESUF): tests/ne2000-test.o
|
||||
tests/wdt_ib700-test$(EXESUF): tests/wdt_ib700-test.o
|
||||
tests/virtio-balloon-test$(EXESUF): tests/virtio-balloon-test.o
|
||||
tests/virtio-blk-test$(EXESUF): tests/virtio-blk-test.o
|
||||
tests/virtio-net-test$(EXESUF): tests/virtio-net-test.o
|
||||
|
Binary file not shown.
@@ -487,7 +487,11 @@ static GString *normalize_asl(gchar *asl_code)
|
||||
/* strip comments (different generation days) */
|
||||
comment = g_strstr_len(asl->str, asl->len, COMMENT_END);
|
||||
if (comment) {
|
||||
asl = g_string_erase(asl, 0, comment + sizeof(COMMENT_END) - asl->str);
|
||||
comment += strlen(COMMENT_END);
|
||||
while (*comment == '\n') {
|
||||
comment++;
|
||||
}
|
||||
asl = g_string_erase(asl, 0, comment - asl->str);
|
||||
}
|
||||
|
||||
/* strip def block name (it has file path in it) */
|
||||
|
@@ -65,7 +65,7 @@ enum {
|
||||
DSKCHG = 0x80,
|
||||
};
|
||||
|
||||
char test_image[] = "/tmp/qtest.XXXXXX";
|
||||
static char test_image[] = "/tmp/qtest.XXXXXX";
|
||||
|
||||
#define assert_bit_set(data, mask) g_assert_cmphex((data) & (mask), ==, (mask))
|
||||
#define assert_bit_clear(data, mask) g_assert_cmphex((data) & (mask), ==, 0)
|
||||
|
@@ -110,7 +110,9 @@ _launch_qemu -drive file="${TEST_IMG}",cache=${CACHEMODE},id=disk
|
||||
h=$QEMU_HANDLE
|
||||
QEMU_COMM_TIMEOUT=1
|
||||
|
||||
_send_qemu_cmd $h "drive_backup disk ${TEST_IMG}.copy" "(qemu)"
|
||||
# Silence output since it contains the disk image path and QEMU's readline
|
||||
# character echoing makes it very hard to filter the output
|
||||
_send_qemu_cmd $h "drive_backup disk ${TEST_IMG}.copy" "(qemu)" >/dev/null
|
||||
qemu_cmd_repeat=20 _send_qemu_cmd $h "info block-jobs" "No active jobs"
|
||||
_send_qemu_cmd $h 'quit' ""
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Test that qcow2 unknown autoclear feature bits are cleared
|
||||
# Test qcow2 feature bits
|
||||
#
|
||||
# Copyright (C) 2011 Red Hat, Inc.
|
||||
# Copyright IBM, Corp. 2010
|
||||
@@ -50,6 +50,56 @@ _supported_os Linux
|
||||
# Only qcow2v3 and later supports feature bits
|
||||
IMGOPTS="compat=1.1"
|
||||
|
||||
echo
|
||||
echo === Image with unknown incompatible feature bit ===
|
||||
echo
|
||||
_make_test_img 64M
|
||||
$PYTHON qcow2.py "$TEST_IMG" set-feature-bit incompatible 63
|
||||
|
||||
# Without feature table
|
||||
$PYTHON qcow2.py "$TEST_IMG" dump-header
|
||||
_img_info
|
||||
|
||||
# With feature table containing bit 63
|
||||
printf "\x00\x3f%s" "Test feature" | $PYTHON qcow2.py "$TEST_IMG" add-header-ext-stdio 0x6803f857
|
||||
_img_info
|
||||
|
||||
echo
|
||||
echo === Image with multiple incompatible feature bits ===
|
||||
echo
|
||||
_make_test_img 64M
|
||||
$PYTHON qcow2.py "$TEST_IMG" set-feature-bit incompatible 61
|
||||
$PYTHON qcow2.py "$TEST_IMG" set-feature-bit incompatible 62
|
||||
$PYTHON qcow2.py "$TEST_IMG" set-feature-bit incompatible 63
|
||||
|
||||
# Without feature table
|
||||
_img_info
|
||||
|
||||
# With feature table containing bit 63
|
||||
printf "\x00\x3f%s" "Test feature" | $PYTHON qcow2.py "$TEST_IMG" add-header-ext-stdio 0x6803f857
|
||||
_img_info
|
||||
|
||||
# With feature table containing bit 61
|
||||
$PYTHON qcow2.py "$TEST_IMG" del-header-ext 0x6803f857
|
||||
printf "\x00\x3d%s" "Test feature" | $PYTHON qcow2.py "$TEST_IMG" add-header-ext-stdio 0x6803f857
|
||||
_img_info
|
||||
|
||||
# With feature table containing bits 61 and 62
|
||||
$PYTHON qcow2.py "$TEST_IMG" del-header-ext 0x6803f857
|
||||
printf "\x00\x3d%s\x00%40s\x00\x3e%s\x00%40s" "test1" "" "test2" "" | $PYTHON qcow2.py "$TEST_IMG" add-header-ext-stdio 0x6803f857
|
||||
_img_info
|
||||
|
||||
# With feature table containing all bits
|
||||
$PYTHON qcow2.py "$TEST_IMG" del-header-ext 0x6803f857
|
||||
printf "\x00\x3d%s\x00%40s\x00\x3e%s\x00%40s\x00\x3f%s\x00%40s" "test1" "" "test2" "" "test3" "" | $PYTHON qcow2.py "$TEST_IMG" add-header-ext-stdio 0x6803f857
|
||||
_img_info
|
||||
|
||||
# With feature table containing unrelated bits, including compatible/autoclear
|
||||
$PYTHON qcow2.py "$TEST_IMG" del-header-ext 0x6803f857
|
||||
printf "\x01\x3d%s\x00%40s\x00\x3e%s\x00%40s\x02\x3f%s\x00%40s\x00\x3c%s\x00%40s" "test1" "" "test2" "" "test3" "" "test4" "" | $PYTHON qcow2.py "$TEST_IMG" add-header-ext-stdio 0x6803f857
|
||||
_img_info
|
||||
|
||||
|
||||
echo === Create image with unknown autoclear feature bit ===
|
||||
echo
|
||||
_make_test_img 64M
|
||||
|
@@ -1,4 +1,39 @@
|
||||
QA output created by 036
|
||||
|
||||
=== Image with unknown incompatible feature bit ===
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
||||
magic 0x514649fb
|
||||
version 3
|
||||
backing_file_offset 0x0
|
||||
backing_file_size 0x0
|
||||
cluster_bits 16
|
||||
size 67108864
|
||||
crypt_method 0
|
||||
l1_size 1
|
||||
l1_table_offset 0x30000
|
||||
refcount_table_offset 0x10000
|
||||
refcount_table_clusters 1
|
||||
nb_snapshots 0
|
||||
snapshot_offset 0x0
|
||||
incompatible_features 0x8000000000000000
|
||||
compatible_features 0x0
|
||||
autoclear_features 0x0
|
||||
refcount_order 4
|
||||
header_length 104
|
||||
|
||||
qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'image' uses a IMGFMT feature which is not supported by this qemu version: Unknown incompatible feature: 8000000000000000
|
||||
qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'image' uses a IMGFMT feature which is not supported by this qemu version: Test feature
|
||||
|
||||
=== Image with multiple incompatible feature bits ===
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
||||
qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'image' uses a IMGFMT feature which is not supported by this qemu version: Unknown incompatible feature: e000000000000000
|
||||
qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'image' uses a IMGFMT feature which is not supported by this qemu version: Test feature, Unknown incompatible feature: 6000000000000000
|
||||
qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'image' uses a IMGFMT feature which is not supported by this qemu version: Test feature, Unknown incompatible feature: c000000000000000
|
||||
qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'image' uses a IMGFMT feature which is not supported by this qemu version: test1, test2, Unknown incompatible feature: 8000000000000000
|
||||
qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'image' uses a IMGFMT feature which is not supported by this qemu version: test1, test2, test3
|
||||
qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'image' uses a IMGFMT feature which is not supported by this qemu version: test2, Unknown incompatible feature: a000000000000000
|
||||
=== Create image with unknown autoclear feature bit ===
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
||||
|
@@ -176,6 +176,10 @@ def cmd_add_header_ext(fd, magic, data):
|
||||
h.extensions.append(QcowHeaderExtension.create(magic, data))
|
||||
h.update(fd)
|
||||
|
||||
def cmd_add_header_ext_stdio(fd, magic):
|
||||
data = sys.stdin.read()
|
||||
cmd_add_header_ext(fd, magic, data)
|
||||
|
||||
def cmd_del_header_ext(fd, magic):
|
||||
try:
|
||||
magic = int(magic, 0)
|
||||
@@ -220,11 +224,12 @@ def cmd_set_feature_bit(fd, group, bit):
|
||||
h.update(fd)
|
||||
|
||||
cmds = [
|
||||
[ 'dump-header', cmd_dump_header, 0, 'Dump image header and header extensions' ],
|
||||
[ 'set-header', cmd_set_header, 2, 'Set a field in the header'],
|
||||
[ 'add-header-ext', cmd_add_header_ext, 2, 'Add a header extension' ],
|
||||
[ 'del-header-ext', cmd_del_header_ext, 1, 'Delete a header extension' ],
|
||||
[ 'set-feature-bit', cmd_set_feature_bit, 2, 'Set a feature bit'],
|
||||
[ 'dump-header', cmd_dump_header, 0, 'Dump image header and header extensions' ],
|
||||
[ 'set-header', cmd_set_header, 2, 'Set a field in the header'],
|
||||
[ 'add-header-ext', cmd_add_header_ext, 2, 'Add a header extension' ],
|
||||
[ 'add-header-ext-stdio', cmd_add_header_ext_stdio, 1, 'Add a header extension, data from stdin' ],
|
||||
[ 'del-header-ext', cmd_del_header_ext, 1, 'Delete a header extension' ],
|
||||
[ 'set-feature-bit', cmd_set_feature_bit, 2, 'Set a feature bit'],
|
||||
]
|
||||
|
||||
def main(filename, cmd, args):
|
||||
|
@@ -15,7 +15,7 @@
|
||||
#include "qemu/timer.h"
|
||||
#include "qemu/sockets.h"
|
||||
|
||||
AioContext *ctx;
|
||||
static AioContext *ctx;
|
||||
|
||||
typedef struct {
|
||||
EventNotifier e;
|
||||
|
@@ -56,7 +56,7 @@ static QemuOptsList opts_list_02 = {
|
||||
},
|
||||
};
|
||||
|
||||
QemuOptsList opts_list_03 = {
|
||||
static QemuOptsList opts_list_03 = {
|
||||
.name = "opts_list_03",
|
||||
.head = QTAILQ_HEAD_INITIALIZER(opts_list_03.head),
|
||||
.desc = {
|
||||
|
@@ -15,10 +15,10 @@
|
||||
#include "block/aio.h"
|
||||
#include "qemu/throttle.h"
|
||||
|
||||
AioContext *ctx;
|
||||
LeakyBucket bkt;
|
||||
ThrottleConfig cfg;
|
||||
ThrottleState ts;
|
||||
static AioContext *ctx;
|
||||
static LeakyBucket bkt;
|
||||
static ThrottleConfig cfg;
|
||||
static ThrottleState ts;
|
||||
|
||||
/* useful function */
|
||||
static bool double_cmp(double x, double y)
|
||||
|
@@ -372,8 +372,8 @@ static void test_primitive_lists(gconstpointer opaque)
|
||||
TestArgs *args = (TestArgs *) opaque;
|
||||
const SerializeOps *ops = args->ops;
|
||||
PrimitiveType *pt = args->test_data;
|
||||
PrimitiveList pl = { .value = { 0 } };
|
||||
PrimitiveList pl_copy = { .value = { 0 } };
|
||||
PrimitiveList pl = { .value = { NULL } };
|
||||
PrimitiveList pl_copy = { .value = { NULL } };
|
||||
PrimitiveList *pl_copy_ptr = &pl_copy;
|
||||
Error *err = NULL;
|
||||
void *serialize_data;
|
||||
@@ -771,7 +771,7 @@ static void test_nested_struct_list(gconstpointer opaque)
|
||||
g_free(args);
|
||||
}
|
||||
|
||||
PrimitiveType pt_values[] = {
|
||||
static PrimitiveType pt_values[] = {
|
||||
/* string tests */
|
||||
{
|
||||
.description = "string_empty",
|
||||
|
@@ -29,8 +29,8 @@
|
||||
#include "migration/vmstate.h"
|
||||
#include "block/coroutine.h"
|
||||
|
||||
char temp_file[] = "/tmp/vmst.test.XXXXXX";
|
||||
int temp_fd;
|
||||
static char temp_file[] = "/tmp/vmst.test.XXXXXX";
|
||||
static int temp_fd;
|
||||
|
||||
/* Fake yield_until_fd_readable() implementation so we don't have to pull the
|
||||
* coroutine code as dependency.
|
||||
|
@@ -76,6 +76,7 @@ typedef struct VhostUserMemoryRegion {
|
||||
uint64_t guest_phys_addr;
|
||||
uint64_t memory_size;
|
||||
uint64_t userspace_addr;
|
||||
uint64_t mmap_offset;
|
||||
} VhostUserMemoryRegion;
|
||||
|
||||
typedef struct VhostUserMemory {
|
||||
@@ -205,6 +206,7 @@ static void read_guest_mem(void)
|
||||
uint32_t *guest_mem;
|
||||
gint64 end_time;
|
||||
int i, j;
|
||||
size_t size;
|
||||
|
||||
g_mutex_lock(data_mutex);
|
||||
|
||||
@@ -231,8 +233,13 @@ static void read_guest_mem(void)
|
||||
|
||||
g_assert_cmpint(memory.regions[i].memory_size, >, 1024);
|
||||
|
||||
guest_mem = mmap(0, memory.regions[i].memory_size,
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED, fds[i], 0);
|
||||
size = memory.regions[i].memory_size + memory.regions[i].mmap_offset;
|
||||
|
||||
guest_mem = mmap(0, size, PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED, fds[i], 0);
|
||||
|
||||
g_assert(guest_mem != MAP_FAILED);
|
||||
guest_mem += (memory.regions[i].mmap_offset / sizeof(*guest_mem));
|
||||
|
||||
for (j = 0; j < 256; j++) {
|
||||
uint32_t a = readl(memory.regions[i].guest_phys_addr + j*4);
|
||||
|
134
tests/wdt_ib700-test.c
Normal file
134
tests/wdt_ib700-test.c
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* QTest testcase for the IB700 watchdog
|
||||
*
|
||||
* Copyright (c) 2014 Red Hat, Inc.
|
||||
*
|
||||
* 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 <glib.h>
|
||||
#include <string.h>
|
||||
#include "libqtest.h"
|
||||
#include "qemu/osdep.h"
|
||||
|
||||
#define NS_PER_SEC 1000000000ULL
|
||||
|
||||
static void qmp_check_no_event(void)
|
||||
{
|
||||
QDict *resp = qmp("{'execute':'query-status'}");
|
||||
g_assert(qdict_haskey(resp, "return"));
|
||||
QDECREF(resp);
|
||||
}
|
||||
|
||||
static QDict *qmp_get_event(const char *name)
|
||||
{
|
||||
QDict *event = qmp("");
|
||||
QDict *data;
|
||||
g_assert(qdict_haskey(event, "event"));
|
||||
g_assert(!strcmp(qdict_get_str(event, "event"), name));
|
||||
|
||||
if (qdict_haskey(event, "data")) {
|
||||
data = qdict_get_qdict(event, "data");
|
||||
QINCREF(data);
|
||||
} else {
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
QDECREF(event);
|
||||
return data;
|
||||
}
|
||||
|
||||
static QDict *ib700_program_and_wait(QTestState *s)
|
||||
{
|
||||
clock_step(NS_PER_SEC * 40);
|
||||
qmp_check_no_event();
|
||||
|
||||
/* 2 second limit */
|
||||
outb(0x443, 14);
|
||||
|
||||
/* Ping */
|
||||
clock_step(NS_PER_SEC);
|
||||
qmp_check_no_event();
|
||||
outb(0x443, 14);
|
||||
|
||||
/* Disable */
|
||||
clock_step(NS_PER_SEC);
|
||||
qmp_check_no_event();
|
||||
outb(0x441, 1);
|
||||
clock_step(3 * NS_PER_SEC);
|
||||
qmp_check_no_event();
|
||||
|
||||
/* Enable and let it fire */
|
||||
outb(0x443, 13);
|
||||
clock_step(3 * NS_PER_SEC);
|
||||
qmp_check_no_event();
|
||||
clock_step(2 * NS_PER_SEC);
|
||||
return qmp_get_event("WATCHDOG");
|
||||
}
|
||||
|
||||
|
||||
static void ib700_pause(void)
|
||||
{
|
||||
QDict *d;
|
||||
QTestState *s = qtest_start("-watchdog-action pause -device ib700");
|
||||
qtest_irq_intercept_in(s, "ioapic");
|
||||
d = ib700_program_and_wait(s);
|
||||
g_assert(!strcmp(qdict_get_str(d, "action"), "pause"));
|
||||
QDECREF(d);
|
||||
d = qmp_get_event("STOP");
|
||||
QDECREF(d);
|
||||
qtest_end();
|
||||
}
|
||||
|
||||
static void ib700_reset(void)
|
||||
{
|
||||
QDict *d;
|
||||
QTestState *s = qtest_start("-watchdog-action reset -device ib700");
|
||||
qtest_irq_intercept_in(s, "ioapic");
|
||||
d = ib700_program_and_wait(s);
|
||||
g_assert(!strcmp(qdict_get_str(d, "action"), "reset"));
|
||||
QDECREF(d);
|
||||
d = qmp_get_event("RESET");
|
||||
QDECREF(d);
|
||||
qtest_end();
|
||||
}
|
||||
|
||||
static void ib700_shutdown(void)
|
||||
{
|
||||
QDict *d;
|
||||
QTestState *s = qtest_start("-watchdog-action reset -no-reboot -device ib700");
|
||||
qtest_irq_intercept_in(s, "ioapic");
|
||||
d = ib700_program_and_wait(s);
|
||||
g_assert(!strcmp(qdict_get_str(d, "action"), "reset"));
|
||||
QDECREF(d);
|
||||
d = qmp_get_event("SHUTDOWN");
|
||||
QDECREF(d);
|
||||
qtest_end();
|
||||
}
|
||||
|
||||
static void ib700_none(void)
|
||||
{
|
||||
QDict *d;
|
||||
QTestState *s = qtest_start("-watchdog-action none -device ib700");
|
||||
qtest_irq_intercept_in(s, "ioapic");
|
||||
d = ib700_program_and_wait(s);
|
||||
g_assert(!strcmp(qdict_get_str(d, "action"), "none"));
|
||||
QDECREF(d);
|
||||
qtest_end();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
g_test_init(&argc, &argv, NULL);
|
||||
qtest_add_func("/wdt_ib700/pause", ib700_pause);
|
||||
qtest_add_func("/wdt_ib700/reset", ib700_reset);
|
||||
qtest_add_func("/wdt_ib700/shutdown", ib700_shutdown);
|
||||
qtest_add_func("/wdt_ib700/none", ib700_none);
|
||||
|
||||
ret = g_test_run();
|
||||
|
||||
return ret;
|
||||
}
|
5
ui/vnc.c
5
ui/vnc.c
@@ -887,6 +887,7 @@ static int find_and_clear_dirty_height(struct VncState *vs,
|
||||
|
||||
static int vnc_update_client(VncState *vs, int has_dirty, bool sync)
|
||||
{
|
||||
vs->has_dirty += has_dirty;
|
||||
if (vs->need_update && vs->csock != -1) {
|
||||
VncDisplay *vd = vs->vd;
|
||||
VncJob *job;
|
||||
@@ -898,7 +899,7 @@ static int vnc_update_client(VncState *vs, int has_dirty, bool sync)
|
||||
/* kernel send buffers are full -> drop frames to throttle */
|
||||
return 0;
|
||||
|
||||
if (!has_dirty && !vs->audio_cap && !vs->force_update)
|
||||
if (!vs->has_dirty && !vs->audio_cap && !vs->force_update)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
@@ -941,6 +942,7 @@ static int vnc_update_client(VncState *vs, int has_dirty, bool sync)
|
||||
vnc_jobs_join(vs);
|
||||
}
|
||||
vs->force_update = 0;
|
||||
vs->has_dirty = 0;
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -1878,6 +1880,7 @@ static void framebuffer_update_request(VncState *vs, int incremental,
|
||||
return;
|
||||
}
|
||||
|
||||
vs->force_update = 1;
|
||||
vnc_set_area_dirty(vs->dirty, width, height, x, y, w, h);
|
||||
}
|
||||
|
||||
|
1
ui/vnc.h
1
ui/vnc.h
@@ -263,6 +263,7 @@ struct VncState
|
||||
VncDisplay *vd;
|
||||
int need_update;
|
||||
int force_update;
|
||||
int has_dirty;
|
||||
uint32_t features;
|
||||
int absolute;
|
||||
int last_x;
|
||||
|
@@ -202,18 +202,13 @@ static void module_load(module_init_type type)
|
||||
for (i = 0; i < ARRAY_SIZE(dirs); i++) {
|
||||
fname = g_strdup_printf("%s/%s%s", dirs[i], *mp, HOST_DSOSUF);
|
||||
ret = module_load_file(fname);
|
||||
g_free(fname);
|
||||
fname = NULL;
|
||||
/* Try loading until loaded a module file */
|
||||
if (!ret) {
|
||||
break;
|
||||
}
|
||||
g_free(fname);
|
||||
fname = NULL;
|
||||
}
|
||||
if (ret == -ENOENT) {
|
||||
fprintf(stderr, "Can't find module: %s\n", *mp);
|
||||
}
|
||||
|
||||
g_free(fname);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dirs); i++) {
|
||||
|
13
vl.c
13
vl.c
@@ -2823,15 +2823,25 @@ static int object_set_property(const char *name, const char *value, void *opaque
|
||||
Object *obj = OBJECT(opaque);
|
||||
StringInputVisitor *siv;
|
||||
Error *local_err = NULL;
|
||||
char *c, *qom_name;
|
||||
|
||||
if (strcmp(name, "qom-type") == 0 || strcmp(name, "id") == 0 ||
|
||||
strcmp(name, "type") == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
qom_name = g_strdup(name);
|
||||
c = qom_name;
|
||||
while (*c++) {
|
||||
if (*c == '_') {
|
||||
*c = '-';
|
||||
}
|
||||
}
|
||||
|
||||
siv = string_input_visitor_new(value);
|
||||
object_property_set(obj, string_input_get_visitor(siv), name, &local_err);
|
||||
object_property_set(obj, string_input_get_visitor(siv), qom_name, &local_err);
|
||||
string_input_visitor_cleanup(siv);
|
||||
g_free(qom_name);
|
||||
|
||||
if (local_err) {
|
||||
qerror_report_err(local_err);
|
||||
@@ -3315,6 +3325,7 @@ int main(int argc, char **argv, char **envp)
|
||||
error_report("ram size too large");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
maxram_size = ram_size;
|
||||
|
||||
maxmem_str = qemu_opt_get(opts, "maxmem");
|
||||
slots_str = qemu_opt_get(opts, "slots");
|
||||
|
@@ -165,7 +165,7 @@ static void xen_ram_init(ram_addr_t *below_4g_mem_size,
|
||||
PC_MACHINE_MAX_RAM_BELOW_4G,
|
||||
&error_abort);
|
||||
|
||||
/* Handle the machine opt max-ram-below-4g. It is basicly doing
|
||||
/* Handle the machine opt max-ram-below-4g. It is basically doing
|
||||
* min(xen limit, user limit).
|
||||
*/
|
||||
if (HVM_BELOW_4G_RAM_END <= user_lowmem) {
|
||||
|
Reference in New Issue
Block a user