Compare commits
138
Commits
v2.1.0-rc2
...
v2.1.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
562d6b4f7f | ||
|
|
9a72433843 | ||
|
|
00dd2b22f6 | ||
|
|
80f4d021f0 | ||
|
|
074e347138 | ||
|
|
9e8d994111 | ||
|
|
a56b9cfd86 | ||
|
|
07178559a9 | ||
|
|
3cb451edb2 | ||
|
|
82d80e1f0b | ||
|
|
5dd076a9f8 | ||
|
|
257e9cfce2 | ||
|
|
1aa87d3689 | ||
|
|
7fe5418d9f | ||
|
|
c5042f04f7 | ||
|
|
cf29a88391 | ||
|
|
08743db463 | ||
|
|
d9c06c0d79 | ||
|
|
f321710cd4 | ||
|
|
ec48bfd57b | ||
|
|
eb36f79d59 | ||
|
|
34d41c1a20 | ||
|
|
6f8d05a8f8 | ||
|
|
5e83dae44e | ||
|
|
ff34ca00fd | ||
|
|
e685d2abf7 | ||
|
|
67cfda8776 | ||
|
|
4fd144f8f5 | ||
|
|
ea774b8dd0 | ||
|
|
3e8966df02 | ||
|
|
ba8576f338 | ||
|
|
07f8c97f84 | ||
|
|
72c9c9a05e | ||
|
|
3d8cc86e4f | ||
|
|
0824ca6bd1 | ||
|
|
feb633411f | ||
|
|
75ada6b763 | ||
|
|
be3af755ac | ||
|
|
bfe3e6f5e3 | ||
|
|
cd4acff8d0 | ||
|
|
4b59161253 | ||
|
|
fab7560c35 | ||
|
|
16c92cd629 | ||
|
|
dea6efe883 | ||
|
|
8c4edd743c | ||
|
|
504e2a7139 | ||
|
|
2f6d5e1c9c | ||
|
|
20463dc874 | ||
|
|
2a575c450e | ||
|
|
1ad9dcec47 | ||
|
|
ba1bc81991 | ||
|
|
948574e0d2 | ||
|
|
044af98ea8 | ||
|
|
7c68c5402a | ||
|
|
bd4740621c | ||
|
|
e22d5dc073 | ||
|
|
dfd4808222 | ||
|
|
5f26e63b17 | ||
|
|
42f7a13178 | ||
|
|
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 |
No files matched your search
+1
-1
@@ -304,7 +304,7 @@ host_memory_backend_memory_complete(UserCreatable *uc, Error **errp)
|
||||
/* ensure policy won't be ignored in case memory is preallocated
|
||||
* before mbind(). note: MPOL_MF_STRICT is ignored on hugepages so
|
||||
* this doesn't catch hugepage case. */
|
||||
unsigned flags = MPOL_MF_STRICT;
|
||||
unsigned flags = MPOL_MF_STRICT | MPOL_MF_MOVE;
|
||||
|
||||
/* check for invalid host-nodes and policies and give more verbose
|
||||
* error messages than mbind(). */
|
||||
|
||||
@@ -169,6 +169,7 @@ static void rng_egd_set_chardev(Object *obj, const char *value, Error **errp)
|
||||
if (b->opened) {
|
||||
error_set(errp, QERR_PERMISSION_DENIED);
|
||||
} else {
|
||||
g_free(s->chr_name);
|
||||
s->chr_name = g_strdup(value);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -449,6 +449,10 @@ static void error_callback_bh(void *opaque)
|
||||
static void blkdebug_aio_cancel(BlockDriverAIOCB *blockacb)
|
||||
{
|
||||
BlkdebugAIOCB *acb = container_of(blockacb, BlkdebugAIOCB, common);
|
||||
if (acb->bh) {
|
||||
qemu_bh_delete(acb->bh);
|
||||
acb->bh = NULL;
|
||||
}
|
||||
qemu_aio_release(acb);
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -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
|
||||
@@ -1510,7 +1509,8 @@ static int iscsi_truncate(BlockDriverState *bs, int64_t offset)
|
||||
if (iscsilun->allocationmap != NULL) {
|
||||
g_free(iscsilun->allocationmap);
|
||||
iscsilun->allocationmap =
|
||||
bitmap_new(DIV_ROUND_UP(bs->total_sectors,
|
||||
bitmap_new(DIV_ROUND_UP(sector_lun2qemu(iscsilun->num_blocks,
|
||||
iscsilun),
|
||||
iscsilun->cluster_sectors));
|
||||
}
|
||||
|
||||
|
||||
+17
-8
@@ -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)
|
||||
|
||||
+1
-3
@@ -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
|
||||
|
||||
+37
-11
@@ -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)
|
||||
@@ -730,6 +747,15 @@ static ssize_t handle_aiocb_rw_linear(RawPosixAIOData *aiocb, char *buf)
|
||||
}
|
||||
if (len == -1 && errno == EINTR) {
|
||||
continue;
|
||||
} else if (len == -1 && errno == EINVAL &&
|
||||
(aiocb->bs->open_flags & BDRV_O_NOCACHE) &&
|
||||
!(aiocb->aio_type & QEMU_AIO_WRITE) &&
|
||||
offset > 0) {
|
||||
/* O_DIRECT pread() may fail with EINVAL when offset is unaligned
|
||||
* after a short read. Assume that O_DIRECT short reads only occur
|
||||
* at EOF. Therefore this is a short read, not an I/O error.
|
||||
*/
|
||||
break;
|
||||
} else if (len == -1) {
|
||||
offset = -errno;
|
||||
break;
|
||||
|
||||
+1
-2
@@ -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)
|
||||
|
||||
+1
-1
@@ -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)
|
||||
|
||||
+1
-3
@@ -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,
|
||||
|
||||
@@ -1723,6 +1723,7 @@ fi
|
||||
|
||||
cat > $TMPC <<EOF
|
||||
#include <sys/socket.h>
|
||||
#include <linux/ip.h>
|
||||
int main(void) { return sizeof(struct mmsghdr); }
|
||||
EOF
|
||||
if compile_prog "" "" ; then
|
||||
|
||||
+74
-6
@@ -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
|
||||
------
|
||||
|
||||
|
||||
@@ -430,15 +430,50 @@ static int cpu_common_post_load(void *opaque, int version_id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cpu_common_pre_load(void *opaque)
|
||||
{
|
||||
CPUState *cpu = opaque;
|
||||
|
||||
cpu->exception_index = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool cpu_common_exception_index_needed(void *opaque)
|
||||
{
|
||||
CPUState *cpu = opaque;
|
||||
|
||||
return cpu->exception_index != 0;
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_cpu_common_exception_index = {
|
||||
.name = "cpu_common/exception_index",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_INT32(exception_index, CPUState),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
const VMStateDescription vmstate_cpu_common = {
|
||||
.name = "cpu_common",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.pre_load = cpu_common_pre_load,
|
||||
.post_load = cpu_common_post_load,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT32(halted, CPUState),
|
||||
VMSTATE_UINT32(interrupt_request, CPUState),
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
.subsections = (VMStateSubsection[]) {
|
||||
{
|
||||
.vmsd = &vmstate_cpu_common_exception_index,
|
||||
.needed = cpu_common_exception_index_needed,
|
||||
} , {
|
||||
/* empty */
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1568,8 +1603,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 +2012,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 +2368,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 +2606,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -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;
|
||||
|
||||
+1
-1
@@ -231,7 +231,7 @@ static uint64_t pci_read(void *opaque, hwaddr addr, unsigned int size)
|
||||
uint32_t val = 0;
|
||||
int bsel = s->hotplug_select;
|
||||
|
||||
if (bsel < 0 || bsel > ACPI_PCIHP_MAX_HOTPLUG_BUS) {
|
||||
if (bsel < 0 || bsel >= ACPI_PCIHP_MAX_HOTPLUG_BUS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+27
-6
@@ -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 */
|
||||
@@ -194,20 +194,41 @@ static void fdt_add_psci_node(const VirtBoardInfo *vbi)
|
||||
|
||||
/* No PSCI for TCG yet */
|
||||
if (kvm_enabled()) {
|
||||
uint32_t cpu_suspend_fn;
|
||||
uint32_t cpu_off_fn;
|
||||
uint32_t cpu_on_fn;
|
||||
uint32_t migrate_fn;
|
||||
|
||||
qemu_fdt_add_subnode(fdt, "/psci");
|
||||
if (armcpu->psci_version == 2) {
|
||||
const char comp[] = "arm,psci-0.2\0arm,psci";
|
||||
qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
|
||||
|
||||
cpu_off_fn = QEMU_PSCI_0_2_FN_CPU_OFF;
|
||||
if (arm_feature(&armcpu->env, ARM_FEATURE_AARCH64)) {
|
||||
cpu_suspend_fn = QEMU_PSCI_0_2_FN64_CPU_SUSPEND;
|
||||
cpu_on_fn = QEMU_PSCI_0_2_FN64_CPU_ON;
|
||||
migrate_fn = QEMU_PSCI_0_2_FN64_MIGRATE;
|
||||
} else {
|
||||
cpu_suspend_fn = QEMU_PSCI_0_2_FN_CPU_SUSPEND;
|
||||
cpu_on_fn = QEMU_PSCI_0_2_FN_CPU_ON;
|
||||
migrate_fn = QEMU_PSCI_0_2_FN_MIGRATE;
|
||||
}
|
||||
} else {
|
||||
qemu_fdt_setprop_string(fdt, "/psci", "compatible", "arm,psci");
|
||||
|
||||
cpu_suspend_fn = QEMU_PSCI_0_1_FN_CPU_SUSPEND;
|
||||
cpu_off_fn = QEMU_PSCI_0_1_FN_CPU_OFF;
|
||||
cpu_on_fn = QEMU_PSCI_0_1_FN_CPU_ON;
|
||||
migrate_fn = QEMU_PSCI_0_1_FN_MIGRATE;
|
||||
}
|
||||
|
||||
qemu_fdt_setprop_string(fdt, "/psci", "method", "hvc");
|
||||
qemu_fdt_setprop_cell(fdt, "/psci", "cpu_suspend",
|
||||
PSCI_FN_CPU_SUSPEND);
|
||||
qemu_fdt_setprop_cell(fdt, "/psci", "cpu_off", PSCI_FN_CPU_OFF);
|
||||
qemu_fdt_setprop_cell(fdt, "/psci", "cpu_on", PSCI_FN_CPU_ON);
|
||||
qemu_fdt_setprop_cell(fdt, "/psci", "migrate", PSCI_FN_MIGRATE);
|
||||
|
||||
qemu_fdt_setprop_cell(fdt, "/psci", "cpu_suspend", cpu_suspend_fn);
|
||||
qemu_fdt_setprop_cell(fdt, "/psci", "cpu_off", cpu_off_fn);
|
||||
qemu_fdt_setprop_cell(fdt, "/psci", "cpu_on", cpu_on_fn);
|
||||
qemu_fdt_setprop_cell(fdt, "/psci", "migrate", migrate_fn);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -469,8 +469,9 @@ static void virtio_blk_dma_restart_bh(void *opaque)
|
||||
s->rq = NULL;
|
||||
|
||||
while (req) {
|
||||
VirtIOBlockReq *next = req->next;
|
||||
virtio_blk_handle_request(req, &mrb);
|
||||
req = req->next;
|
||||
req = next;
|
||||
}
|
||||
|
||||
virtio_submit_multiwrite(s->bs, &mrb);
|
||||
|
||||
+11
-4
@@ -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);
|
||||
/*
|
||||
|
||||
+12
-4
@@ -24,6 +24,7 @@ static void machine_set_accel(Object *obj, const char *value, Error **errp)
|
||||
{
|
||||
MachineState *ms = MACHINE(obj);
|
||||
|
||||
g_free(ms->accel);
|
||||
ms->accel = g_strdup(value);
|
||||
}
|
||||
|
||||
@@ -79,6 +80,7 @@ static void machine_set_kernel(Object *obj, const char *value, Error **errp)
|
||||
{
|
||||
MachineState *ms = MACHINE(obj);
|
||||
|
||||
g_free(ms->kernel_filename);
|
||||
ms->kernel_filename = g_strdup(value);
|
||||
}
|
||||
|
||||
@@ -93,6 +95,7 @@ static void machine_set_initrd(Object *obj, const char *value, Error **errp)
|
||||
{
|
||||
MachineState *ms = MACHINE(obj);
|
||||
|
||||
g_free(ms->initrd_filename);
|
||||
ms->initrd_filename = g_strdup(value);
|
||||
}
|
||||
|
||||
@@ -107,6 +110,7 @@ static void machine_set_append(Object *obj, const char *value, Error **errp)
|
||||
{
|
||||
MachineState *ms = MACHINE(obj);
|
||||
|
||||
g_free(ms->kernel_cmdline);
|
||||
ms->kernel_cmdline = g_strdup(value);
|
||||
}
|
||||
|
||||
@@ -121,6 +125,7 @@ static void machine_set_dtb(Object *obj, const char *value, Error **errp)
|
||||
{
|
||||
MachineState *ms = MACHINE(obj);
|
||||
|
||||
g_free(ms->dtb);
|
||||
ms->dtb = g_strdup(value);
|
||||
}
|
||||
|
||||
@@ -135,6 +140,7 @@ static void machine_set_dumpdtb(Object *obj, const char *value, Error **errp)
|
||||
{
|
||||
MachineState *ms = MACHINE(obj);
|
||||
|
||||
g_free(ms->dumpdtb);
|
||||
ms->dumpdtb = g_strdup(value);
|
||||
}
|
||||
|
||||
@@ -176,6 +182,7 @@ static void machine_set_dt_compatible(Object *obj, const char *value, Error **er
|
||||
{
|
||||
MachineState *ms = MACHINE(obj);
|
||||
|
||||
g_free(ms->dt_compatible);
|
||||
ms->dt_compatible = g_strdup(value);
|
||||
}
|
||||
|
||||
@@ -232,6 +239,7 @@ static void machine_set_firmware(Object *obj, const char *value, Error **errp)
|
||||
{
|
||||
MachineState *ms = MACHINE(obj);
|
||||
|
||||
g_free(ms->firmware);
|
||||
ms->firmware = g_strdup(value);
|
||||
}
|
||||
|
||||
@@ -239,11 +247,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 +265,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);
|
||||
|
||||
@@ -138,7 +138,9 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
|
||||
if (qemu_spice_rect_is_empty(qxl->dirty+i)) {
|
||||
break;
|
||||
}
|
||||
if (qxl->dirty[i].left > qxl->dirty[i].right ||
|
||||
if (qxl->dirty[i].left < 0 ||
|
||||
qxl->dirty[i].top < 0 ||
|
||||
qxl->dirty[i].left > qxl->dirty[i].right ||
|
||||
qxl->dirty[i].top > qxl->dirty[i].bottom ||
|
||||
qxl->dirty[i].right > qxl->guest_primary.surface.width ||
|
||||
qxl->dirty[i].bottom > qxl->guest_primary.surface.height) {
|
||||
|
||||
@@ -2063,6 +2063,7 @@ static int qxl_init_primary(PCIDevice *dev)
|
||||
|
||||
qxl->id = 0;
|
||||
qxl_init_ramsize(qxl);
|
||||
vga->vbe_size = qxl->vgamem_size;
|
||||
vga->vram_size_mb = qxl->vga.vram_size >> 20;
|
||||
vga_common_init(vga, OBJECT(dev), true);
|
||||
vga_init(vga, OBJECT(dev),
|
||||
|
||||
+99
-60
@@ -580,6 +580,93 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Sanity check vbe register writes.
|
||||
*
|
||||
* As we don't have a way to signal errors to the guest in the bochs
|
||||
* dispi interface we'll go adjust the registers to the closest valid
|
||||
* value.
|
||||
*/
|
||||
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)) {
|
||||
/* vbe is turned off -- nothing to do */
|
||||
return;
|
||||
}
|
||||
|
||||
/* check depth */
|
||||
switch (r[VBE_DISPI_INDEX_BPP]) {
|
||||
case 4:
|
||||
case 8:
|
||||
case 16:
|
||||
case 24:
|
||||
case 32:
|
||||
bits = r[VBE_DISPI_INDEX_BPP];
|
||||
break;
|
||||
case 15:
|
||||
bits = 16;
|
||||
break;
|
||||
default:
|
||||
bits = r[VBE_DISPI_INDEX_BPP] = 8;
|
||||
break;
|
||||
}
|
||||
|
||||
/* check width */
|
||||
r[VBE_DISPI_INDEX_XRES] &= ~7u;
|
||||
if (r[VBE_DISPI_INDEX_XRES] == 0) {
|
||||
r[VBE_DISPI_INDEX_XRES] = 8;
|
||||
}
|
||||
if (r[VBE_DISPI_INDEX_XRES] > VBE_DISPI_MAX_XRES) {
|
||||
r[VBE_DISPI_INDEX_XRES] = VBE_DISPI_MAX_XRES;
|
||||
}
|
||||
r[VBE_DISPI_INDEX_VIRT_WIDTH] &= ~7u;
|
||||
if (r[VBE_DISPI_INDEX_VIRT_WIDTH] > VBE_DISPI_MAX_XRES) {
|
||||
r[VBE_DISPI_INDEX_VIRT_WIDTH] = VBE_DISPI_MAX_XRES;
|
||||
}
|
||||
if (r[VBE_DISPI_INDEX_VIRT_WIDTH] < r[VBE_DISPI_INDEX_XRES]) {
|
||||
r[VBE_DISPI_INDEX_VIRT_WIDTH] = r[VBE_DISPI_INDEX_XRES];
|
||||
}
|
||||
|
||||
/* check height */
|
||||
linelength = r[VBE_DISPI_INDEX_VIRT_WIDTH] * bits / 8;
|
||||
maxy = s->vbe_size / linelength;
|
||||
if (r[VBE_DISPI_INDEX_YRES] == 0) {
|
||||
r[VBE_DISPI_INDEX_YRES] = 1;
|
||||
}
|
||||
if (r[VBE_DISPI_INDEX_YRES] > VBE_DISPI_MAX_YRES) {
|
||||
r[VBE_DISPI_INDEX_YRES] = VBE_DISPI_MAX_YRES;
|
||||
}
|
||||
if (r[VBE_DISPI_INDEX_YRES] > maxy) {
|
||||
r[VBE_DISPI_INDEX_YRES] = maxy;
|
||||
}
|
||||
|
||||
/* check offset */
|
||||
if (r[VBE_DISPI_INDEX_X_OFFSET] > VBE_DISPI_MAX_XRES) {
|
||||
r[VBE_DISPI_INDEX_X_OFFSET] = VBE_DISPI_MAX_XRES;
|
||||
}
|
||||
if (r[VBE_DISPI_INDEX_Y_OFFSET] > VBE_DISPI_MAX_YRES) {
|
||||
r[VBE_DISPI_INDEX_Y_OFFSET] = VBE_DISPI_MAX_YRES;
|
||||
}
|
||||
offset = r[VBE_DISPI_INDEX_X_OFFSET] * bits / 8;
|
||||
offset += r[VBE_DISPI_INDEX_Y_OFFSET] * linelength;
|
||||
if (offset + r[VBE_DISPI_INDEX_YRES] * linelength > s->vbe_size) {
|
||||
r[VBE_DISPI_INDEX_Y_OFFSET] = 0;
|
||||
offset = r[VBE_DISPI_INDEX_X_OFFSET] * bits / 8;
|
||||
if (offset + r[VBE_DISPI_INDEX_YRES] * linelength > s->vbe_size) {
|
||||
r[VBE_DISPI_INDEX_X_OFFSET] = 0;
|
||||
offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* update vga state */
|
||||
r[VBE_DISPI_INDEX_VIRT_HEIGHT] = maxy;
|
||||
s->vbe_line_offset = linelength;
|
||||
s->vbe_start_addr = offset / 4;
|
||||
}
|
||||
|
||||
static uint32_t vbe_ioport_read_index(void *opaque, uint32_t addr)
|
||||
{
|
||||
VGACommonState *s = opaque;
|
||||
@@ -614,7 +701,7 @@ uint32_t vbe_ioport_read_data(void *opaque, uint32_t addr)
|
||||
val = s->vbe_regs[s->vbe_index];
|
||||
}
|
||||
} else if (s->vbe_index == VBE_DISPI_INDEX_VIDEO_MEMORY_64K) {
|
||||
val = s->vram_size / (64 * 1024);
|
||||
val = s->vbe_size / (64 * 1024);
|
||||
} else {
|
||||
val = 0;
|
||||
}
|
||||
@@ -649,22 +736,13 @@ void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
|
||||
}
|
||||
break;
|
||||
case VBE_DISPI_INDEX_XRES:
|
||||
if ((val <= VBE_DISPI_MAX_XRES) && ((val & 7) == 0)) {
|
||||
s->vbe_regs[s->vbe_index] = val;
|
||||
}
|
||||
break;
|
||||
case VBE_DISPI_INDEX_YRES:
|
||||
if (val <= VBE_DISPI_MAX_YRES) {
|
||||
s->vbe_regs[s->vbe_index] = val;
|
||||
}
|
||||
break;
|
||||
case VBE_DISPI_INDEX_BPP:
|
||||
if (val == 0)
|
||||
val = 8;
|
||||
if (val == 4 || val == 8 || val == 15 ||
|
||||
val == 16 || val == 24 || val == 32) {
|
||||
s->vbe_regs[s->vbe_index] = val;
|
||||
}
|
||||
case VBE_DISPI_INDEX_VIRT_WIDTH:
|
||||
case VBE_DISPI_INDEX_X_OFFSET:
|
||||
case VBE_DISPI_INDEX_Y_OFFSET:
|
||||
s->vbe_regs[s->vbe_index] = val;
|
||||
vbe_fixup_regs(s);
|
||||
break;
|
||||
case VBE_DISPI_INDEX_BANK:
|
||||
if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
|
||||
@@ -681,19 +759,11 @@ void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
|
||||
!(s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) {
|
||||
int h, shift_control;
|
||||
|
||||
s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] =
|
||||
s->vbe_regs[VBE_DISPI_INDEX_XRES];
|
||||
s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] =
|
||||
s->vbe_regs[VBE_DISPI_INDEX_YRES];
|
||||
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;
|
||||
|
||||
if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
|
||||
s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 1;
|
||||
else
|
||||
s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] *
|
||||
((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
|
||||
s->vbe_start_addr = 0;
|
||||
s->vbe_regs[VBE_DISPI_INDEX_ENABLE] |= VBE_DISPI_ENABLED;
|
||||
vbe_fixup_regs(s);
|
||||
|
||||
/* clear the screen (should be done in BIOS) */
|
||||
if (!(val & VBE_DISPI_NOCLEARMEM)) {
|
||||
@@ -742,40 +812,6 @@ void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
|
||||
s->vbe_regs[s->vbe_index] = val;
|
||||
vga_update_memory_access(s);
|
||||
break;
|
||||
case VBE_DISPI_INDEX_VIRT_WIDTH:
|
||||
{
|
||||
int w, h, line_offset;
|
||||
|
||||
if (val < s->vbe_regs[VBE_DISPI_INDEX_XRES])
|
||||
return;
|
||||
w = val;
|
||||
if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
|
||||
line_offset = w >> 1;
|
||||
else
|
||||
line_offset = w * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
|
||||
h = s->vram_size / line_offset;
|
||||
/* XXX: support weird bochs semantics ? */
|
||||
if (h < s->vbe_regs[VBE_DISPI_INDEX_YRES])
|
||||
return;
|
||||
s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = w;
|
||||
s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = h;
|
||||
s->vbe_line_offset = line_offset;
|
||||
}
|
||||
break;
|
||||
case VBE_DISPI_INDEX_X_OFFSET:
|
||||
case VBE_DISPI_INDEX_Y_OFFSET:
|
||||
{
|
||||
int x;
|
||||
s->vbe_regs[s->vbe_index] = val;
|
||||
s->vbe_start_addr = s->vbe_line_offset * s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET];
|
||||
x = s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET];
|
||||
if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
|
||||
s->vbe_start_addr += x >> 1;
|
||||
else
|
||||
s->vbe_start_addr += x * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
|
||||
s->vbe_start_addr >>= 2;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -2289,6 +2325,9 @@ void vga_common_init(VGACommonState *s, Object *obj, bool global_vmstate)
|
||||
s->vram_size <<= 1;
|
||||
}
|
||||
s->vram_size_mb = s->vram_size >> 20;
|
||||
if (!s->vbe_size) {
|
||||
s->vbe_size = s->vram_size;
|
||||
}
|
||||
|
||||
s->is_vbe_vmstate = 1;
|
||||
memory_region_init_ram(&s->vram, obj, "vga.vram", s->vram_size);
|
||||
|
||||
@@ -93,6 +93,7 @@ typedef struct VGACommonState {
|
||||
MemoryRegion vram_vbe;
|
||||
uint32_t vram_size;
|
||||
uint32_t vram_size_mb; /* property */
|
||||
uint32_t vbe_size;
|
||||
uint32_t latch;
|
||||
MemoryRegion *chain4_alias;
|
||||
uint8_t sr_index;
|
||||
|
||||
+97
-10
@@ -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)
|
||||
@@ -529,6 +546,12 @@ static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
|
||||
(1 << ACPI_FADT_F_SLP_BUTTON) |
|
||||
(1 << ACPI_FADT_F_RTC_S4));
|
||||
fadt->flags |= cpu_to_le32(1 << ACPI_FADT_F_USE_PLATFORM_CLOCK);
|
||||
/* APIC destination mode ("Flat Logical") has an upper limit of 8 CPUs
|
||||
* For more than 8 CPUs, "Clustered Logical" mode has to be used
|
||||
*/
|
||||
if (max_cpus > 8) {
|
||||
fadt->flags |= cpu_to_le32(1 << ACPI_FADT_F_FORCE_APIC_CLUSTER_MODEL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -768,11 +791,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 +811,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 +832,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 +877,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 +887,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 +905,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 +1170,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. */
|
||||
@@ -1359,7 +1399,7 @@ build_rsdp(GArray *rsdp_table, GArray *linker, unsigned rsdt)
|
||||
{
|
||||
AcpiRsdpDescriptor *rsdp = acpi_data_push(rsdp_table, sizeof *rsdp);
|
||||
|
||||
bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, 1,
|
||||
bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, 16,
|
||||
true /* fseg memory */);
|
||||
|
||||
memcpy(&rsdp->signature, "RSD PTR ", 8);
|
||||
@@ -1440,13 +1480,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 +1515,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 +1561,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);
|
||||
|
||||
+38
-50
@@ -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) {
|
||||
@@ -314,7 +302,7 @@ DefinitionBlock (
|
||||
/****************************************************************
|
||||
* General purpose events
|
||||
****************************************************************/
|
||||
External(\_SB.PCI0.MEMORY_HOPTLUG_DEVICE.MEMORY_SLOT_SCAN_METHOD, MethodObj)
|
||||
External(\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_SCAN_METHOD, MethodObj)
|
||||
|
||||
Scope(\_GPE) {
|
||||
Name(_HID, "ACPI0006")
|
||||
@@ -333,7 +321,7 @@ DefinitionBlock (
|
||||
}
|
||||
Method(_E03) {
|
||||
// Memory hotplug event
|
||||
\_SB.PCI0.MEMORY_HOPTLUG_DEVICE.MEMORY_SLOT_SCAN_METHOD()
|
||||
\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_SCAN_METHOD()
|
||||
}
|
||||
Method(_L04) {
|
||||
}
|
||||
|
||||
+107
-1799
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));
|
||||
|
||||
+12
-4
@@ -72,8 +72,15 @@
|
||||
#define DPRINTF(fmt, ...)
|
||||
#endif
|
||||
|
||||
/* Leave a chunk of memory at the top of RAM for the BIOS ACPI tables. */
|
||||
#define ACPI_DATA_SIZE 0x10000
|
||||
/* Leave a chunk of memory at the top of RAM for the BIOS ACPI tables
|
||||
* (128K) and other BIOS datastructures (less than 4K reported to be used at
|
||||
* the moment, 32K should be enough for a while). */
|
||||
unsigned acpi_data_size = 0x20000 + 0x8000;
|
||||
void pc_set_legacy_acpi_data_size(void)
|
||||
{
|
||||
acpi_data_size = 0x10000;
|
||||
}
|
||||
|
||||
#define BIOS_CFG_IOPORT 0x510
|
||||
#define FW_CFG_ACPI_TABLES (FW_CFG_ARCH_LOCAL + 0)
|
||||
#define FW_CFG_SMBIOS_ENTRIES (FW_CFG_ARCH_LOCAL + 1)
|
||||
@@ -811,8 +818,9 @@ static void load_linux(FWCfgState *fw_cfg,
|
||||
initrd_max = 0x37ffffff;
|
||||
}
|
||||
|
||||
if (initrd_max >= max_ram_size-ACPI_DATA_SIZE)
|
||||
initrd_max = max_ram_size-ACPI_DATA_SIZE-1;
|
||||
if (initrd_max >= max_ram_size - acpi_data_size) {
|
||||
initrd_max = max_ram_size - acpi_data_size - 1;
|
||||
}
|
||||
|
||||
fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_ADDR, cmdline_addr);
|
||||
fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, strlen(kernel_cmdline)+1);
|
||||
|
||||
+24
-12
@@ -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,8 +299,26 @@ 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;
|
||||
pc_set_legacy_acpi_data_size();
|
||||
}
|
||||
|
||||
static void pc_compat_1_7(MachineState *machine)
|
||||
@@ -307,6 +327,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 +407,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);
|
||||
}
|
||||
|
||||
|
||||
+7
-1
@@ -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 */
|
||||
@@ -277,6 +282,7 @@ static void pc_compat_2_0(MachineState *machine)
|
||||
{
|
||||
smbios_legacy_mode = true;
|
||||
has_reserved_memory = false;
|
||||
pc_set_legacy_acpi_data_size();
|
||||
}
|
||||
|
||||
static void pc_compat_1_7(MachineState *machine)
|
||||
|
||||
@@ -410,7 +410,7 @@ DefinitionBlock (
|
||||
/****************************************************************
|
||||
* General purpose events
|
||||
****************************************************************/
|
||||
External(\_SB.PCI0.MEMORY_HOPTLUG_DEVICE.MEMORY_SLOT_SCAN_METHOD, MethodObj)
|
||||
External(\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_SCAN_METHOD, MethodObj)
|
||||
|
||||
Scope(\_GPE) {
|
||||
Name(_HID, "ACPI0006")
|
||||
@@ -425,7 +425,7 @@ DefinitionBlock (
|
||||
}
|
||||
Method(_E03) {
|
||||
// Memory hotplug event
|
||||
\_SB.PCI0.MEMORY_HOPTLUG_DEVICE.MEMORY_SLOT_SCAN_METHOD()
|
||||
\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_SCAN_METHOD()
|
||||
}
|
||||
Method(_L04) {
|
||||
}
|
||||
|
||||
@@ -39,10 +39,10 @@ ACPI_EXTRACT_ALL_CODE ssdm_mem_aml
|
||||
DefinitionBlock ("ssdt-mem.aml", "SSDT", 0x02, "BXPC", "CSSDT", 0x1)
|
||||
{
|
||||
|
||||
External(\_SB.PCI0.MEMORY_HOPTLUG_DEVICE.MEMORY_SLOT_CRS_METHOD, MethodObj)
|
||||
External(\_SB.PCI0.MEMORY_HOPTLUG_DEVICE.MEMORY_SLOT_STATUS_METHOD, MethodObj)
|
||||
External(\_SB.PCI0.MEMORY_HOPTLUG_DEVICE.MEMORY_SLOT_OST_METHOD, MethodObj)
|
||||
External(\_SB.PCI0.MEMORY_HOPTLUG_DEVICE.MEMORY_SLOT_PROXIMITY_METHOD, MethodObj)
|
||||
External(\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_CRS_METHOD, MethodObj)
|
||||
External(\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_STATUS_METHOD, MethodObj)
|
||||
External(\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_OST_METHOD, MethodObj)
|
||||
External(\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_PROXIMITY_METHOD, MethodObj)
|
||||
|
||||
Scope(\_SB) {
|
||||
/* v------------------ DO NOT EDIT ------------------v */
|
||||
@@ -58,19 +58,19 @@ DefinitionBlock ("ssdt-mem.aml", "SSDT", 0x02, "BXPC", "CSSDT", 0x1)
|
||||
Name(_HID, EISAID("PNP0C80"))
|
||||
|
||||
Method(_CRS, 0) {
|
||||
Return(\_SB.PCI0.MEMORY_HOPTLUG_DEVICE.MEMORY_SLOT_CRS_METHOD(_UID))
|
||||
Return(\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_CRS_METHOD(_UID))
|
||||
}
|
||||
|
||||
Method(_STA, 0) {
|
||||
Return(\_SB.PCI0.MEMORY_HOPTLUG_DEVICE.MEMORY_SLOT_STATUS_METHOD(_UID))
|
||||
Return(\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_STATUS_METHOD(_UID))
|
||||
}
|
||||
|
||||
Method(_PXM, 0) {
|
||||
Return(\_SB.PCI0.MEMORY_HOPTLUG_DEVICE.MEMORY_SLOT_PROXIMITY_METHOD(_UID))
|
||||
Return(\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_PROXIMITY_METHOD(_UID))
|
||||
}
|
||||
|
||||
Method(_OST, 3) {
|
||||
\_SB.PCI0.MEMORY_HOPTLUG_DEVICE.MEMORY_SLOT_OST_METHOD(_UID, Arg0, Arg1, Arg2)
|
||||
\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_OST_METHOD(_UID, Arg0, Arg1, Arg2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1)
|
||||
|
||||
External(MEMORY_SLOT_NOTIFY_METHOD, MethodObj)
|
||||
Scope(\_SB.PCI0) {
|
||||
Device(MEMORY_HOPTLUG_DEVICE) {
|
||||
Device(MEMORY_HOTPLUG_DEVICE) {
|
||||
Name(_HID, "PNP0A06")
|
||||
Name(_UID, "Memory hotplug resources")
|
||||
|
||||
|
||||
+2
-1
@@ -688,7 +688,8 @@ void ide_dma_cb(void *opaque, int ret)
|
||||
sector_num, n, s->dma_cmd);
|
||||
#endif
|
||||
|
||||
if (!ide_sect_range_ok(s, sector_num, n)) {
|
||||
if ((s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) &&
|
||||
!ide_sect_range_ok(s, sector_num, n)) {
|
||||
dma_buf_commit(s);
|
||||
ide_dma_error(s);
|
||||
return;
|
||||
|
||||
@@ -252,6 +252,12 @@ static void pc_dimm_realize(DeviceState *dev, Error **errp)
|
||||
error_setg(errp, "'" PC_DIMM_MEMDEV_PROP "' property is not set");
|
||||
return;
|
||||
}
|
||||
if (dimm->node >= nb_numa_nodes) {
|
||||
error_setg(errp, "'DIMM property " PC_DIMM_NODE_PROP " has value %"
|
||||
PRIu32 "' which exceeds the number of numa nodes: %d",
|
||||
dimm->node, nb_numa_nodes);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static MemoryRegion *pc_dimm_get_memory_region(PCDIMMDevice *dimm)
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
+29
-9
@@ -120,11 +120,20 @@ typedef struct VFIOINTx {
|
||||
} VFIOINTx;
|
||||
|
||||
typedef struct VFIOMSIVector {
|
||||
EventNotifier interrupt; /* eventfd triggered on interrupt */
|
||||
EventNotifier kvm_interrupt; /* eventfd triggered for KVM irqfd bypass */
|
||||
/*
|
||||
* Two interrupt paths are configured per vector. The first, is only used
|
||||
* for interrupts injected via QEMU. This is typically the non-accel path,
|
||||
* but may also be used when we want QEMU to handle masking and pending
|
||||
* bits. The KVM path bypasses QEMU and is therefore higher performance,
|
||||
* but requires masking at the device. virq is used to track the MSI route
|
||||
* through KVM, thus kvm_interrupt is only available when virq is set to a
|
||||
* valid (>= 0) value.
|
||||
*/
|
||||
EventNotifier interrupt;
|
||||
EventNotifier kvm_interrupt;
|
||||
struct VFIODevice *vdev; /* back pointer to device */
|
||||
MSIMessage msg; /* cache the MSI message so we know when it changes */
|
||||
int virq; /* KVM irqchip route for QEMU bypass */
|
||||
int virq;
|
||||
bool use;
|
||||
} VFIOMSIVector;
|
||||
|
||||
@@ -681,13 +690,24 @@ static int vfio_enable_vectors(VFIODevice *vdev, bool msix)
|
||||
fds = (int32_t *)&irq_set->data;
|
||||
|
||||
for (i = 0; i < vdev->nr_vectors; i++) {
|
||||
if (!vdev->msi_vectors[i].use) {
|
||||
fds[i] = -1;
|
||||
} else if (vdev->msi_vectors[i].virq >= 0) {
|
||||
fds[i] = event_notifier_get_fd(&vdev->msi_vectors[i].kvm_interrupt);
|
||||
} else {
|
||||
fds[i] = event_notifier_get_fd(&vdev->msi_vectors[i].interrupt);
|
||||
int fd = -1;
|
||||
|
||||
/*
|
||||
* MSI vs MSI-X - The guest has direct access to MSI mask and pending
|
||||
* bits, therefore we always use the KVM signaling path when setup.
|
||||
* MSI-X mask and pending bits are emulated, so we want to use the
|
||||
* KVM signaling path only when configured and unmasked.
|
||||
*/
|
||||
if (vdev->msi_vectors[i].use) {
|
||||
if (vdev->msi_vectors[i].virq < 0 ||
|
||||
(msix && msix_is_masked(&vdev->pdev, i))) {
|
||||
fd = event_notifier_get_fd(&vdev->msi_vectors[i].interrupt);
|
||||
} else {
|
||||
fd = event_notifier_get_fd(&vdev->msi_vectors[i].kvm_interrupt);
|
||||
}
|
||||
}
|
||||
|
||||
fds[i] = fd;
|
||||
}
|
||||
|
||||
ret = ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, irq_set);
|
||||
|
||||
+28
-14
@@ -115,6 +115,7 @@ unsigned vhost_net_get_features(struct vhost_net *net, unsigned features)
|
||||
|
||||
void vhost_net_ack_features(struct vhost_net *net, unsigned features)
|
||||
{
|
||||
net->dev.acked_features = net->dev.backend_features;
|
||||
vhost_ack_features(&net->dev, vhost_net_get_feature_bits(net), features);
|
||||
}
|
||||
|
||||
@@ -188,9 +189,13 @@ bool vhost_net_query(VHostNetState *net, VirtIODevice *dev)
|
||||
return vhost_dev_query(&net->dev, dev);
|
||||
}
|
||||
|
||||
static void vhost_net_set_vq_index(struct vhost_net *net, int vq_index)
|
||||
{
|
||||
net->dev.vq_index = vq_index;
|
||||
}
|
||||
|
||||
static int vhost_net_start_one(struct vhost_net *net,
|
||||
VirtIODevice *dev,
|
||||
int vq_index)
|
||||
VirtIODevice *dev)
|
||||
{
|
||||
struct vhost_vring_file file = { };
|
||||
int r;
|
||||
@@ -201,7 +206,6 @@ static int vhost_net_start_one(struct vhost_net *net,
|
||||
|
||||
net->dev.nvqs = 2;
|
||||
net->dev.vqs = net->vqs;
|
||||
net->dev.vq_index = vq_index;
|
||||
|
||||
r = vhost_dev_enable_notifiers(&net->dev, dev);
|
||||
if (r < 0) {
|
||||
@@ -294,7 +298,7 @@ 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, i = 0;
|
||||
int r, e, i;
|
||||
|
||||
if (!vhost_net_device_endian_ok(dev)) {
|
||||
error_report("vhost-net does not support cross-endian");
|
||||
@@ -309,11 +313,7 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
|
||||
}
|
||||
|
||||
for (i = 0; i < total_queues; i++) {
|
||||
r = vhost_net_start_one(get_vhost_net(ncs[i].peer), dev, i * 2);
|
||||
|
||||
if (r < 0) {
|
||||
goto err;
|
||||
}
|
||||
vhost_net_set_vq_index(get_vhost_net(ncs[i].peer), i * 2);
|
||||
}
|
||||
|
||||
r = k->set_guest_notifiers(qbus->parent, total_queues * 2, true);
|
||||
@@ -322,12 +322,26 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (i = 0; i < total_queues; i++) {
|
||||
r = vhost_net_start_one(get_vhost_net(ncs[i].peer), dev);
|
||||
|
||||
if (r < 0) {
|
||||
goto err_start;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
err_start:
|
||||
while (--i >= 0) {
|
||||
vhost_net_stop_one(get_vhost_net(ncs[i].peer), dev);
|
||||
}
|
||||
e = k->set_guest_notifiers(qbus->parent, total_queues * 2, false);
|
||||
if (e < 0) {
|
||||
fprintf(stderr, "vhost guest notifier cleanup failed: %d\n", e);
|
||||
fflush(stderr);
|
||||
}
|
||||
err:
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -339,16 +353,16 @@ void vhost_net_stop(VirtIODevice *dev, NetClientState *ncs,
|
||||
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(vbus);
|
||||
int i, r;
|
||||
|
||||
for (i = 0; i < total_queues; i++) {
|
||||
vhost_net_stop_one(get_vhost_net(ncs[i].peer), dev);
|
||||
}
|
||||
|
||||
r = k->set_guest_notifiers(qbus->parent, total_queues * 2, false);
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "vhost guest notifier cleanup failed: %d\n", r);
|
||||
fflush(stderr);
|
||||
}
|
||||
assert(r >= 0);
|
||||
|
||||
for (i = 0; i < total_queues; i++) {
|
||||
vhost_net_stop_one(get_vhost_net(ncs[i].peer), dev);
|
||||
}
|
||||
}
|
||||
|
||||
void vhost_net_cleanup(struct vhost_net *net)
|
||||
|
||||
+26
-5
@@ -125,10 +125,23 @@ static void virtio_net_vhost_status(VirtIONet *n, uint8_t status)
|
||||
return;
|
||||
}
|
||||
if (!n->vhost_started) {
|
||||
int r;
|
||||
int r, i;
|
||||
|
||||
if (!vhost_net_query(get_vhost_net(nc->peer), vdev)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Any packets outstanding? Purge them to avoid touching rings
|
||||
* when vhost is running.
|
||||
*/
|
||||
for (i = 0; i < queues; i++) {
|
||||
NetClientState *qnc = qemu_get_subqueue(n->nic, i);
|
||||
|
||||
/* Purge both directions: TX and RX. */
|
||||
qemu_net_queue_purge(qnc->peer->incoming_queue, qnc);
|
||||
qemu_net_queue_purge(qnc->incoming_queue, qnc->peer);
|
||||
}
|
||||
|
||||
n->vhost_started = 1;
|
||||
r = vhost_net_start(vdev, n->nic->ncs, queues);
|
||||
if (r < 0) {
|
||||
@@ -1112,8 +1125,6 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
|
||||
return num_packets;
|
||||
}
|
||||
|
||||
assert(vdev->vm_running);
|
||||
|
||||
if (q->async_tx.elem.out_num) {
|
||||
virtio_queue_set_notification(q->tx_vq, 0);
|
||||
return num_packets;
|
||||
@@ -1224,7 +1235,12 @@ static void virtio_net_tx_timer(void *opaque)
|
||||
VirtIONetQueue *q = opaque;
|
||||
VirtIONet *n = q->n;
|
||||
VirtIODevice *vdev = VIRTIO_DEVICE(n);
|
||||
assert(vdev->vm_running);
|
||||
/* This happens when device was stopped but BH wasn't. */
|
||||
if (!vdev->vm_running) {
|
||||
/* Make sure tx waiting is set, so we'll run when restarted. */
|
||||
assert(q->tx_waiting);
|
||||
return;
|
||||
}
|
||||
|
||||
q->tx_waiting = 0;
|
||||
|
||||
@@ -1244,7 +1260,12 @@ static void virtio_net_tx_bh(void *opaque)
|
||||
VirtIODevice *vdev = VIRTIO_DEVICE(n);
|
||||
int32_t ret;
|
||||
|
||||
assert(vdev->vm_running);
|
||||
/* This happens when device was stopped but BH wasn't. */
|
||||
if (!vdev->vm_running) {
|
||||
/* Make sure tx waiting is set, so we'll run when restarted. */
|
||||
assert(q->tx_waiting);
|
||||
return;
|
||||
}
|
||||
|
||||
q->tx_waiting = 0;
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
|
||||
#define PCI_DEVICE_ID_VMWARE_VMXNET3_REVISION 0x1
|
||||
#define VMXNET3_MSIX_BAR_SIZE 0x2000
|
||||
#define MIN_BUF_SIZE 60
|
||||
|
||||
#define VMXNET3_BAR0_IDX (0)
|
||||
#define VMXNET3_BAR1_IDX (1)
|
||||
@@ -1871,12 +1872,21 @@ vmxnet3_receive(NetClientState *nc, const uint8_t *buf, size_t size)
|
||||
{
|
||||
VMXNET3State *s = qemu_get_nic_opaque(nc);
|
||||
size_t bytes_indicated;
|
||||
uint8_t min_buf[MIN_BUF_SIZE];
|
||||
|
||||
if (!vmxnet3_can_receive(nc)) {
|
||||
VMW_PKPRN("Cannot receive now");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Pad to minimum Ethernet frame length */
|
||||
if (size < sizeof(min_buf)) {
|
||||
memcpy(min_buf, buf, size);
|
||||
memset(&min_buf[size], 0, sizeof(min_buf) - size);
|
||||
buf = min_buf;
|
||||
size = sizeof(min_buf);
|
||||
}
|
||||
|
||||
if (s->peer_has_vhdr) {
|
||||
vmxnet_rx_pkt_set_vhdr(s->rx_pkt, (struct virtio_net_hdr *)buf);
|
||||
buf += sizeof(struct virtio_net_hdr);
|
||||
|
||||
+4
-3
@@ -1147,9 +1147,10 @@ uint32_t pci_default_read_config(PCIDevice *d,
|
||||
return le32_to_cpu(val);
|
||||
}
|
||||
|
||||
void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l)
|
||||
void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val_in, int l)
|
||||
{
|
||||
int i, was_irq_disabled = pci_irq_disabled(d);
|
||||
uint32_t val = val_in;
|
||||
|
||||
for (i = 0; i < l; val >>= 8, ++i) {
|
||||
uint8_t wmask = d->wmask[addr + i];
|
||||
@@ -1171,8 +1172,8 @@ void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l)
|
||||
& PCI_COMMAND_MASTER);
|
||||
}
|
||||
|
||||
msi_write_config(d, addr, val, l);
|
||||
msix_write_config(d, addr, val, l);
|
||||
msi_write_config(d, addr, val_in, l);
|
||||
msix_write_config(d, addr, val_in, l);
|
||||
}
|
||||
|
||||
/***********************************************************/
|
||||
|
||||
@@ -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);
|
||||
|
||||
+18
-10
@@ -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));
|
||||
|
||||
+2
-2
@@ -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);
|
||||
|
||||
+26
-12
@@ -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;
|
||||
}
|
||||
@@ -238,6 +238,7 @@ static void vhost_scsi_realize(DeviceState *dev, Error **errp)
|
||||
s->dev.nvqs = VHOST_SCSI_VQ_NUM_FIXED + vs->conf.num_queues;
|
||||
s->dev.vqs = g_new(struct vhost_virtqueue, s->dev.nvqs);
|
||||
s->dev.vq_index = 0;
|
||||
s->dev.backend_features = 0;
|
||||
|
||||
ret = vhost_dev_init(&s->dev, (void *)(uintptr_t)vhostfd,
|
||||
VHOST_BACKEND_TYPE_KERNEL, true);
|
||||
@@ -246,7 +247,6 @@ static void vhost_scsi_realize(DeviceState *dev, Error **errp)
|
||||
strerror(-ret));
|
||||
return;
|
||||
}
|
||||
s->dev.backend_features = 0;
|
||||
|
||||
error_setg(&s->migration_blocker,
|
||||
"vhost-scsi does not support migration");
|
||||
|
||||
+1
-1
@@ -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(),
|
||||
};
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
@@ -976,7 +976,6 @@ void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev)
|
||||
bool vhost_virtqueue_pending(struct vhost_dev *hdev, int n)
|
||||
{
|
||||
struct vhost_virtqueue *vq = hdev->vqs + n - hdev->vq_index;
|
||||
assert(hdev->started);
|
||||
assert(n >= hdev->vq_index && n < hdev->vq_index + hdev->nvqs);
|
||||
return event_notifier_test_and_clear(&vq->masked_notifier);
|
||||
}
|
||||
@@ -988,7 +987,6 @@ void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n,
|
||||
struct VirtQueue *vvq = virtio_get_queue(vdev, n);
|
||||
int r, index = n - hdev->vq_index;
|
||||
|
||||
assert(hdev->started);
|
||||
assert(n >= hdev->vq_index && n < hdev->vq_index + hdev->nvqs);
|
||||
|
||||
struct vhost_vring_file file = {
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#define ACPI_MEMORY_HOTPLUG_IO_LEN 24
|
||||
#define ACPI_MEMORY_HOTPLUG_BASE 0x0a00
|
||||
|
||||
#define MEMORY_HOPTLUG_DEVICE MHPD
|
||||
#define MEMORY_HOTPLUG_DEVICE MHPD
|
||||
#define MEMORY_SLOTS_NUMBER MDNR
|
||||
#define MEMORY_HOTPLUG_IO_REGION HPMR
|
||||
#define MEMORY_SLOT_ADDR_LOW MRBL
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
@@ -176,6 +177,8 @@ void pc_acpi_init(const char *default_dsdt);
|
||||
PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size,
|
||||
ram_addr_t above_4g_mem_size);
|
||||
|
||||
void pc_set_legacy_acpi_data_size(void);
|
||||
|
||||
#define PCI_HOST_PROP_PCI_HOLE_START "pci-hole-start"
|
||||
#define PCI_HOST_PROP_PCI_HOLE_END "pci-hole-end"
|
||||
#define PCI_HOST_PROP_PCI_HOLE64_START "pci-hole64-start"
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,12 +41,14 @@
|
||||
#include "qapi-visit.h"
|
||||
#include "qapi/opts-visitor.h"
|
||||
#include "qapi/dealloc-visitor.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
|
||||
/* Net bridge is currently not supported for W32. */
|
||||
#if !defined(_WIN32)
|
||||
# define CONFIG_NET_BRIDGE
|
||||
#endif
|
||||
|
||||
static VMChangeStateEntry *net_change_state_entry;
|
||||
static QTAILQ_HEAD(, NetClientState) net_clients;
|
||||
|
||||
const char *host_net_devices[] = {
|
||||
@@ -452,6 +454,12 @@ void qemu_set_vnet_hdr_len(NetClientState *nc, int len)
|
||||
|
||||
int qemu_can_send_packet(NetClientState *sender)
|
||||
{
|
||||
int vm_running = runstate_is_running();
|
||||
|
||||
if (!vm_running) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!sender->peer) {
|
||||
return 1;
|
||||
}
|
||||
@@ -504,7 +512,8 @@ void qemu_purge_queued_packets(NetClientState *nc)
|
||||
qemu_net_queue_purge(nc->peer->incoming_queue, nc);
|
||||
}
|
||||
|
||||
void qemu_flush_queued_packets(NetClientState *nc)
|
||||
static
|
||||
void qemu_flush_or_purge_queued_packets(NetClientState *nc, bool purge)
|
||||
{
|
||||
nc->receive_disabled = 0;
|
||||
|
||||
@@ -518,9 +527,17 @@ void qemu_flush_queued_packets(NetClientState *nc)
|
||||
* the file descriptor (for tap, for example).
|
||||
*/
|
||||
qemu_notify_event();
|
||||
} else if (purge) {
|
||||
/* Unable to empty the queue, purge remaining packets */
|
||||
qemu_net_queue_purge(nc->incoming_queue, nc);
|
||||
}
|
||||
}
|
||||
|
||||
void qemu_flush_queued_packets(NetClientState *nc)
|
||||
{
|
||||
qemu_flush_or_purge_queued_packets(nc, false);
|
||||
}
|
||||
|
||||
static ssize_t qemu_send_packet_async_with_flags(NetClientState *sender,
|
||||
unsigned flags,
|
||||
const uint8_t *buf, int size,
|
||||
@@ -1168,6 +1185,22 @@ void qmp_set_link(const char *name, bool up, Error **errp)
|
||||
}
|
||||
}
|
||||
|
||||
static void net_vm_change_state_handler(void *opaque, int running,
|
||||
RunState state)
|
||||
{
|
||||
/* Complete all queued packets, to guarantee we don't modify
|
||||
* state later when VM is not running.
|
||||
*/
|
||||
if (!running) {
|
||||
NetClientState *nc;
|
||||
NetClientState *tmp;
|
||||
|
||||
QTAILQ_FOREACH_SAFE(nc, &net_clients, next, tmp) {
|
||||
qemu_flush_or_purge_queued_packets(nc, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void net_cleanup(void)
|
||||
{
|
||||
NetClientState *nc;
|
||||
@@ -1183,6 +1216,8 @@ void net_cleanup(void)
|
||||
qemu_del_net_client(nc);
|
||||
}
|
||||
}
|
||||
|
||||
qemu_del_vm_change_state_handler(net_change_state_entry);
|
||||
}
|
||||
|
||||
void net_check_clients(void)
|
||||
@@ -1268,6 +1303,9 @@ int net_init_clients(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
net_change_state_entry =
|
||||
qemu_add_vm_change_state_handler(net_vm_change_state_handler, NULL);
|
||||
|
||||
QTAILQ_INIT(&net_clients);
|
||||
|
||||
if (qemu_opts_foreach(qemu_find_opts("netdev"), net_init_netdev, NULL, 1) == -1)
|
||||
|
||||
@@ -233,6 +233,9 @@ void qemu_net_queue_purge(NetQueue *queue, NetClientState *from)
|
||||
if (packet->sender == from) {
|
||||
QTAILQ_REMOVE(&queue->packets, packet, entry);
|
||||
queue->nq_count--;
|
||||
if (packet->sent_cb) {
|
||||
packet->sent_cb(packet->sender, 0);
|
||||
}
|
||||
g_free(packet);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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")) {
|
||||
|
||||
@@ -210,8 +210,8 @@ void set_numa_nodes(void)
|
||||
numa_total += numa_info[i].node_mem;
|
||||
}
|
||||
if (numa_total != ram_size) {
|
||||
error_report("total memory for NUMA nodes (%" PRIu64 ")"
|
||||
" should equal RAM size (" RAM_ADDR_FMT ")",
|
||||
error_report("total memory for NUMA nodes (0x%" PRIx64 ")"
|
||||
" should equal RAM size (0x" RAM_ADDR_FMT ")",
|
||||
numa_total, ram_size);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
+37
-16
@@ -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"
|
||||
+40
-16
@@ -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"
|
||||
@@ -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"
|
||||
+17
-23
@@ -182,9 +182,10 @@ static const char *find_typename_by_alias(const char *alias)
|
||||
|
||||
int qdev_device_help(QemuOpts *opts)
|
||||
{
|
||||
Error *local_err = NULL;
|
||||
const char *driver;
|
||||
Property *prop;
|
||||
ObjectClass *klass;
|
||||
DevicePropertyInfoList *prop_list;
|
||||
DevicePropertyInfoList *prop;
|
||||
|
||||
driver = qemu_opt_get(opts, "driver");
|
||||
if (driver && is_help_option(driver)) {
|
||||
@@ -196,35 +197,28 @@ int qdev_device_help(QemuOpts *opts)
|
||||
return 0;
|
||||
}
|
||||
|
||||
klass = object_class_by_name(driver);
|
||||
if (!klass) {
|
||||
if (!object_class_by_name(driver)) {
|
||||
const char *typename = find_typename_by_alias(driver);
|
||||
|
||||
if (typename) {
|
||||
driver = typename;
|
||||
klass = object_class_by_name(driver);
|
||||
}
|
||||
}
|
||||
|
||||
if (!object_class_dynamic_cast(klass, TYPE_DEVICE)) {
|
||||
return 0;
|
||||
prop_list = qmp_device_list_properties(driver, &local_err);
|
||||
if (!prop_list) {
|
||||
error_printf("%s\n", error_get_pretty(local_err));
|
||||
error_free(local_err);
|
||||
return 1;
|
||||
}
|
||||
do {
|
||||
for (prop = DEVICE_CLASS(klass)->props; prop && prop->name; prop++) {
|
||||
/*
|
||||
* TODO Properties without a parser are just for dirty hacks.
|
||||
* qdev_prop_ptr is the only such PropertyInfo. It's marked
|
||||
* for removal. This conditional should be removed along with
|
||||
* it.
|
||||
*/
|
||||
if (!prop->info->set) {
|
||||
continue; /* no way to set it, don't show */
|
||||
}
|
||||
error_printf("%s.%s=%s\n", driver, prop->name,
|
||||
prop->info->legacy_name ?: prop->info->name);
|
||||
}
|
||||
klass = object_class_get_parent(klass);
|
||||
} while (klass != object_class_by_name(TYPE_DEVICE));
|
||||
|
||||
for (prop = prop_list; prop; prop = prop->next) {
|
||||
error_printf("%s.%s=%s\n", driver,
|
||||
prop->value->name,
|
||||
prop->value->type);
|
||||
}
|
||||
|
||||
qapi_free_DevicePropertyInfoList(prop_list);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
+10
-1
@@ -1160,7 +1160,9 @@ static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
|
||||
if (!s->connected) {
|
||||
/* guest sends data, check for (re-)connect */
|
||||
pty_chr_update_read_handler_locked(chr);
|
||||
return 0;
|
||||
if (!s->connected) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return io_channel_send(s->fd, buf, len);
|
||||
}
|
||||
@@ -1168,6 +1170,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 +3669,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);
|
||||
|
||||
+10
-3
@@ -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) {
|
||||
|
||||
+1
-1
@@ -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",
|
||||
};
|
||||
|
||||
@@ -509,6 +509,7 @@ DevicePropertyInfoList *qmp_device_list_properties(const char *typename,
|
||||
if (strcmp(prop->name, "type") == 0 ||
|
||||
strcmp(prop->name, "realized") == 0 ||
|
||||
strcmp(prop->name, "hotpluggable") == 0 ||
|
||||
strcmp(prop->name, "hotplugged") == 0 ||
|
||||
strcmp(prop->name, "parent_bus") == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
+1
-1
@@ -152,7 +152,7 @@ udp_input(register struct mbuf *m, int iphlen)
|
||||
* Locate pcb for datagram.
|
||||
*/
|
||||
so = slirp->udp_last_so;
|
||||
if (so->so_lport != uh->uh_sport ||
|
||||
if (so == &slirp->udb || so->so_lport != uh->uh_sport ||
|
||||
so->so_laddr.s_addr != ip->ip_src.s_addr) {
|
||||
struct socket *tmp;
|
||||
|
||||
|
||||
+8
-1
@@ -1170,7 +1170,14 @@ static inline int cpu_mmu_index (CPUARMState *env)
|
||||
static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
|
||||
target_ulong *cs_base, int *flags)
|
||||
{
|
||||
int fpen = extract32(env->cp15.c1_coproc, 20, 2);
|
||||
int fpen;
|
||||
|
||||
if (arm_feature(env, ARM_FEATURE_V6)) {
|
||||
fpen = extract32(env->cp15.c1_coproc, 20, 2);
|
||||
} else {
|
||||
/* CPACR doesn't exist before v6, so VFP is always accessible */
|
||||
fpen = 3;
|
||||
}
|
||||
|
||||
if (is_a64(env)) {
|
||||
*pc = env->pc;
|
||||
|
||||
+2
-1
@@ -123,9 +123,10 @@ static void aarch64_a57_initfn(Object *obj)
|
||||
cpu->id_isar2 = 0x21232042;
|
||||
cpu->id_isar3 = 0x01112131;
|
||||
cpu->id_isar4 = 0x00011142;
|
||||
cpu->id_isar5 = 0x00011121;
|
||||
cpu->id_aa64pfr0 = 0x00002222;
|
||||
cpu->id_aa64dfr0 = 0x10305106;
|
||||
cpu->id_aa64isar0 = 0x00010000;
|
||||
cpu->id_aa64isar0 = 0x00011120;
|
||||
cpu->id_aa64mmfr0 = 0x00001124;
|
||||
cpu->clidr = 0x0a200023;
|
||||
cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */
|
||||
|
||||
+37
-10
@@ -17,6 +17,7 @@
|
||||
#ifdef CONFIG_KVM
|
||||
#include "qemu/compiler.h"
|
||||
#include <linux/kvm.h>
|
||||
#include <linux/psci.h>
|
||||
|
||||
#define MISMATCH_CHECK(X, Y) QEMU_BUILD_BUG_ON(X != Y)
|
||||
|
||||
@@ -38,17 +39,43 @@ MISMATCH_CHECK(CP_REG_SIZE_U64, KVM_REG_SIZE_U64)
|
||||
MISMATCH_CHECK(CP_REG_ARM, KVM_REG_ARM)
|
||||
MISMATCH_CHECK(CP_REG_ARCH_MASK, KVM_REG_ARCH_MASK)
|
||||
|
||||
#define PSCI_FN_BASE 0x95c1ba5e
|
||||
#define PSCI_FN(n) (PSCI_FN_BASE + (n))
|
||||
#define PSCI_FN_CPU_SUSPEND PSCI_FN(0)
|
||||
#define PSCI_FN_CPU_OFF PSCI_FN(1)
|
||||
#define PSCI_FN_CPU_ON PSCI_FN(2)
|
||||
#define PSCI_FN_MIGRATE PSCI_FN(3)
|
||||
#define QEMU_PSCI_0_1_FN_BASE 0x95c1ba5e
|
||||
#define QEMU_PSCI_0_1_FN(n) (QEMU_PSCI_0_1_FN_BASE + (n))
|
||||
#define QEMU_PSCI_0_1_FN_CPU_SUSPEND QEMU_PSCI_0_1_FN(0)
|
||||
#define QEMU_PSCI_0_1_FN_CPU_OFF QEMU_PSCI_0_1_FN(1)
|
||||
#define QEMU_PSCI_0_1_FN_CPU_ON QEMU_PSCI_0_1_FN(2)
|
||||
#define QEMU_PSCI_0_1_FN_MIGRATE QEMU_PSCI_0_1_FN(3)
|
||||
|
||||
MISMATCH_CHECK(PSCI_FN_CPU_SUSPEND, KVM_PSCI_FN_CPU_SUSPEND)
|
||||
MISMATCH_CHECK(PSCI_FN_CPU_OFF, KVM_PSCI_FN_CPU_OFF)
|
||||
MISMATCH_CHECK(PSCI_FN_CPU_ON, KVM_PSCI_FN_CPU_ON)
|
||||
MISMATCH_CHECK(PSCI_FN_MIGRATE, KVM_PSCI_FN_MIGRATE)
|
||||
MISMATCH_CHECK(QEMU_PSCI_0_1_FN_CPU_SUSPEND, KVM_PSCI_FN_CPU_SUSPEND)
|
||||
MISMATCH_CHECK(QEMU_PSCI_0_1_FN_CPU_OFF, KVM_PSCI_FN_CPU_OFF)
|
||||
MISMATCH_CHECK(QEMU_PSCI_0_1_FN_CPU_ON, KVM_PSCI_FN_CPU_ON)
|
||||
MISMATCH_CHECK(QEMU_PSCI_0_1_FN_MIGRATE, KVM_PSCI_FN_MIGRATE)
|
||||
|
||||
#define QEMU_PSCI_0_2_FN_BASE 0x84000000
|
||||
#define QEMU_PSCI_0_2_FN(n) (QEMU_PSCI_0_2_FN_BASE + (n))
|
||||
|
||||
#define QEMU_PSCI_0_2_64BIT 0x40000000
|
||||
#define QEMU_PSCI_0_2_FN64_BASE \
|
||||
(QEMU_PSCI_0_2_FN_BASE + QEMU_PSCI_0_2_64BIT)
|
||||
#define QEMU_PSCI_0_2_FN64(n) (QEMU_PSCI_0_2_FN64_BASE + (n))
|
||||
|
||||
#define QEMU_PSCI_0_2_FN_CPU_SUSPEND QEMU_PSCI_0_2_FN(1)
|
||||
#define QEMU_PSCI_0_2_FN_CPU_OFF QEMU_PSCI_0_2_FN(2)
|
||||
#define QEMU_PSCI_0_2_FN_CPU_ON QEMU_PSCI_0_2_FN(3)
|
||||
#define QEMU_PSCI_0_2_FN_MIGRATE QEMU_PSCI_0_2_FN(5)
|
||||
|
||||
#define QEMU_PSCI_0_2_FN64_CPU_SUSPEND QEMU_PSCI_0_2_FN64(1)
|
||||
#define QEMU_PSCI_0_2_FN64_CPU_OFF QEMU_PSCI_0_2_FN64(2)
|
||||
#define QEMU_PSCI_0_2_FN64_CPU_ON QEMU_PSCI_0_2_FN64(3)
|
||||
#define QEMU_PSCI_0_2_FN64_MIGRATE QEMU_PSCI_0_2_FN64(5)
|
||||
|
||||
MISMATCH_CHECK(QEMU_PSCI_0_2_FN_CPU_SUSPEND, PSCI_0_2_FN_CPU_SUSPEND)
|
||||
MISMATCH_CHECK(QEMU_PSCI_0_2_FN_CPU_OFF, PSCI_0_2_FN_CPU_OFF)
|
||||
MISMATCH_CHECK(QEMU_PSCI_0_2_FN_CPU_ON, PSCI_0_2_FN_CPU_ON)
|
||||
MISMATCH_CHECK(QEMU_PSCI_0_2_FN_MIGRATE, PSCI_0_2_FN_MIGRATE)
|
||||
MISMATCH_CHECK(QEMU_PSCI_0_2_FN64_CPU_SUSPEND, PSCI_0_2_FN64_CPU_SUSPEND)
|
||||
MISMATCH_CHECK(QEMU_PSCI_0_2_FN64_CPU_ON, PSCI_0_2_FN64_CPU_ON)
|
||||
MISMATCH_CHECK(QEMU_PSCI_0_2_FN64_MIGRATE, PSCI_0_2_FN64_MIGRATE)
|
||||
|
||||
/* Note that KVM uses overlapping values for AArch32 and AArch64
|
||||
* target CPU numbers. AArch32 targets:
|
||||
|
||||
@@ -1454,7 +1454,7 @@ static void disas_exc(DisasContext *s, uint32_t insn)
|
||||
break;
|
||||
}
|
||||
/* BRK */
|
||||
gen_exception_insn(s, 0, EXCP_BKPT, syn_aa64_bkpt(imm16));
|
||||
gen_exception_insn(s, 4, EXCP_BKPT, syn_aa64_bkpt(imm16));
|
||||
break;
|
||||
case 2:
|
||||
if (op2_ll != 0) {
|
||||
|
||||
@@ -92,6 +92,7 @@ typedef struct X86CPU {
|
||||
bool enforce_cpuid;
|
||||
bool expose_kvm;
|
||||
bool migratable;
|
||||
bool host_features;
|
||||
|
||||
/* if true the CPUID code directly forward host cache leaves to the guest */
|
||||
bool cache_info_passthrough;
|
||||
|
||||
+25
-8
@@ -1254,6 +1254,9 @@ void x86_cpu_compat_set_features(const char *cpu_model, FeatureWord w,
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t x86_cpu_get_supported_feature_word(FeatureWord w,
|
||||
bool migratable_only);
|
||||
|
||||
#ifdef CONFIG_KVM
|
||||
|
||||
static int cpu_x86_fill_model_id(char *str)
|
||||
@@ -1310,26 +1313,23 @@ static void host_x86_cpu_class_init(ObjectClass *oc, void *data)
|
||||
dc->props = host_x86_cpu_properties;
|
||||
}
|
||||
|
||||
static uint32_t x86_cpu_get_supported_feature_word(FeatureWord w,
|
||||
bool migratable_only);
|
||||
|
||||
static void host_x86_cpu_initfn(Object *obj)
|
||||
{
|
||||
X86CPU *cpu = X86_CPU(obj);
|
||||
CPUX86State *env = &cpu->env;
|
||||
KVMState *s = kvm_state;
|
||||
FeatureWord w;
|
||||
|
||||
assert(kvm_enabled());
|
||||
|
||||
/* We can't fill the features array here because we don't know yet if
|
||||
* "migratable" is true or false.
|
||||
*/
|
||||
cpu->host_features = true;
|
||||
|
||||
env->cpuid_level = kvm_arch_get_supported_cpuid(s, 0x0, 0, R_EAX);
|
||||
env->cpuid_xlevel = kvm_arch_get_supported_cpuid(s, 0x80000000, 0, R_EAX);
|
||||
env->cpuid_xlevel2 = kvm_arch_get_supported_cpuid(s, 0xC0000000, 0, R_EAX);
|
||||
|
||||
for (w = 0; w < FEATURE_WORDS; w++) {
|
||||
env->features[w] =
|
||||
x86_cpu_get_supported_feature_word(w, cpu->migratable);
|
||||
}
|
||||
object_property_set_bool(OBJECT(cpu), true, "pmu", &error_abort);
|
||||
}
|
||||
|
||||
@@ -1828,6 +1828,13 @@ static void x86_cpu_parse_featurestr(CPUState *cs, char *features,
|
||||
featurestr = strtok(NULL, ",");
|
||||
}
|
||||
|
||||
if (cpu->host_features) {
|
||||
for (w = 0; w < FEATURE_WORDS; w++) {
|
||||
env->features[w] =
|
||||
x86_cpu_get_supported_feature_word(w, cpu->migratable);
|
||||
}
|
||||
}
|
||||
|
||||
for (w = 0; w < FEATURE_WORDS; w++) {
|
||||
env->features[w] |= plus_features[w];
|
||||
env->features[w] &= ~minus_features[w];
|
||||
@@ -2588,6 +2595,16 @@ static void x86_cpu_reset(CPUState *s)
|
||||
|
||||
env->xcr0 = 1;
|
||||
|
||||
/*
|
||||
* SDM 11.11.5 requires:
|
||||
* - IA32_MTRR_DEF_TYPE MSR.E = 0
|
||||
* - IA32_MTRR_PHYSMASKn.V = 0
|
||||
* All other bits are undefined. For simplification, zero it all.
|
||||
*/
|
||||
env->mtrr_deftype = 0;
|
||||
memset(env->mtrr_var, 0, sizeof(env->mtrr_var));
|
||||
memset(env->mtrr_fixed, 0, sizeof(env->mtrr_fixed));
|
||||
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
/* We hard-wire the BSP to the first CPU. */
|
||||
if (s->cpu_index == 0) {
|
||||
|
||||
+3
-1
@@ -337,6 +337,8 @@
|
||||
#define MSR_MTRRphysBase(reg) (0x200 + 2 * (reg))
|
||||
#define MSR_MTRRphysMask(reg) (0x200 + 2 * (reg) + 1)
|
||||
|
||||
#define MSR_MTRRphysIndex(addr) ((((addr) & ~1u) - 0x200) / 2)
|
||||
|
||||
#define MSR_MTRRfix64K_00000 0x250
|
||||
#define MSR_MTRRfix16K_80000 0x258
|
||||
#define MSR_MTRRfix16K_A0000 0x259
|
||||
@@ -930,7 +932,7 @@ typedef struct CPUX86State {
|
||||
/* MTRRs */
|
||||
uint64_t mtrr_fixed[11];
|
||||
uint64_t mtrr_deftype;
|
||||
MTRRVar mtrr_var[8];
|
||||
MTRRVar mtrr_var[MSR_MTRRcap_VCNT];
|
||||
|
||||
/* For KVM */
|
||||
uint32_t mp_state;
|
||||
|
||||
@@ -615,8 +615,8 @@ int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
|
||||
if (!(pdpe & PG_PRESENT_MASK)) {
|
||||
goto do_fault;
|
||||
}
|
||||
rsvd_mask |= PG_HI_USER_MASK | PG_NX_MASK;
|
||||
if (pdpe & rsvd_mask) {
|
||||
rsvd_mask |= PG_HI_USER_MASK;
|
||||
if (pdpe & (rsvd_mask | PG_NX_MASK)) {
|
||||
goto do_fault_rsvd;
|
||||
}
|
||||
ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK;
|
||||
@@ -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) {
|
||||
|
||||
+99
-2
@@ -79,6 +79,7 @@ static int lm_capable_kernel;
|
||||
static bool has_msr_hv_hypercall;
|
||||
static bool has_msr_hv_vapic;
|
||||
static bool has_msr_hv_tsc;
|
||||
static bool has_msr_mtrr;
|
||||
|
||||
static bool has_msr_architectural_pmu;
|
||||
static uint32_t num_architectural_pmu_counters;
|
||||
@@ -739,6 +740,10 @@ int kvm_arch_init_vcpu(CPUState *cs)
|
||||
env->kvm_xsave_buf = qemu_memalign(4096, sizeof(struct kvm_xsave));
|
||||
}
|
||||
|
||||
if (env->features[FEAT_1_EDX] & CPUID_MTRR) {
|
||||
has_msr_mtrr = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1183,7 +1188,7 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
|
||||
CPUX86State *env = &cpu->env;
|
||||
struct {
|
||||
struct kvm_msrs info;
|
||||
struct kvm_msr_entry entries[100];
|
||||
struct kvm_msr_entry entries[150];
|
||||
} msr_data;
|
||||
struct kvm_msr_entry *msrs = msr_data.entries;
|
||||
int n = 0, i;
|
||||
@@ -1278,6 +1283,37 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
|
||||
kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_REFERENCE_TSC,
|
||||
env->msr_hv_tsc);
|
||||
}
|
||||
if (has_msr_mtrr) {
|
||||
kvm_msr_entry_set(&msrs[n++], MSR_MTRRdefType, env->mtrr_deftype);
|
||||
kvm_msr_entry_set(&msrs[n++],
|
||||
MSR_MTRRfix64K_00000, env->mtrr_fixed[0]);
|
||||
kvm_msr_entry_set(&msrs[n++],
|
||||
MSR_MTRRfix16K_80000, env->mtrr_fixed[1]);
|
||||
kvm_msr_entry_set(&msrs[n++],
|
||||
MSR_MTRRfix16K_A0000, env->mtrr_fixed[2]);
|
||||
kvm_msr_entry_set(&msrs[n++],
|
||||
MSR_MTRRfix4K_C0000, env->mtrr_fixed[3]);
|
||||
kvm_msr_entry_set(&msrs[n++],
|
||||
MSR_MTRRfix4K_C8000, env->mtrr_fixed[4]);
|
||||
kvm_msr_entry_set(&msrs[n++],
|
||||
MSR_MTRRfix4K_D0000, env->mtrr_fixed[5]);
|
||||
kvm_msr_entry_set(&msrs[n++],
|
||||
MSR_MTRRfix4K_D8000, env->mtrr_fixed[6]);
|
||||
kvm_msr_entry_set(&msrs[n++],
|
||||
MSR_MTRRfix4K_E0000, env->mtrr_fixed[7]);
|
||||
kvm_msr_entry_set(&msrs[n++],
|
||||
MSR_MTRRfix4K_E8000, env->mtrr_fixed[8]);
|
||||
kvm_msr_entry_set(&msrs[n++],
|
||||
MSR_MTRRfix4K_F0000, env->mtrr_fixed[9]);
|
||||
kvm_msr_entry_set(&msrs[n++],
|
||||
MSR_MTRRfix4K_F8000, env->mtrr_fixed[10]);
|
||||
for (i = 0; i < MSR_MTRRcap_VCNT; i++) {
|
||||
kvm_msr_entry_set(&msrs[n++],
|
||||
MSR_MTRRphysBase(i), env->mtrr_var[i].base);
|
||||
kvm_msr_entry_set(&msrs[n++],
|
||||
MSR_MTRRphysMask(i), env->mtrr_var[i].mask);
|
||||
}
|
||||
}
|
||||
|
||||
/* Note: MSR_IA32_FEATURE_CONTROL is written separately, see
|
||||
* kvm_put_msr_feature_control. */
|
||||
@@ -1484,7 +1520,7 @@ static int kvm_get_msrs(X86CPU *cpu)
|
||||
CPUX86State *env = &cpu->env;
|
||||
struct {
|
||||
struct kvm_msrs info;
|
||||
struct kvm_msr_entry entries[100];
|
||||
struct kvm_msr_entry entries[150];
|
||||
} msr_data;
|
||||
struct kvm_msr_entry *msrs = msr_data.entries;
|
||||
int ret, i, n;
|
||||
@@ -1572,6 +1608,24 @@ static int kvm_get_msrs(X86CPU *cpu)
|
||||
if (has_msr_hv_tsc) {
|
||||
msrs[n++].index = HV_X64_MSR_REFERENCE_TSC;
|
||||
}
|
||||
if (has_msr_mtrr) {
|
||||
msrs[n++].index = MSR_MTRRdefType;
|
||||
msrs[n++].index = MSR_MTRRfix64K_00000;
|
||||
msrs[n++].index = MSR_MTRRfix16K_80000;
|
||||
msrs[n++].index = MSR_MTRRfix16K_A0000;
|
||||
msrs[n++].index = MSR_MTRRfix4K_C0000;
|
||||
msrs[n++].index = MSR_MTRRfix4K_C8000;
|
||||
msrs[n++].index = MSR_MTRRfix4K_D0000;
|
||||
msrs[n++].index = MSR_MTRRfix4K_D8000;
|
||||
msrs[n++].index = MSR_MTRRfix4K_E0000;
|
||||
msrs[n++].index = MSR_MTRRfix4K_E8000;
|
||||
msrs[n++].index = MSR_MTRRfix4K_F0000;
|
||||
msrs[n++].index = MSR_MTRRfix4K_F8000;
|
||||
for (i = 0; i < MSR_MTRRcap_VCNT; i++) {
|
||||
msrs[n++].index = MSR_MTRRphysBase(i);
|
||||
msrs[n++].index = MSR_MTRRphysMask(i);
|
||||
}
|
||||
}
|
||||
|
||||
msr_data.info.nmsrs = n;
|
||||
ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_MSRS, &msr_data);
|
||||
@@ -1692,6 +1746,49 @@ static int kvm_get_msrs(X86CPU *cpu)
|
||||
case HV_X64_MSR_REFERENCE_TSC:
|
||||
env->msr_hv_tsc = msrs[i].data;
|
||||
break;
|
||||
case MSR_MTRRdefType:
|
||||
env->mtrr_deftype = msrs[i].data;
|
||||
break;
|
||||
case MSR_MTRRfix64K_00000:
|
||||
env->mtrr_fixed[0] = msrs[i].data;
|
||||
break;
|
||||
case MSR_MTRRfix16K_80000:
|
||||
env->mtrr_fixed[1] = msrs[i].data;
|
||||
break;
|
||||
case MSR_MTRRfix16K_A0000:
|
||||
env->mtrr_fixed[2] = msrs[i].data;
|
||||
break;
|
||||
case MSR_MTRRfix4K_C0000:
|
||||
env->mtrr_fixed[3] = msrs[i].data;
|
||||
break;
|
||||
case MSR_MTRRfix4K_C8000:
|
||||
env->mtrr_fixed[4] = msrs[i].data;
|
||||
break;
|
||||
case MSR_MTRRfix4K_D0000:
|
||||
env->mtrr_fixed[5] = msrs[i].data;
|
||||
break;
|
||||
case MSR_MTRRfix4K_D8000:
|
||||
env->mtrr_fixed[6] = msrs[i].data;
|
||||
break;
|
||||
case MSR_MTRRfix4K_E0000:
|
||||
env->mtrr_fixed[7] = msrs[i].data;
|
||||
break;
|
||||
case MSR_MTRRfix4K_E8000:
|
||||
env->mtrr_fixed[8] = msrs[i].data;
|
||||
break;
|
||||
case MSR_MTRRfix4K_F0000:
|
||||
env->mtrr_fixed[9] = msrs[i].data;
|
||||
break;
|
||||
case MSR_MTRRfix4K_F8000:
|
||||
env->mtrr_fixed[10] = msrs[i].data;
|
||||
break;
|
||||
case MSR_MTRRphysBase(0) ... MSR_MTRRphysMask(MSR_MTRRcap_VCNT - 1):
|
||||
if (index & 1) {
|
||||
env->mtrr_var[MSR_MTRRphysIndex(index)].mask = msrs[i].data;
|
||||
} else {
|
||||
env->mtrr_var[MSR_MTRRphysIndex(index)].base = msrs[i].data;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -677,7 +677,7 @@ VMStateDescription vmstate_x86_cpu = {
|
||||
/* MTRRs */
|
||||
VMSTATE_UINT64_ARRAY_V(env.mtrr_fixed, X86CPU, 11, 8),
|
||||
VMSTATE_UINT64_V(env.mtrr_deftype, X86CPU, 8),
|
||||
VMSTATE_MTRR_VARS(env.mtrr_var, X86CPU, 8, 8),
|
||||
VMSTATE_MTRR_VARS(env.mtrr_var, X86CPU, MSR_MTRRcap_VCNT, 8),
|
||||
/* KVM-related states */
|
||||
VMSTATE_INT32_V(env.interrupt_injected, X86CPU, 9),
|
||||
VMSTATE_UINT32_V(env.mp_state, X86CPU, 9),
|
||||
|
||||
@@ -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) */
|
||||
|
||||
+1
-1
@@ -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' ""
|
||||
|
||||
|
||||
@@ -468,8 +468,6 @@ No errors were found on the image.
|
||||
|
||||
block-backup
|
||||
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) d[K[Ddr[K[D[Ddri[K[D[D[Ddriv[K[D[D[D[Ddrive[K[D[D[D[D[Ddrive_[K[D[D[D[D[D[Ddrive_b[K[D[D[D[D[D[D[Ddrive_ba[K[D[D[D[D[D[D[D[Ddrive_bac[K[D[D[D[D[D[D[D[D[Ddrive_back[K[D[D[D[D[D[D[D[D[D[Ddrive_backu[K[D[D[D[D[D[D[D[D[D[D[Ddrive_backup[K[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup [K[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup d[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup di[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup dis[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /h[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /ho[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /hom[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/k[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kw[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwo[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwol[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/s[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/so[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/sou[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/sour[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/sourc[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/q[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qe[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qem[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu/[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu/t[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu/te[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu/tes[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu/test[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu/tests[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu/tests/[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu/tests/q[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Line truncated
|
||||
Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 size=4294968832 backing_file='TEST_DIR/t.qcow2.base' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off
|
||||
(qemu) i[K[Din[K[D[Dinf[K[D[D[Dinfo[K[D[D[D[Dinfo [K[D[D[D[D[Dinfo b[K[D[D[D[D[D[Dinfo bl[K[D[D[D[D[D[D[Dinfo blo[K[D[D[D[D[D[D[D[Dinfo bloc[K[D[D[D[D[D[D[D[D[Dinfo block[K[D[D[D[D[D[D[D[D[D[Dinfo block-[K[D[D[D[D[D[D[D[D[D[D[Dinfo block-j[K[D[D[D[D[D[D[D[D[D[D[D[Dinfo block-jo[K[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block-job[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block-jobs[K
|
||||
Type backup, device disk: Completed 0 of 4294968832 bytes, speed limit 0 bytes/s
|
||||
|
||||
+51
-1
@@ -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
|
||||
|
||||
Executable
+58
@@ -0,0 +1,58 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Test short file I/O
|
||||
#
|
||||
# Copyright (C) 2014 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=stefanha@redhat.com
|
||||
|
||||
seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
{
|
||||
_cleanup_test_img
|
||||
}
|
||||
trap "_cleanup; exit \$status" 0 1 2 3 15
|
||||
|
||||
# get standard environment, filters and checks
|
||||
. ./common.rc
|
||||
. ./common.filter
|
||||
|
||||
_supported_fmt raw
|
||||
_supported_proto file
|
||||
_supported_os Linux
|
||||
|
||||
|
||||
echo
|
||||
echo "== creating short image file =="
|
||||
dd if=/dev/zero of="$TEST_IMG" bs=1 count=320
|
||||
|
||||
echo
|
||||
echo "== reading bytes beyond EOF gives zeroes =="
|
||||
$QEMU_IO -c "read -P 0 0 512" "$TEST_IMG" | _filter_qemu_io
|
||||
|
||||
|
||||
# success, all done
|
||||
echo "*** done"
|
||||
rm -f $seq.full
|
||||
status=0
|
||||
Loaded 100 of 117 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user