Compare commits
89
Commits
stable-9.2
...
v1.6.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e82ee0845c | ||
|
|
192d2f4cc7 | ||
|
|
9388fdb603 | ||
|
|
68a1ac19a1 | ||
|
|
08dde5b17b | ||
|
|
12f741031f | ||
|
|
982c8c5e20 | ||
|
|
d90ff19d0a | ||
|
|
7cfd037403 | ||
|
|
0f6298786f | ||
|
|
03060dc086 | ||
|
|
2cafbbf1e0 | ||
|
|
991a5f3782 | ||
|
|
817a872cc6 | ||
|
|
37da395651 | ||
|
|
4d2f39a918 | ||
|
|
4a5bf69f78 | ||
|
|
53e8cf93b3 | ||
|
|
2c8187434f | ||
|
|
5326636ff2 | ||
|
|
3bd74d1712 | ||
|
|
c554ddb901 | ||
|
|
c1fecf2085 | ||
|
|
08e2f35c65 | ||
|
|
ba3b29e04b | ||
|
|
0ca1774b61 | ||
|
|
bd821a9bc3 | ||
|
|
7bda8555de | ||
|
|
91a2cf3d0b | ||
|
|
b685f6af6f | ||
|
|
99b5b999a4 | ||
|
|
78bd79fac3 | ||
|
|
a2c9dc504a | ||
|
|
927fab3e06 | ||
|
|
2c342444a0 | ||
|
|
98384a92cc | ||
|
|
7038fe818e | ||
|
|
8501da4b93 | ||
|
|
aeefaaac83 | ||
|
|
205cff77af | ||
|
|
62ecc3a0e3 | ||
|
|
fdcbe7d587 | ||
|
|
1b5f770941 | ||
|
|
bc05a488b4 | ||
|
|
ba20326a93 | ||
|
|
ae00a27fea | ||
|
|
61fbeb6e81 | ||
|
|
fc06b43094 | ||
|
|
6bbb9d8100 | ||
|
|
b314120afd | ||
|
|
dc6fbaa832 | ||
|
|
c8adc0db7e | ||
|
|
aeab582580 | ||
|
|
5c20c1ffe7 | ||
|
|
5d2de77798 | ||
|
|
7ea8a3c12a | ||
|
|
50b31e8052 | ||
|
|
4b5b472146 | ||
|
|
76f6989487 | ||
|
|
8b4b3a71fd | ||
|
|
41900b0857 | ||
|
|
755ec4ca0f | ||
|
|
dc0973b588 | ||
|
|
b6d163fdd8 | ||
|
|
a1991d05d3 | ||
|
|
1110014801 | ||
|
|
2a93d3dd32 | ||
|
|
7ab1044eb1 | ||
|
|
e8601a4e31 | ||
|
|
96b14d0db1 | ||
|
|
9dbfbb89b2 | ||
|
|
57ea2d21ae | ||
|
|
1cd7138d49 | ||
|
|
9fab8e1fe1 | ||
|
|
2ffbe03e8b | ||
|
|
f9fd82ee93 | ||
|
|
da4e203efa | ||
|
|
c09a4634d9 | ||
|
|
c0a5eb81b4 | ||
|
|
358bb0daa1 | ||
|
|
3fe494efc5 | ||
|
|
a73c74f63a | ||
|
|
964e0d4ec5 | ||
|
|
11b0ab70a5 | ||
|
|
d6dcfd69f8 | ||
|
|
260790645e | ||
|
|
52f99b02e5 | ||
|
|
c0c080c5d1 | ||
|
|
670599a08c |
+2
-1
@@ -1124,7 +1124,8 @@ static int audio_is_timer_needed (void)
|
||||
static void audio_reset_timer (AudioState *s)
|
||||
{
|
||||
if (audio_is_timer_needed ()) {
|
||||
qemu_mod_timer (s->ts, qemu_get_clock_ns (vm_clock) + 1);
|
||||
qemu_mod_timer (s->ts,
|
||||
qemu_get_clock_ns(vm_clock) + conf.period.ticks);
|
||||
}
|
||||
else {
|
||||
qemu_del_timer (s->ts);
|
||||
|
||||
+3
-1
@@ -91,12 +91,14 @@ static int rng_egd_chr_can_read(void *opaque)
|
||||
static void rng_egd_chr_read(void *opaque, const uint8_t *buf, int size)
|
||||
{
|
||||
RngEgd *s = RNG_EGD(opaque);
|
||||
size_t buf_offset = 0;
|
||||
|
||||
while (size > 0 && s->requests) {
|
||||
RngRequest *req = s->requests->data;
|
||||
int len = MIN(size, req->size - req->offset);
|
||||
|
||||
memcpy(req->data + req->offset, buf, len);
|
||||
memcpy(req->data + req->offset, buf + buf_offset, len);
|
||||
buf_offset += len;
|
||||
req->offset += len;
|
||||
size -= len;
|
||||
|
||||
|
||||
@@ -1606,11 +1606,11 @@ void bdrv_delete(BlockDriverState *bs)
|
||||
assert(!bs->job);
|
||||
assert(!bs->in_use);
|
||||
|
||||
bdrv_close(bs);
|
||||
|
||||
/* remove from list, if necessary */
|
||||
bdrv_make_anon(bs);
|
||||
|
||||
bdrv_close(bs);
|
||||
|
||||
g_free(bs);
|
||||
}
|
||||
|
||||
@@ -1803,8 +1803,11 @@ int bdrv_commit(BlockDriverState *bs)
|
||||
buf = g_malloc(COMMIT_BUF_SECTORS * BDRV_SECTOR_SIZE);
|
||||
|
||||
for (sector = 0; sector < total_sectors; sector += n) {
|
||||
if (bdrv_is_allocated(bs, sector, COMMIT_BUF_SECTORS, &n)) {
|
||||
|
||||
ret = bdrv_is_allocated(bs, sector, COMMIT_BUF_SECTORS, &n);
|
||||
if (ret < 0) {
|
||||
goto ro_cleanup;
|
||||
}
|
||||
if (ret) {
|
||||
if (bdrv_read(bs, sector, buf, n) != 0) {
|
||||
ret = -EIO;
|
||||
goto ro_cleanup;
|
||||
|
||||
+5
-1
@@ -189,7 +189,11 @@ static int coroutine_fn cow_read(BlockDriverState *bs, int64_t sector_num,
|
||||
int ret, n;
|
||||
|
||||
while (nb_sectors > 0) {
|
||||
if (bdrv_co_is_allocated(bs, sector_num, nb_sectors, &n)) {
|
||||
ret = bdrv_co_is_allocated(bs, sector_num, nb_sectors, &n);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
if (ret) {
|
||||
ret = bdrv_pread(bs->file,
|
||||
s->cow_sectors_offset + sector_num * 512,
|
||||
buf, n * 512);
|
||||
|
||||
@@ -266,12 +266,15 @@ static int count_contiguous_clusters(uint64_t nb_clusters, int cluster_size,
|
||||
uint64_t *l2_table, uint64_t start, uint64_t stop_flags)
|
||||
{
|
||||
int i;
|
||||
uint64_t mask = stop_flags | L2E_OFFSET_MASK;
|
||||
uint64_t offset = be64_to_cpu(l2_table[0]) & mask;
|
||||
uint64_t mask = stop_flags | L2E_OFFSET_MASK | QCOW_OFLAG_COMPRESSED;
|
||||
uint64_t first_entry = be64_to_cpu(l2_table[0]);
|
||||
uint64_t offset = first_entry & mask;
|
||||
|
||||
if (!offset)
|
||||
return 0;
|
||||
|
||||
assert(qcow2_get_cluster_type(first_entry) != QCOW2_CLUSTER_COMPRESSED);
|
||||
|
||||
for (i = start; i < start + nb_clusters; i++) {
|
||||
uint64_t l2_entry = be64_to_cpu(l2_table[i]) & mask;
|
||||
if (offset + (uint64_t) i * cluster_size != l2_entry) {
|
||||
|
||||
+21
-19
@@ -648,13 +648,11 @@ static int coroutine_fn qcow2_co_is_allocated(BlockDriverState *bs,
|
||||
int ret;
|
||||
|
||||
*pnum = nb_sectors;
|
||||
/* FIXME We can get errors here, but the bdrv_co_is_allocated interface
|
||||
* can't pass them on today */
|
||||
qemu_co_mutex_lock(&s->lock);
|
||||
ret = qcow2_get_cluster_offset(bs, sector_num << 9, pnum, &cluster_offset);
|
||||
qemu_co_mutex_unlock(&s->lock);
|
||||
if (ret < 0) {
|
||||
*pnum = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return (cluster_offset != 0) || (ret == QCOW2_CLUSTER_ZERO);
|
||||
@@ -1287,7 +1285,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
|
||||
* size for any qcow2 image.
|
||||
*/
|
||||
BlockDriverState* bs;
|
||||
QCowHeader header;
|
||||
QCowHeader *header;
|
||||
uint8_t* refcount_table;
|
||||
int ret;
|
||||
|
||||
@@ -1302,30 +1300,34 @@ static int qcow2_create2(const char *filename, int64_t total_size,
|
||||
}
|
||||
|
||||
/* Write the header */
|
||||
memset(&header, 0, sizeof(header));
|
||||
header.magic = cpu_to_be32(QCOW_MAGIC);
|
||||
header.version = cpu_to_be32(version);
|
||||
header.cluster_bits = cpu_to_be32(cluster_bits);
|
||||
header.size = cpu_to_be64(0);
|
||||
header.l1_table_offset = cpu_to_be64(0);
|
||||
header.l1_size = cpu_to_be32(0);
|
||||
header.refcount_table_offset = cpu_to_be64(cluster_size);
|
||||
header.refcount_table_clusters = cpu_to_be32(1);
|
||||
header.refcount_order = cpu_to_be32(3 + REFCOUNT_SHIFT);
|
||||
header.header_length = cpu_to_be32(sizeof(header));
|
||||
QEMU_BUILD_BUG_ON((1 << MIN_CLUSTER_BITS) < sizeof(*header));
|
||||
header = g_malloc0(cluster_size);
|
||||
*header = (QCowHeader) {
|
||||
.magic = cpu_to_be32(QCOW_MAGIC),
|
||||
.version = cpu_to_be32(version),
|
||||
.cluster_bits = cpu_to_be32(cluster_bits),
|
||||
.size = cpu_to_be64(0),
|
||||
.l1_table_offset = cpu_to_be64(0),
|
||||
.l1_size = cpu_to_be32(0),
|
||||
.refcount_table_offset = cpu_to_be64(cluster_size),
|
||||
.refcount_table_clusters = cpu_to_be32(1),
|
||||
.refcount_order = cpu_to_be32(3 + REFCOUNT_SHIFT),
|
||||
.header_length = cpu_to_be32(sizeof(*header)),
|
||||
};
|
||||
|
||||
if (flags & BLOCK_FLAG_ENCRYPT) {
|
||||
header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
|
||||
header->crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
|
||||
} else {
|
||||
header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);
|
||||
header->crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);
|
||||
}
|
||||
|
||||
if (flags & BLOCK_FLAG_LAZY_REFCOUNTS) {
|
||||
header.compatible_features |=
|
||||
header->compatible_features |=
|
||||
cpu_to_be64(QCOW2_COMPAT_LAZY_REFCOUNTS);
|
||||
}
|
||||
|
||||
ret = bdrv_pwrite(bs, 0, &header, sizeof(header));
|
||||
ret = bdrv_pwrite(bs, 0, header, cluster_size);
|
||||
g_free(header);
|
||||
if (ret < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
+29
-7
@@ -535,13 +535,29 @@ static int hdev_open(BlockDriverState *bs, QDict *options, int flags)
|
||||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
int access_flags, create_flags;
|
||||
int ret = 0;
|
||||
DWORD overlapped;
|
||||
char device_name[64];
|
||||
const char *filename = qdict_get_str(options, "filename");
|
||||
|
||||
Error *local_err = NULL;
|
||||
const char *filename;
|
||||
|
||||
QemuOpts *opts = qemu_opts_create_nofail(&raw_runtime_opts);
|
||||
qemu_opts_absorb_qdict(opts, options, &local_err);
|
||||
if (error_is_set(&local_err)) {
|
||||
qerror_report_err(local_err);
|
||||
error_free(local_err);
|
||||
ret = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
filename = qemu_opt_get(opts, "filename");
|
||||
|
||||
if (strstart(filename, "/dev/cdrom", NULL)) {
|
||||
if (find_cdrom(device_name, sizeof(device_name)) < 0)
|
||||
return -ENOENT;
|
||||
if (find_cdrom(device_name, sizeof(device_name)) < 0) {
|
||||
ret = -ENOENT;
|
||||
goto done;
|
||||
}
|
||||
filename = device_name;
|
||||
} else {
|
||||
/* transform drive letters into device name */
|
||||
@@ -564,11 +580,17 @@ static int hdev_open(BlockDriverState *bs, QDict *options, int flags)
|
||||
if (s->hfile == INVALID_HANDLE_VALUE) {
|
||||
int err = GetLastError();
|
||||
|
||||
if (err == ERROR_ACCESS_DENIED)
|
||||
return -EACCES;
|
||||
return -1;
|
||||
if (err == ERROR_ACCESS_DENIED) {
|
||||
ret = -EACCES;
|
||||
} else {
|
||||
ret = -1;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
return 0;
|
||||
|
||||
done:
|
||||
qemu_opts_del(opts);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BlockDriver bdrv_host_device = {
|
||||
|
||||
+2
-1
@@ -934,7 +934,7 @@ static int qemu_rbd_snap_list(BlockDriverState *bs,
|
||||
do {
|
||||
snaps = g_malloc(sizeof(*snaps) * max_snaps);
|
||||
snap_count = rbd_snap_list(s->image, snaps, &max_snaps);
|
||||
if (snap_count < 0) {
|
||||
if (snap_count <= 0) {
|
||||
g_free(snaps);
|
||||
}
|
||||
} while (snap_count == -ERANGE);
|
||||
@@ -958,6 +958,7 @@ static int qemu_rbd_snap_list(BlockDriverState *bs,
|
||||
sn_info->vm_clock_nsec = 0;
|
||||
}
|
||||
rbd_snap_list_end(snaps);
|
||||
g_free(snaps);
|
||||
|
||||
done:
|
||||
*psn_tab = sn_tab;
|
||||
|
||||
+1
-1
@@ -120,7 +120,7 @@ wait:
|
||||
if (ret == 1) {
|
||||
/* Allocated in the top, no need to copy. */
|
||||
copy = false;
|
||||
} else {
|
||||
} else if (ret >= 0) {
|
||||
/* Copy if allocated in the intermediate images. Limit to the
|
||||
* known-unallocated area [sector_num, sector_num+n). */
|
||||
ret = bdrv_co_is_allocated_above(bs->backing_hd, base,
|
||||
|
||||
+44
-28
@@ -105,7 +105,7 @@ typedef struct VmdkExtent {
|
||||
uint32_t l2_cache_offsets[L2_CACHE_SIZE];
|
||||
uint32_t l2_cache_counts[L2_CACHE_SIZE];
|
||||
|
||||
unsigned int cluster_sectors;
|
||||
int64_t cluster_sectors;
|
||||
} VmdkExtent;
|
||||
|
||||
typedef struct BDRVVmdkState {
|
||||
@@ -416,7 +416,7 @@ static int vmdk_add_extent(BlockDriverState *bs,
|
||||
extent->l1_size = l1_size;
|
||||
extent->l1_entry_sectors = l2_size * cluster_sectors;
|
||||
extent->l2_size = l2_size;
|
||||
extent->cluster_sectors = cluster_sectors;
|
||||
extent->cluster_sectors = flat ? sectors : cluster_sectors;
|
||||
|
||||
if (s->num_extents > 1) {
|
||||
extent->end_sector = (*(extent - 1)).end_sector + extent->sectors;
|
||||
@@ -736,7 +736,7 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
|
||||
VmdkExtent *extent;
|
||||
|
||||
ret = vmdk_add_extent(bs, extent_file, true, sectors,
|
||||
0, 0, 0, 0, sectors, &extent);
|
||||
0, 0, 0, 0, 0, &extent);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
@@ -755,10 +755,13 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
|
||||
}
|
||||
next_line:
|
||||
/* move to next line */
|
||||
while (*p && *p != '\n') {
|
||||
while (*p) {
|
||||
if (*p == '\n') {
|
||||
p++;
|
||||
break;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1535,7 +1538,7 @@ static int filename_decompose(const char *filename, char *path, char *prefix,
|
||||
static int vmdk_create(const char *filename, QEMUOptionParameter *options)
|
||||
{
|
||||
int fd, idx = 0;
|
||||
char desc[BUF_SIZE];
|
||||
char *desc = NULL;
|
||||
int64_t total_size = 0, filesize;
|
||||
const char *adapter_type = NULL;
|
||||
const char *backing_file = NULL;
|
||||
@@ -1543,7 +1546,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options)
|
||||
int flags = 0;
|
||||
int ret = 0;
|
||||
bool flat, split, compress;
|
||||
char ext_desc_lines[BUF_SIZE] = "";
|
||||
GString *ext_desc_lines;
|
||||
char path[PATH_MAX], prefix[PATH_MAX], postfix[PATH_MAX];
|
||||
const int64_t split_size = 0x80000000; /* VMDK has constant split size */
|
||||
const char *desc_extent_line;
|
||||
@@ -1571,8 +1574,11 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options)
|
||||
"ddb.geometry.sectors = \"63\"\n"
|
||||
"ddb.adapterType = \"%s\"\n";
|
||||
|
||||
ext_desc_lines = g_string_new(NULL);
|
||||
|
||||
if (filename_decompose(filename, path, prefix, postfix, PATH_MAX)) {
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
/* Read out options */
|
||||
while (options && options->name) {
|
||||
@@ -1598,7 +1604,8 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options)
|
||||
strcmp(adapter_type, "lsilogic") &&
|
||||
strcmp(adapter_type, "legacyESX")) {
|
||||
fprintf(stderr, "VMDK: Unknown adapter type: '%s'.\n", adapter_type);
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
if (strcmp(adapter_type, "ide") != 0) {
|
||||
/* that's the number of heads with which vmware operates when
|
||||
@@ -1614,7 +1621,8 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options)
|
||||
strcmp(fmt, "twoGbMaxExtentFlat") &&
|
||||
strcmp(fmt, "streamOptimized")) {
|
||||
fprintf(stderr, "VMDK: Unknown subformat: %s\n", fmt);
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
split = !(strcmp(fmt, "twoGbMaxExtentFlat") &&
|
||||
strcmp(fmt, "twoGbMaxExtentSparse"));
|
||||
@@ -1628,18 +1636,20 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options)
|
||||
}
|
||||
if (flat && backing_file) {
|
||||
/* not supporting backing file for flat image */
|
||||
return -ENOTSUP;
|
||||
ret = -ENOTSUP;
|
||||
goto exit;
|
||||
}
|
||||
if (backing_file) {
|
||||
BlockDriverState *bs = bdrv_new("");
|
||||
ret = bdrv_open(bs, backing_file, NULL, 0, NULL);
|
||||
if (ret != 0) {
|
||||
bdrv_delete(bs);
|
||||
return ret;
|
||||
goto exit;
|
||||
}
|
||||
if (strcmp(bs->drv->format_name, "vmdk")) {
|
||||
bdrv_delete(bs);
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
parent_cid = vmdk_read_cid(bs, 0);
|
||||
bdrv_delete(bs);
|
||||
@@ -1673,25 +1683,27 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options)
|
||||
|
||||
if (vmdk_create_extent(ext_filename, size,
|
||||
flat, compress, zeroed_grain)) {
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
filesize -= size;
|
||||
|
||||
/* Format description line */
|
||||
snprintf(desc_line, sizeof(desc_line),
|
||||
desc_extent_line, size / 512, desc_filename);
|
||||
pstrcat(ext_desc_lines, sizeof(ext_desc_lines), desc_line);
|
||||
g_string_append(ext_desc_lines, desc_line);
|
||||
}
|
||||
/* generate descriptor file */
|
||||
snprintf(desc, sizeof(desc), desc_template,
|
||||
(unsigned int)time(NULL),
|
||||
parent_cid,
|
||||
fmt,
|
||||
parent_desc_line,
|
||||
ext_desc_lines,
|
||||
(flags & BLOCK_FLAG_COMPAT6 ? 6 : 4),
|
||||
total_size / (int64_t)(63 * number_heads * 512), number_heads,
|
||||
adapter_type);
|
||||
desc = g_strdup_printf(desc_template,
|
||||
(unsigned int)time(NULL),
|
||||
parent_cid,
|
||||
fmt,
|
||||
parent_desc_line,
|
||||
ext_desc_lines->str,
|
||||
(flags & BLOCK_FLAG_COMPAT6 ? 6 : 4),
|
||||
total_size / (int64_t)(63 * number_heads * 512),
|
||||
number_heads,
|
||||
adapter_type);
|
||||
if (split || flat) {
|
||||
fd = qemu_open(filename,
|
||||
O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,
|
||||
@@ -1702,21 +1714,25 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options)
|
||||
0644);
|
||||
}
|
||||
if (fd < 0) {
|
||||
return -errno;
|
||||
ret = -errno;
|
||||
goto exit;
|
||||
}
|
||||
/* the descriptor offset = 0x200 */
|
||||
if (!split && !flat && 0x200 != lseek(fd, 0x200, SEEK_SET)) {
|
||||
ret = -errno;
|
||||
goto exit;
|
||||
goto close_exit;
|
||||
}
|
||||
ret = qemu_write_full(fd, desc, strlen(desc));
|
||||
if (ret != strlen(desc)) {
|
||||
ret = -errno;
|
||||
goto exit;
|
||||
goto close_exit;
|
||||
}
|
||||
ret = 0;
|
||||
exit:
|
||||
close_exit:
|
||||
qemu_close(fd);
|
||||
exit:
|
||||
g_free(desc);
|
||||
g_string_free(ext_desc_lines, true);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -460,7 +460,7 @@ static DriveInfo *blockdev_init(QemuOpts *all_opts,
|
||||
if (qemu_opt_get_bool(opts, "cache.direct", false)) {
|
||||
bdrv_flags |= BDRV_O_NOCACHE;
|
||||
}
|
||||
if (qemu_opt_get_bool(opts, "cache.no-flush", true)) {
|
||||
if (qemu_opt_get_bool(opts, "cache.no-flush", false)) {
|
||||
bdrv_flags |= BDRV_O_NO_FLUSH;
|
||||
}
|
||||
|
||||
|
||||
@@ -235,6 +235,7 @@ guest_agent=""
|
||||
want_tools="yes"
|
||||
libiscsi=""
|
||||
coroutine=""
|
||||
coroutine_pool=""
|
||||
seccomp=""
|
||||
glusterfs=""
|
||||
glusterfs_discard="no"
|
||||
@@ -297,6 +298,9 @@ query_pkg_config() {
|
||||
pkg_config=query_pkg_config
|
||||
sdl_config="${SDL_CONFIG-${cross_prefix}sdl-config}"
|
||||
|
||||
# If the user hasn't specified ARFLAGS, default to 'rv', just as make does.
|
||||
ARFLAGS="${ARFLAGS-rv}"
|
||||
|
||||
# default flags for all hosts
|
||||
QEMU_CFLAGS="-fno-strict-aliasing $QEMU_CFLAGS"
|
||||
QEMU_CFLAGS="-Wall -Wundef -Wwrite-strings -Wmissing-prototypes $QEMU_CFLAGS"
|
||||
@@ -871,6 +875,10 @@ for opt do
|
||||
;;
|
||||
--with-coroutine=*) coroutine="$optarg"
|
||||
;;
|
||||
--disable-coroutine-pool) coroutine_pool="no"
|
||||
;;
|
||||
--enable-coroutine-pool) coroutine_pool="yes"
|
||||
;;
|
||||
--disable-docs) docs="no"
|
||||
;;
|
||||
--enable-docs) docs="yes"
|
||||
@@ -1152,6 +1160,8 @@ echo " --disable-seccomp disable seccomp support"
|
||||
echo " --enable-seccomp enables seccomp support"
|
||||
echo " --with-coroutine=BACKEND coroutine backend. Supported options:"
|
||||
echo " gthread, ucontext, sigaltstack, windows"
|
||||
echo " --disable-coroutine-pool disable coroutine freelist (worse performance)"
|
||||
echo " --enable-coroutine-pool enable coroutine freelist (better performance)"
|
||||
echo " --enable-glusterfs enable GlusterFS backend"
|
||||
echo " --disable-glusterfs disable GlusterFS backend"
|
||||
echo " --enable-gcov enable test coverage analysis with gcov"
|
||||
@@ -1387,39 +1397,27 @@ feature_not_found() {
|
||||
"configure was not able to find it"
|
||||
}
|
||||
|
||||
if test -z "$cross_prefix" ; then
|
||||
|
||||
# ---
|
||||
# big/little endian test
|
||||
cat > $TMPC << EOF
|
||||
#include <inttypes.h>
|
||||
int main(void) {
|
||||
volatile uint32_t i=0x01234567;
|
||||
return (*((uint8_t*)(&i))) == 0x67;
|
||||
short big_endian[] = { 0x4269, 0x4765, 0x4e64, 0x4961, 0x4e00, 0, };
|
||||
short little_endian[] = { 0x694c, 0x7454, 0x654c, 0x6e45, 0x6944, 0x6e41, 0, };
|
||||
extern int foo(short *, short *);
|
||||
int main(int argc, char *argv[]) {
|
||||
return foo(big_endian, little_endian);
|
||||
}
|
||||
EOF
|
||||
|
||||
if compile_prog "" "" ; then
|
||||
$TMPE && bigendian="yes"
|
||||
else
|
||||
echo big/little test failed
|
||||
fi
|
||||
|
||||
else
|
||||
|
||||
# if cross compiling, cannot launch a program, so make a static guess
|
||||
case "$cpu" in
|
||||
arm)
|
||||
# ARM can be either way; ask the compiler which one we are
|
||||
if check_define __ARMEB__; then
|
||||
bigendian=yes
|
||||
if compile_object ; then
|
||||
if grep -q BiGeNdIaN $TMPO ; then
|
||||
bigendian="yes"
|
||||
elif grep -q LiTtLeEnDiAn $TMPO ; then
|
||||
bigendian="no"
|
||||
else
|
||||
echo big/little test failed
|
||||
fi
|
||||
;;
|
||||
hppa|m68k|mips|mips64|ppc|ppc64|s390|s390x|sparc|sparc64)
|
||||
bigendian=yes
|
||||
;;
|
||||
esac
|
||||
|
||||
else
|
||||
echo big/little test failed
|
||||
fi
|
||||
|
||||
##########################################
|
||||
@@ -3240,6 +3238,17 @@ else
|
||||
esac
|
||||
fi
|
||||
|
||||
if test "$coroutine_pool" = ""; then
|
||||
if test "$coroutine" = "gthread"; then
|
||||
coroutine_pool=no
|
||||
else
|
||||
coroutine_pool=yes
|
||||
fi
|
||||
fi
|
||||
if test "$coroutine" = "gthread" -a "$coroutine_pool" = "yes"; then
|
||||
error_exit "'gthread' coroutine backend does not support pool (use --disable-coroutine-pool)"
|
||||
fi
|
||||
|
||||
##########################################
|
||||
# check if we have open_by_handle_at
|
||||
|
||||
@@ -3523,6 +3532,7 @@ echo "Source path $source_path"
|
||||
echo "C compiler $cc"
|
||||
echo "Host C compiler $host_cc"
|
||||
echo "Objective-C compiler $objcc"
|
||||
echo "ARFLAGS $ARFLAGS"
|
||||
echo "CFLAGS $CFLAGS"
|
||||
echo "QEMU_CFLAGS $QEMU_CFLAGS"
|
||||
echo "LDFLAGS $LDFLAGS"
|
||||
@@ -3605,6 +3615,7 @@ echo "libiscsi support $libiscsi"
|
||||
echo "build guest agent $guest_agent"
|
||||
echo "seccomp support $seccomp"
|
||||
echo "coroutine backend $coroutine"
|
||||
echo "coroutine pool $coroutine_pool"
|
||||
echo "GlusterFS support $glusterfs"
|
||||
echo "virtio-blk-data-plane $virtio_blk_data_plane"
|
||||
echo "gcov $gcov_tool"
|
||||
@@ -3954,6 +3965,11 @@ if test "$rbd" = "yes" ; then
|
||||
fi
|
||||
|
||||
echo "CONFIG_COROUTINE_BACKEND=$coroutine" >> $config_host_mak
|
||||
if test "$coroutine_pool" = "yes" ; then
|
||||
echo "CONFIG_COROUTINE_POOL=1" >> $config_host_mak
|
||||
else
|
||||
echo "CONFIG_COROUTINE_POOL=0" >> $config_host_mak
|
||||
fi
|
||||
|
||||
if test "$open_by_handle_at" = "yes" ; then
|
||||
echo "CONFIG_OPEN_BY_HANDLE=y" >> $config_host_mak
|
||||
@@ -4105,6 +4121,7 @@ echo "CC_I386=$cc_i386" >> $config_host_mak
|
||||
echo "HOST_CC=$host_cc" >> $config_host_mak
|
||||
echo "OBJCC=$objcc" >> $config_host_mak
|
||||
echo "AR=$ar" >> $config_host_mak
|
||||
echo "ARFLAGS=$ARFLAGS" >> $config_host_mak
|
||||
echo "AS=$as" >> $config_host_mak
|
||||
echo "CPP=$cpp" >> $config_host_mak
|
||||
echo "OBJCOPY=$objcopy" >> $config_host_mak
|
||||
|
||||
@@ -425,8 +425,10 @@ static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
|
||||
#else
|
||||
static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
|
||||
{
|
||||
tb_invalidate_phys_addr(cpu_get_phys_page_debug(cpu, pc) |
|
||||
(pc & ~TARGET_PAGE_MASK));
|
||||
hwaddr phys = cpu_get_phys_page_debug(cpu, pc);
|
||||
if (phys != -1) {
|
||||
tb_invalidate_phys_addr(phys | (pc & ~TARGET_PAGE_MASK));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* TARGET_HAS_ICE */
|
||||
@@ -869,7 +871,7 @@ static void mem_add(MemoryListener *listener, MemoryRegionSection *section)
|
||||
now = remain;
|
||||
if (int128_lt(remain.size, page_size)) {
|
||||
register_subpage(d, &now);
|
||||
} else if (remain.offset_within_region & ~TARGET_PAGE_MASK) {
|
||||
} else if (remain.offset_within_address_space & ~TARGET_PAGE_MASK) {
|
||||
now.size = page_size;
|
||||
register_subpage(d, &now);
|
||||
} else {
|
||||
@@ -1172,6 +1174,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
|
||||
|
||||
qemu_ram_setup_dump(new_block->host, size);
|
||||
qemu_madvise(new_block->host, size, QEMU_MADV_HUGEPAGE);
|
||||
qemu_madvise(new_block->host, size, QEMU_MADV_DONTFORK);
|
||||
|
||||
if (kvm_enabled())
|
||||
kvm_setup_guest_memory(new_block->host, size);
|
||||
@@ -1820,7 +1823,8 @@ static void memory_map_init(void)
|
||||
address_space_init(&address_space_memory, system_memory, "memory");
|
||||
|
||||
system_io = g_malloc(sizeof(*system_io));
|
||||
memory_region_init(system_io, NULL, "io", 65536);
|
||||
memory_region_init_io(system_io, NULL, &unassigned_io_ops, NULL, "io",
|
||||
65536);
|
||||
address_space_init(&address_space_io, system_io, "I/O");
|
||||
|
||||
memory_listener_register(&core_memory_listener, &address_space_memory);
|
||||
@@ -1928,6 +1932,9 @@ static int memory_access_size(MemoryRegion *mr, unsigned l, hwaddr addr)
|
||||
if (l > access_size_max) {
|
||||
l = access_size_max;
|
||||
}
|
||||
if (l & (l - 1)) {
|
||||
l = 1 << (qemu_fls(l) - 1);
|
||||
}
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
@@ -621,6 +621,8 @@ void gdb_register_coprocessor(CPUState *cpu,
|
||||
if (g_pos != s->base_reg) {
|
||||
fprintf(stderr, "Error: Bad gdb register numbering for '%s'\n"
|
||||
"Expected %d got %d\n", xml, g_pos, s->base_reg);
|
||||
} else {
|
||||
cpu->gdb_num_g_regs = cpu->gdb_num_regs;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -902,7 +904,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
|
||||
case 'g':
|
||||
cpu_synchronize_state(s->g_cpu);
|
||||
len = 0;
|
||||
for (addr = 0; addr < s->g_cpu->gdb_num_regs; addr++) {
|
||||
for (addr = 0; addr < s->g_cpu->gdb_num_g_regs; addr++) {
|
||||
reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr);
|
||||
len += reg_size;
|
||||
}
|
||||
@@ -914,7 +916,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
|
||||
registers = mem_buf;
|
||||
len = strlen(p) / 2;
|
||||
hextomem((uint8_t *)registers, p, len);
|
||||
for (addr = 0; addr < s->g_cpu->gdb_num_regs && len > 0; addr++) {
|
||||
for (addr = 0; addr < s->g_cpu->gdb_num_g_regs && len > 0; addr++) {
|
||||
reg_size = gdb_write_register(s->g_cpu, registers, addr);
|
||||
len -= reg_size;
|
||||
registers += reg_size;
|
||||
|
||||
+2
-1
@@ -324,12 +324,13 @@ static void acpi_notify_wakeup(Notifier *notifier, void *data)
|
||||
(ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_TIMER_STATUS);
|
||||
break;
|
||||
case QEMU_WAKEUP_REASON_OTHER:
|
||||
default:
|
||||
/* ACPI_BITMASK_WAKE_STATUS should be set on resume.
|
||||
Pretend that resume was caused by power button */
|
||||
ar->pm1.evt.sts |=
|
||||
(ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_POWER_BUTTON_STATUS);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -380,6 +380,7 @@ static void piix4_reset(void *opaque)
|
||||
/* Mark SMM as already inited (until KVM supports SMM). */
|
||||
pci_conf[0x5B] = 0x02;
|
||||
}
|
||||
pm_io_space_update(s);
|
||||
piix4_update_hotplug(s);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -284,9 +284,9 @@ static void Adlib_fini (AdlibState *s)
|
||||
}
|
||||
|
||||
static MemoryRegionPortio adlib_portio_list[] = {
|
||||
{ 0x388, 4, 1, .read = adlib_read, .write = adlib_write, },
|
||||
{ 0, 4, 1, .read = adlib_read, .write = adlib_write, },
|
||||
{ 0, 2, 1, .read = adlib_read, .write = adlib_write, },
|
||||
{ 0x388, 4, 1, .read = adlib_read, .write = adlib_write, },
|
||||
PORTIO_END_OF_LIST(),
|
||||
};
|
||||
|
||||
|
||||
+22
-2
@@ -460,9 +460,9 @@ static void virtio_blk_dma_restart_cb(void *opaque, int running,
|
||||
|
||||
static void virtio_blk_reset(VirtIODevice *vdev)
|
||||
{
|
||||
#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
|
||||
VirtIOBlock *s = VIRTIO_BLK(vdev);
|
||||
|
||||
#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
|
||||
if (s->dataplane) {
|
||||
virtio_blk_data_plane_stop(s->dataplane);
|
||||
}
|
||||
@@ -473,6 +473,7 @@ static void virtio_blk_reset(VirtIODevice *vdev)
|
||||
* are per-device request lists.
|
||||
*/
|
||||
bdrv_drain_all();
|
||||
bdrv_set_enable_write_cache(s->bs, s->original_wce);
|
||||
}
|
||||
|
||||
/* coalesce internal state, copy to pci i/o region 0
|
||||
@@ -564,7 +565,25 @@ static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status)
|
||||
}
|
||||
|
||||
features = vdev->guest_features;
|
||||
bdrv_set_enable_write_cache(s->bs, !!(features & (1 << VIRTIO_BLK_F_WCE)));
|
||||
|
||||
/* A guest that supports VIRTIO_BLK_F_CONFIG_WCE must be able to send
|
||||
* cache flushes. Thus, the "auto writethrough" behavior is never
|
||||
* necessary for guests that support the VIRTIO_BLK_F_CONFIG_WCE feature.
|
||||
* Leaving it enabled would break the following sequence:
|
||||
*
|
||||
* Guest started with "-drive cache=writethrough"
|
||||
* Guest sets status to 0
|
||||
* Guest sets DRIVER bit in status field
|
||||
* Guest reads host features (WCE=0, CONFIG_WCE=1)
|
||||
* Guest writes guest features (WCE=0, CONFIG_WCE=1)
|
||||
* Guest writes 1 to the WCE configuration field (writeback mode)
|
||||
* Guest sets DRIVER_OK bit in status field
|
||||
*
|
||||
* s->bs would erroneously be placed in writethrough mode.
|
||||
*/
|
||||
if (!(features & (1 << VIRTIO_BLK_F_CONFIG_WCE))) {
|
||||
bdrv_set_enable_write_cache(s->bs, !!(features & (1 << VIRTIO_BLK_F_WCE)));
|
||||
}
|
||||
}
|
||||
|
||||
static void virtio_blk_save(QEMUFile *f, void *opaque)
|
||||
@@ -674,6 +693,7 @@ static int virtio_blk_device_init(VirtIODevice *vdev)
|
||||
}
|
||||
|
||||
blkconf_serial(&blk->conf, &blk->serial);
|
||||
s->original_wce = bdrv_enable_write_cache(blk->conf.bs);
|
||||
if (blkconf_geometry(&blk->conf, NULL, 65535, 255, 255) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -405,6 +405,7 @@ static int ioreq_map(struct ioreq *ioreq)
|
||||
xen_be_printf(&ioreq->blkdev->xendev, 0,
|
||||
"can't map grant ref %d (%s, %d maps)\n",
|
||||
refs[i], strerror(errno), ioreq->blkdev->cnt_map);
|
||||
ioreq->mapped = 1;
|
||||
ioreq_unmap(ioreq);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -47,6 +47,8 @@ static int vty_getchars(VIOsPAPRDevice *sdev, uint8_t *buf, int max)
|
||||
buf[n++] = dev->buf[dev->out++ % VTERM_BUFSIZE];
|
||||
}
|
||||
|
||||
qemu_chr_accept_input(dev->chardev);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
+10
-5
@@ -31,10 +31,6 @@ static void qxl_blit(PCIQXLDevice *qxl, QXLRect *rect)
|
||||
if (is_buffer_shared(surface)) {
|
||||
return;
|
||||
}
|
||||
if (!qxl->guest_primary.data) {
|
||||
trace_qxl_render_blit_guest_primary_initialized();
|
||||
qxl->guest_primary.data = memory_region_get_ram_ptr(&qxl->vga.vram);
|
||||
}
|
||||
trace_qxl_render_blit(qxl->guest_primary.qxl_stride,
|
||||
rect->left, rect->right, rect->top, rect->bottom);
|
||||
src = qxl->guest_primary.data;
|
||||
@@ -104,7 +100,12 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
|
||||
|
||||
if (qxl->guest_primary.resized) {
|
||||
qxl->guest_primary.resized = 0;
|
||||
qxl->guest_primary.data = memory_region_get_ram_ptr(&qxl->vga.vram);
|
||||
qxl->guest_primary.data = qxl_phys2virt(qxl,
|
||||
qxl->guest_primary.surface.mem,
|
||||
MEMSLOT_GROUP_GUEST);
|
||||
if (!qxl->guest_primary.data) {
|
||||
return;
|
||||
}
|
||||
qxl_set_rect_to_surface(qxl, &qxl->dirty[0]);
|
||||
qxl->num_dirty_rects = 1;
|
||||
trace_qxl_render_guest_primary_resized(
|
||||
@@ -128,6 +129,10 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
|
||||
}
|
||||
dpy_gfx_replace_surface(vga->con, surface);
|
||||
}
|
||||
|
||||
if (!qxl->guest_primary.data) {
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < qxl->num_dirty_rects; i++) {
|
||||
if (qemu_spice_rect_is_empty(qxl->dirty+i)) {
|
||||
break;
|
||||
|
||||
+12
-5
@@ -510,9 +510,8 @@ static void vapic_reset(DeviceState *dev)
|
||||
{
|
||||
VAPICROMState *s = VAPIC(dev);
|
||||
|
||||
if (s->state == VAPIC_ACTIVE) {
|
||||
s->state = VAPIC_STANDBY;
|
||||
}
|
||||
s->state = VAPIC_INACTIVE;
|
||||
s->rom_state_paddr = 0;
|
||||
vapic_enable_tpr_reporting(false);
|
||||
}
|
||||
|
||||
@@ -578,7 +577,7 @@ static int patch_hypercalls(VAPICROMState *s)
|
||||
* enable write access to the option ROM so that variables can be updated by
|
||||
* the guest.
|
||||
*/
|
||||
static void vapic_map_rom_writable(VAPICROMState *s)
|
||||
static int vapic_map_rom_writable(VAPICROMState *s)
|
||||
{
|
||||
hwaddr rom_paddr = s->rom_state_paddr & ROM_BLOCK_MASK;
|
||||
MemoryRegionSection section;
|
||||
@@ -599,6 +598,9 @@ static void vapic_map_rom_writable(VAPICROMState *s)
|
||||
/* read ROM size from RAM region */
|
||||
ram = memory_region_get_ram_ptr(section.mr);
|
||||
rom_size = ram[rom_paddr + 2] * ROM_BLOCK_SIZE;
|
||||
if (rom_size == 0) {
|
||||
return -1;
|
||||
}
|
||||
s->rom_size = rom_size;
|
||||
|
||||
/* We need to round to avoid creating subpages
|
||||
@@ -612,11 +614,15 @@ static void vapic_map_rom_writable(VAPICROMState *s)
|
||||
memory_region_add_subregion_overlap(as, rom_paddr, &s->rom, 1000);
|
||||
s->rom_mapped_writable = true;
|
||||
memory_region_unref(section.mr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vapic_prepare(VAPICROMState *s)
|
||||
{
|
||||
vapic_map_rom_writable(s);
|
||||
if (vapic_map_rom_writable(s) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (patch_hypercalls(s) < 0) {
|
||||
return -1;
|
||||
@@ -659,6 +665,7 @@ static void vapic_write(void *opaque, hwaddr addr, uint64_t data,
|
||||
}
|
||||
if (vapic_prepare(s) < 0) {
|
||||
s->state = VAPIC_INACTIVE;
|
||||
s->rom_state_paddr = 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
+1
-1
@@ -93,7 +93,7 @@ static void pc_init1(MemoryRegion *system_memory,
|
||||
FWCfgState *fw_cfg = NULL;
|
||||
PcGuestInfo *guest_info;
|
||||
|
||||
if (xen_enabled() && xen_hvm_init() != 0) {
|
||||
if (xen_enabled() && xen_hvm_init(&ram_memory) != 0) {
|
||||
fprintf(stderr, "xen hardware virtual machine initialisation failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -81,6 +81,11 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
|
||||
DeviceState *icc_bridge;
|
||||
PcGuestInfo *guest_info;
|
||||
|
||||
if (xen_enabled() && xen_hvm_init(&ram_memory) != 0) {
|
||||
fprintf(stderr, "xen hardware virtual machine initialisation failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
icc_bridge = qdev_create(NULL, TYPE_ICC_BRIDGE);
|
||||
object_property_add_child(qdev_get_machine(), "icc-bridge",
|
||||
OBJECT(icc_bridge), NULL);
|
||||
|
||||
@@ -873,8 +873,20 @@ static void vfio_disable_msi_common(VFIODevice *vdev)
|
||||
|
||||
static void vfio_disable_msix(VFIODevice *vdev)
|
||||
{
|
||||
int i;
|
||||
|
||||
msix_unset_vector_notifiers(&vdev->pdev);
|
||||
|
||||
/*
|
||||
* MSI-X will only release vectors if MSI-X is still enabled on the
|
||||
* device, check through the rest and release it ourselves if necessary.
|
||||
*/
|
||||
for (i = 0; i < vdev->nr_vectors; i++) {
|
||||
if (vdev->msi_vectors[i].use) {
|
||||
vfio_msix_vector_release(&vdev->pdev, i);
|
||||
}
|
||||
}
|
||||
|
||||
if (vdev->nr_vectors) {
|
||||
vfio_disable_irqindex(vdev, VFIO_PCI_MSIX_IRQ_INDEX);
|
||||
}
|
||||
@@ -3142,6 +3154,13 @@ static int vfio_initfn(PCIDevice *pdev)
|
||||
vdev->emulated_config_bits[PCI_HEADER_TYPE] =
|
||||
PCI_HEADER_TYPE_MULTI_FUNCTION;
|
||||
|
||||
/* Restore or clear multifunction, this is always controlled by QEMU */
|
||||
if (vdev->pdev.cap_present & QEMU_PCI_CAP_MULTIFUNCTION) {
|
||||
vdev->pdev.config[PCI_HEADER_TYPE] |= PCI_HEADER_TYPE_MULTI_FUNCTION;
|
||||
} else {
|
||||
vdev->pdev.config[PCI_HEADER_TYPE] &= ~PCI_HEADER_TYPE_MULTI_FUNCTION;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear host resource mapping info. If we choose not to register a
|
||||
* BAR, such as might be the case with the option ROM, we can get
|
||||
|
||||
+1
-1
@@ -693,7 +693,7 @@ static void ne2000_write(void *opaque, hwaddr addr,
|
||||
static const MemoryRegionOps ne2000_ops = {
|
||||
.read = ne2000_read,
|
||||
.write = ne2000_write,
|
||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
};
|
||||
|
||||
/***********************************************************/
|
||||
|
||||
+2
-2
@@ -134,7 +134,7 @@ static void pcnet_ioport_write(void *opaque, hwaddr addr,
|
||||
static const MemoryRegionOps pcnet_io_ops = {
|
||||
.read = pcnet_ioport_read,
|
||||
.write = pcnet_ioport_write,
|
||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
};
|
||||
|
||||
static void pcnet_mmio_writeb(void *opaque, hwaddr addr, uint32_t val)
|
||||
@@ -256,7 +256,7 @@ static const MemoryRegionOps pcnet_mmio_ops = {
|
||||
.read = { pcnet_mmio_readb, pcnet_mmio_readw, pcnet_mmio_readl },
|
||||
.write = { pcnet_mmio_writeb, pcnet_mmio_writew, pcnet_mmio_writel },
|
||||
},
|
||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
};
|
||||
|
||||
static void pci_physical_memory_write(void *dma_opaque, hwaddr addr,
|
||||
|
||||
+5
-5
@@ -200,16 +200,16 @@ static void rxfilter_notify(NetClientState *nc)
|
||||
VirtIONet *n = qemu_get_nic_opaque(nc);
|
||||
|
||||
if (nc->rxfilter_notify_enabled) {
|
||||
gchar *path = object_get_canonical_path(OBJECT(n->qdev));
|
||||
if (n->netclient_name) {
|
||||
event_data = qobject_from_jsonf("{ 'name': %s, 'path': %s }",
|
||||
n->netclient_name,
|
||||
object_get_canonical_path(OBJECT(n->qdev)));
|
||||
n->netclient_name, path);
|
||||
} else {
|
||||
event_data = qobject_from_jsonf("{ 'path': %s }",
|
||||
object_get_canonical_path(OBJECT(n->qdev)));
|
||||
event_data = qobject_from_jsonf("{ 'path': %s }", path);
|
||||
}
|
||||
monitor_protocol_event(QEVENT_NIC_RX_FILTER_CHANGED, event_data);
|
||||
qobject_decref(event_data);
|
||||
g_free(path);
|
||||
|
||||
/* disable event notification to avoid events flooding */
|
||||
nc->rxfilter_notify_enabled = 0;
|
||||
@@ -1600,7 +1600,7 @@ static int virtio_net_device_exit(DeviceState *qdev)
|
||||
if (q->tx_timer) {
|
||||
qemu_del_timer(q->tx_timer);
|
||||
qemu_free_timer(q->tx_timer);
|
||||
} else {
|
||||
} else if (q->tx_bh) {
|
||||
qemu_bh_delete(q->tx_bh);
|
||||
}
|
||||
}
|
||||
|
||||
+14
-4
@@ -48,6 +48,7 @@ typedef struct I440FXState {
|
||||
PCIHostState parent_obj;
|
||||
PcPciInfo pci_info;
|
||||
uint64_t pci_hole64_size;
|
||||
uint32_t short_root_bus;
|
||||
} I440FXState;
|
||||
|
||||
#define PIIX_NUM_PIC_IRQS 16 /* i8259 * 2 */
|
||||
@@ -320,6 +321,7 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
|
||||
PCII440FXState *f;
|
||||
unsigned i;
|
||||
I440FXState *i440fx;
|
||||
uint64_t pci_hole64_size;
|
||||
|
||||
dev = qdev_create(NULL, TYPE_I440FX_PCI_HOST_BRIDGE);
|
||||
s = PCI_HOST_BRIDGE(dev);
|
||||
@@ -351,13 +353,15 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
|
||||
pci_hole_start, pci_hole_size);
|
||||
memory_region_add_subregion(f->system_memory, pci_hole_start, &f->pci_hole);
|
||||
|
||||
pci_hole64_size = pci_host_get_hole64_size(i440fx->pci_hole64_size);
|
||||
|
||||
pc_init_pci64_hole(&i440fx->pci_info, 0x100000000ULL + above_4g_mem_size,
|
||||
i440fx->pci_hole64_size);
|
||||
pci_hole64_size);
|
||||
memory_region_init_alias(&f->pci_hole_64bit, OBJECT(d), "pci-hole64",
|
||||
f->pci_address_space,
|
||||
i440fx->pci_info.w64.begin,
|
||||
i440fx->pci_hole64_size);
|
||||
if (i440fx->pci_hole64_size) {
|
||||
pci_hole64_size);
|
||||
if (pci_hole64_size) {
|
||||
memory_region_add_subregion(f->system_memory,
|
||||
i440fx->pci_info.w64.begin,
|
||||
&f->pci_hole_64bit);
|
||||
@@ -703,13 +707,19 @@ static const TypeInfo i440fx_info = {
|
||||
static const char *i440fx_pcihost_root_bus_path(PCIHostState *host_bridge,
|
||||
PCIBus *rootbus)
|
||||
{
|
||||
I440FXState *s = I440FX_PCI_HOST_BRIDGE(host_bridge);
|
||||
|
||||
/* For backwards compat with old device paths */
|
||||
return "0000";
|
||||
if (s->short_root_bus) {
|
||||
return "0000";
|
||||
}
|
||||
return "0000:00";
|
||||
}
|
||||
|
||||
static Property i440fx_props[] = {
|
||||
DEFINE_PROP_SIZE(PCI_HOST_PROP_PCI_HOLE64_SIZE, I440FXState,
|
||||
pci_hole64_size, DEFAULT_PCI_HOLE64_SIZE),
|
||||
DEFINE_PROP_UINT32("short_root_bus", I440FXState, short_root_bus, 1),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
|
||||
+13
-5
@@ -61,8 +61,13 @@ static void q35_host_realize(DeviceState *dev, Error **errp)
|
||||
static const char *q35_host_root_bus_path(PCIHostState *host_bridge,
|
||||
PCIBus *rootbus)
|
||||
{
|
||||
/* For backwards compat with old device paths */
|
||||
return "0000";
|
||||
Q35PCIHost *s = Q35_HOST_DEVICE(host_bridge);
|
||||
|
||||
/* For backwards compat with old device paths */
|
||||
if (s->mch.short_root_bus) {
|
||||
return "0000";
|
||||
}
|
||||
return "0000:00";
|
||||
}
|
||||
|
||||
static void q35_host_get_pci_hole_start(Object *obj, Visitor *v,
|
||||
@@ -108,6 +113,7 @@ static Property mch_props[] = {
|
||||
MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT),
|
||||
DEFINE_PROP_SIZE(PCI_HOST_PROP_PCI_HOLE64_SIZE, Q35PCIHost,
|
||||
mch.pci_hole64_size, DEFAULT_PCI_HOLE64_SIZE),
|
||||
DEFINE_PROP_UINT32("short_root_bus", Q35PCIHost, mch.short_root_bus, 1),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
@@ -320,6 +326,7 @@ static int mch_init(PCIDevice *d)
|
||||
{
|
||||
int i;
|
||||
MCHPCIState *mch = MCH_PCI_DEVICE(d);
|
||||
uint64_t pci_hole64_size;
|
||||
|
||||
/* setup pci memory regions */
|
||||
memory_region_init_alias(&mch->pci_hole, OBJECT(mch), "pci-hole",
|
||||
@@ -329,13 +336,14 @@ static int mch_init(PCIDevice *d)
|
||||
memory_region_add_subregion(mch->system_memory, mch->below_4g_mem_size,
|
||||
&mch->pci_hole);
|
||||
|
||||
pci_hole64_size = pci_host_get_hole64_size(mch->pci_hole64_size);
|
||||
pc_init_pci64_hole(&mch->pci_info, 0x100000000ULL + mch->above_4g_mem_size,
|
||||
mch->pci_hole64_size);
|
||||
pci_hole64_size);
|
||||
memory_region_init_alias(&mch->pci_hole_64bit, OBJECT(mch), "pci-hole64",
|
||||
mch->pci_address_space,
|
||||
mch->pci_info.w64.begin,
|
||||
mch->pci_hole64_size);
|
||||
if (mch->pci_hole64_size) {
|
||||
pci_hole64_size);
|
||||
if (pci_hole64_size) {
|
||||
memory_region_add_subregion(mch->system_memory,
|
||||
mch->pci_info.w64.begin,
|
||||
&mch->pci_hole_64bit);
|
||||
|
||||
@@ -47,6 +47,7 @@ static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent);
|
||||
static char *pcibus_get_dev_path(DeviceState *dev);
|
||||
static char *pcibus_get_fw_dev_path(DeviceState *dev);
|
||||
static int pcibus_reset(BusState *qbus);
|
||||
static void pci_bus_finalize(Object *obj);
|
||||
|
||||
static Property pci_props[] = {
|
||||
DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1),
|
||||
@@ -73,6 +74,7 @@ static const TypeInfo pci_bus_info = {
|
||||
.name = TYPE_PCI_BUS,
|
||||
.parent = TYPE_BUS,
|
||||
.instance_size = sizeof(PCIBus),
|
||||
.instance_finalize = pci_bus_finalize,
|
||||
.class_init = pci_bus_class_init,
|
||||
};
|
||||
|
||||
@@ -375,6 +377,12 @@ int pci_bus_num(PCIBus *s)
|
||||
return s->parent_dev->config[PCI_SECONDARY_BUS];
|
||||
}
|
||||
|
||||
static void pci_bus_finalize(Object *obj)
|
||||
{
|
||||
PCIBus *bus = PCI_BUS(obj);
|
||||
vmstate_unregister(NULL, &vmstate_pcibus, bus);
|
||||
}
|
||||
|
||||
static int get_pci_config_device(QEMUFile *f, void *pv, size_t size)
|
||||
{
|
||||
PCIDevice *s = container_of(pv, PCIDevice, config);
|
||||
|
||||
+34
-11
@@ -11,6 +11,8 @@ static char *scsibus_get_dev_path(DeviceState *dev);
|
||||
static char *scsibus_get_fw_dev_path(DeviceState *dev);
|
||||
static int scsi_req_parse(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf);
|
||||
static void scsi_req_dequeue(SCSIRequest *req);
|
||||
static uint8_t *scsi_target_alloc_buf(SCSIRequest *req, size_t len);
|
||||
static void scsi_target_free_buf(SCSIRequest *req);
|
||||
|
||||
static Property scsi_props[] = {
|
||||
DEFINE_PROP_UINT32("channel", SCSIDevice, channel, 0),
|
||||
@@ -224,7 +226,7 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv,
|
||||
if (object_property_find(OBJECT(dev), "removable", NULL)) {
|
||||
qdev_prop_set_bit(dev, "removable", removable);
|
||||
}
|
||||
if (serial) {
|
||||
if (serial && object_property_find(OBJECT(dev), "serial", NULL)) {
|
||||
qdev_prop_set_string(dev, "serial", serial);
|
||||
}
|
||||
if (qdev_prop_set_drive(dev, "drive", bdrv) < 0) {
|
||||
@@ -317,7 +319,8 @@ typedef struct SCSITargetReq SCSITargetReq;
|
||||
struct SCSITargetReq {
|
||||
SCSIRequest req;
|
||||
int len;
|
||||
uint8_t buf[2056];
|
||||
uint8_t *buf;
|
||||
int buf_len;
|
||||
};
|
||||
|
||||
static void store_lun(uint8_t *outbuf, int lun)
|
||||
@@ -361,14 +364,12 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq *r)
|
||||
if (!found_lun0) {
|
||||
n += 8;
|
||||
}
|
||||
len = MIN(n + 8, r->req.cmd.xfer & ~7);
|
||||
if (len > sizeof(r->buf)) {
|
||||
/* TODO: > 256 LUNs? */
|
||||
return false;
|
||||
}
|
||||
|
||||
scsi_target_alloc_buf(&r->req, n + 8);
|
||||
|
||||
len = MIN(n + 8, r->req.cmd.xfer & ~7);
|
||||
memset(r->buf, 0, len);
|
||||
stl_be_p(&r->buf, n);
|
||||
stl_be_p(r->buf, n);
|
||||
i = found_lun0 ? 8 : 16;
|
||||
QTAILQ_FOREACH(kid, &r->req.bus->qbus.children, sibling) {
|
||||
DeviceState *qdev = kid->child;
|
||||
@@ -387,6 +388,9 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq *r)
|
||||
static bool scsi_target_emulate_inquiry(SCSITargetReq *r)
|
||||
{
|
||||
assert(r->req.dev->lun != r->req.lun);
|
||||
|
||||
scsi_target_alloc_buf(&r->req, SCSI_INQUIRY_LEN);
|
||||
|
||||
if (r->req.cmd.buf[1] & 0x2) {
|
||||
/* Command support data - optional, not implemented */
|
||||
return false;
|
||||
@@ -411,7 +415,7 @@ static bool scsi_target_emulate_inquiry(SCSITargetReq *r)
|
||||
return false;
|
||||
}
|
||||
/* done with EVPD */
|
||||
assert(r->len < sizeof(r->buf));
|
||||
assert(r->len < r->buf_len);
|
||||
r->len = MIN(r->req.cmd.xfer, r->len);
|
||||
return true;
|
||||
}
|
||||
@@ -455,8 +459,9 @@ static int32_t scsi_target_send_command(SCSIRequest *req, uint8_t *buf)
|
||||
}
|
||||
break;
|
||||
case REQUEST_SENSE:
|
||||
scsi_target_alloc_buf(&r->req, SCSI_SENSE_LEN);
|
||||
r->len = scsi_device_get_sense(r->req.dev, r->buf,
|
||||
MIN(req->cmd.xfer, sizeof r->buf),
|
||||
MIN(req->cmd.xfer, r->buf_len),
|
||||
(req->cmd.buf[1] & 1) == 0);
|
||||
if (r->req.dev->sense_is_ua) {
|
||||
scsi_device_unit_attention_reported(req->dev);
|
||||
@@ -501,11 +506,29 @@ static uint8_t *scsi_target_get_buf(SCSIRequest *req)
|
||||
return r->buf;
|
||||
}
|
||||
|
||||
static uint8_t *scsi_target_alloc_buf(SCSIRequest *req, size_t len)
|
||||
{
|
||||
SCSITargetReq *r = DO_UPCAST(SCSITargetReq, req, req);
|
||||
|
||||
r->buf = g_malloc(len);
|
||||
r->buf_len = len;
|
||||
|
||||
return r->buf;
|
||||
}
|
||||
|
||||
static void scsi_target_free_buf(SCSIRequest *req)
|
||||
{
|
||||
SCSITargetReq *r = DO_UPCAST(SCSITargetReq, req, req);
|
||||
|
||||
g_free(r->buf);
|
||||
}
|
||||
|
||||
static const struct SCSIReqOps reqops_target_command = {
|
||||
.size = sizeof(SCSITargetReq),
|
||||
.send_command = scsi_target_send_command,
|
||||
.read_data = scsi_target_read_data,
|
||||
.get_buf = scsi_target_get_buf,
|
||||
.free_req = scsi_target_free_buf,
|
||||
};
|
||||
|
||||
|
||||
@@ -1365,7 +1388,7 @@ int scsi_build_sense(uint8_t *in_buf, int in_len,
|
||||
buf[7] = 10;
|
||||
buf[12] = sense.asc;
|
||||
buf[13] = sense.ascq;
|
||||
return MIN(len, 18);
|
||||
return MIN(len, SCSI_SENSE_LEN);
|
||||
} else {
|
||||
/* Return descriptor format sense buffer */
|
||||
buf[0] = 0x72;
|
||||
|
||||
+4
-3
@@ -403,7 +403,7 @@ void usb_handle_packet(USBDevice *dev, USBPacket *p)
|
||||
p->ep->halted = false;
|
||||
}
|
||||
|
||||
if (QTAILQ_EMPTY(&p->ep->queue) || p->ep->pipeline) {
|
||||
if (QTAILQ_EMPTY(&p->ep->queue) || p->ep->pipeline || p->stream) {
|
||||
usb_process_one(p);
|
||||
if (p->status == USB_RET_ASYNC) {
|
||||
/* hcd drivers cannot handle async for isoc */
|
||||
@@ -420,7 +420,8 @@ void usb_handle_packet(USBDevice *dev, USBPacket *p)
|
||||
* When pipelining is enabled usb-devices must always return async,
|
||||
* otherwise packets can complete out of order!
|
||||
*/
|
||||
assert(!p->ep->pipeline || QTAILQ_EMPTY(&p->ep->queue));
|
||||
assert(p->stream || !p->ep->pipeline ||
|
||||
QTAILQ_EMPTY(&p->ep->queue));
|
||||
if (p->status != USB_RET_NAK) {
|
||||
usb_packet_set_state(p, USB_PACKET_COMPLETE);
|
||||
}
|
||||
@@ -434,7 +435,7 @@ void usb_packet_complete_one(USBDevice *dev, USBPacket *p)
|
||||
{
|
||||
USBEndpoint *ep = p->ep;
|
||||
|
||||
assert(QTAILQ_FIRST(&ep->queue) == p);
|
||||
assert(p->stream || QTAILQ_FIRST(&ep->queue) == p);
|
||||
assert(p->status != USB_RET_ASYNC && p->status != USB_RET_NAK);
|
||||
|
||||
if (p->status != USB_RET_SUCCESS ||
|
||||
|
||||
+1
-1
@@ -658,7 +658,7 @@ static void usb_tablet_class_initfn(ObjectClass *klass, void *data)
|
||||
uc->product_desc = "QEMU USB Tablet";
|
||||
dc->vmsd = &vmstate_usb_ptr;
|
||||
dc->props = usb_tablet_properties;
|
||||
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
|
||||
set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
|
||||
}
|
||||
|
||||
static const TypeInfo usb_tablet_info = {
|
||||
|
||||
+1
-5
@@ -33,7 +33,6 @@ typedef struct USBHubPort {
|
||||
USBPort port;
|
||||
uint16_t wPortStatus;
|
||||
uint16_t wPortChange;
|
||||
uint16_t wPortChange_reported;
|
||||
} USBHubPort;
|
||||
|
||||
typedef struct USBHubState {
|
||||
@@ -468,11 +467,8 @@ static void usb_hub_handle_data(USBDevice *dev, USBPacket *p)
|
||||
status = 0;
|
||||
for(i = 0; i < NUM_PORTS; i++) {
|
||||
port = &s->ports[i];
|
||||
if (port->wPortChange &&
|
||||
port->wPortChange_reported != port->wPortChange) {
|
||||
if (port->wPortChange)
|
||||
status |= (1 << (i + 1));
|
||||
}
|
||||
port->wPortChange_reported = port->wPortChange;
|
||||
}
|
||||
if (status != 0) {
|
||||
for(i = 0; i < n; i++) {
|
||||
|
||||
+3
-4
@@ -1241,13 +1241,11 @@ static int ehci_init_transfer(EHCIPacket *p)
|
||||
{
|
||||
uint32_t cpage, offset, bytes, plen;
|
||||
dma_addr_t page;
|
||||
USBBus *bus = &p->queue->ehci->bus;
|
||||
BusState *qbus = BUS(bus);
|
||||
|
||||
cpage = get_field(p->qtd.token, QTD_TOKEN_CPAGE);
|
||||
bytes = get_field(p->qtd.token, QTD_TOKEN_TBYTES);
|
||||
offset = p->qtd.bufptr[0] & ~QTD_BUFPTR_MASK;
|
||||
qemu_sglist_init(&p->sgl, qbus->parent, 5, p->queue->ehci->as);
|
||||
qemu_sglist_init(&p->sgl, p->queue->ehci->device, 5, p->queue->ehci->as);
|
||||
|
||||
while (bytes > 0) {
|
||||
if (cpage > 4) {
|
||||
@@ -1486,7 +1484,7 @@ static int ehci_process_itd(EHCIState *ehci,
|
||||
return -1;
|
||||
}
|
||||
|
||||
qemu_sglist_init(&ehci->isgl, DEVICE(ehci), 2, ehci->as);
|
||||
qemu_sglist_init(&ehci->isgl, ehci->device, 2, ehci->as);
|
||||
if (off + len > 4096) {
|
||||
/* transfer crosses page border */
|
||||
uint32_t len2 = off + len - 4096;
|
||||
@@ -2529,6 +2527,7 @@ void usb_ehci_realize(EHCIState *s, DeviceState *dev, Error **errp)
|
||||
|
||||
s->frame_timer = qemu_new_timer_ns(vm_clock, ehci_frame_timer, s);
|
||||
s->async_bh = qemu_bh_new(ehci_frame_timer, s);
|
||||
s->device = dev;
|
||||
|
||||
qemu_register_reset(ehci_reset, s);
|
||||
qemu_add_vm_change_state_handler(usb_ehci_vm_state_change, s);
|
||||
|
||||
@@ -255,6 +255,7 @@ typedef QTAILQ_HEAD(EHCIQueueHead, EHCIQueue) EHCIQueueHead;
|
||||
|
||||
struct EHCIState {
|
||||
USBBus bus;
|
||||
DeviceState *device;
|
||||
qemu_irq irq;
|
||||
MemoryRegion mem;
|
||||
AddressSpace *as;
|
||||
|
||||
+39
-8
@@ -355,6 +355,7 @@ typedef struct XHCITransfer {
|
||||
unsigned int streamid;
|
||||
bool in_xfer;
|
||||
bool iso_xfer;
|
||||
bool timed_xfer;
|
||||
|
||||
unsigned int trb_count;
|
||||
unsigned int trb_alloced;
|
||||
@@ -1257,7 +1258,7 @@ static void xhci_init_epctx(XHCIEPContext *epctx,
|
||||
epctx->ring.ccs = ctx[2] & 1;
|
||||
}
|
||||
|
||||
epctx->interval = 1 << (ctx[0] >> 16) & 0xff;
|
||||
epctx->interval = 1 << ((ctx[0] >> 16) & 0xff);
|
||||
}
|
||||
|
||||
static TRBCCode xhci_enable_ep(XHCIState *xhci, unsigned int slotid,
|
||||
@@ -1803,6 +1804,7 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer)
|
||||
|
||||
xfer->in_xfer = bmRequestType & USB_DIR_IN;
|
||||
xfer->iso_xfer = false;
|
||||
xfer->timed_xfer = false;
|
||||
|
||||
if (xhci_setup_packet(xfer) < 0) {
|
||||
return -1;
|
||||
@@ -1818,6 +1820,17 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void xhci_calc_intr_kick(XHCIState *xhci, XHCITransfer *xfer,
|
||||
XHCIEPContext *epctx, uint64_t mfindex)
|
||||
{
|
||||
uint64_t asap = ((mfindex + epctx->interval - 1) &
|
||||
~(epctx->interval-1));
|
||||
uint64_t kick = epctx->mfindex_last + epctx->interval;
|
||||
|
||||
assert(epctx->interval != 0);
|
||||
xfer->mfindex_kick = MAX(asap, kick);
|
||||
}
|
||||
|
||||
static void xhci_calc_iso_kick(XHCIState *xhci, XHCITransfer *xfer,
|
||||
XHCIEPContext *epctx, uint64_t mfindex)
|
||||
{
|
||||
@@ -1840,8 +1853,8 @@ static void xhci_calc_iso_kick(XHCIState *xhci, XHCITransfer *xfer,
|
||||
}
|
||||
}
|
||||
|
||||
static void xhci_check_iso_kick(XHCIState *xhci, XHCITransfer *xfer,
|
||||
XHCIEPContext *epctx, uint64_t mfindex)
|
||||
static void xhci_check_intr_iso_kick(XHCIState *xhci, XHCITransfer *xfer,
|
||||
XHCIEPContext *epctx, uint64_t mfindex)
|
||||
{
|
||||
if (xfer->mfindex_kick > mfindex) {
|
||||
qemu_mod_timer(epctx->kick_timer, qemu_get_clock_ns(vm_clock) +
|
||||
@@ -1866,18 +1879,30 @@ static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx
|
||||
switch(epctx->type) {
|
||||
case ET_INTR_OUT:
|
||||
case ET_INTR_IN:
|
||||
xfer->pkts = 0;
|
||||
xfer->iso_xfer = false;
|
||||
xfer->timed_xfer = true;
|
||||
mfindex = xhci_mfindex_get(xhci);
|
||||
xhci_calc_intr_kick(xhci, xfer, epctx, mfindex);
|
||||
xhci_check_intr_iso_kick(xhci, xfer, epctx, mfindex);
|
||||
if (xfer->running_retry) {
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case ET_BULK_OUT:
|
||||
case ET_BULK_IN:
|
||||
xfer->pkts = 0;
|
||||
xfer->iso_xfer = false;
|
||||
xfer->timed_xfer = false;
|
||||
break;
|
||||
case ET_ISO_OUT:
|
||||
case ET_ISO_IN:
|
||||
xfer->pkts = 1;
|
||||
xfer->iso_xfer = true;
|
||||
xfer->timed_xfer = true;
|
||||
mfindex = xhci_mfindex_get(xhci);
|
||||
xhci_calc_iso_kick(xhci, xfer, epctx, mfindex);
|
||||
xhci_check_iso_kick(xhci, xfer, epctx, mfindex);
|
||||
xhci_check_intr_iso_kick(xhci, xfer, epctx, mfindex);
|
||||
if (xfer->running_retry) {
|
||||
return -1;
|
||||
}
|
||||
@@ -1938,13 +1963,18 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid,
|
||||
|
||||
trace_usb_xhci_xfer_retry(xfer);
|
||||
assert(xfer->running_retry);
|
||||
if (xfer->iso_xfer) {
|
||||
/* retry delayed iso transfer */
|
||||
if (xfer->timed_xfer) {
|
||||
/* time to kick the transfer? */
|
||||
mfindex = xhci_mfindex_get(xhci);
|
||||
xhci_check_iso_kick(xhci, xfer, epctx, mfindex);
|
||||
xhci_check_intr_iso_kick(xhci, xfer, epctx, mfindex);
|
||||
if (xfer->running_retry) {
|
||||
return;
|
||||
}
|
||||
xfer->timed_xfer = 0;
|
||||
xfer->running_retry = 1;
|
||||
}
|
||||
if (xfer->iso_xfer) {
|
||||
/* retry iso transfer */
|
||||
if (xhci_setup_packet(xfer) < 0) {
|
||||
return;
|
||||
}
|
||||
@@ -2030,7 +2060,7 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid,
|
||||
epctx->next_xfer = (epctx->next_xfer + 1) % TD_QUEUE;
|
||||
ep = xfer->packet.ep;
|
||||
} else {
|
||||
if (!xfer->iso_xfer) {
|
||||
if (!xfer->timed_xfer) {
|
||||
fprintf(stderr, "xhci: error firing data transfer\n");
|
||||
}
|
||||
}
|
||||
@@ -2076,6 +2106,7 @@ static TRBCCode xhci_disable_slot(XHCIState *xhci, unsigned int slotid)
|
||||
|
||||
xhci->slots[slotid-1].enabled = 0;
|
||||
xhci->slots[slotid-1].addressed = 0;
|
||||
xhci->slots[slotid-1].uport = NULL;
|
||||
return CC_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -799,8 +799,7 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign)
|
||||
break;
|
||||
}
|
||||
|
||||
r = virtio_pci_set_guest_notifier(d, n, assign,
|
||||
kvm_msi_via_irqfd_enabled());
|
||||
r = virtio_pci_set_guest_notifier(d, n, assign, with_irqfd);
|
||||
if (r < 0) {
|
||||
goto assign_error;
|
||||
}
|
||||
|
||||
+1
-1
@@ -377,8 +377,8 @@ void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes,
|
||||
/* loop over the indirect descriptor table */
|
||||
indirect = 1;
|
||||
max = vring_desc_len(desc_pa, i) / sizeof(VRingDesc);
|
||||
num_bufs = i = 0;
|
||||
desc_pa = vring_desc_addr(desc_pa, i);
|
||||
num_bufs = i = 0;
|
||||
}
|
||||
|
||||
do {
|
||||
|
||||
@@ -45,6 +45,10 @@ typedef struct MemoryRegionPortio {
|
||||
|
||||
#define PORTIO_END_OF_LIST() { }
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
extern const MemoryRegionOps unassigned_io_ops;
|
||||
#endif
|
||||
|
||||
void cpu_outb(pio_addr_t addr, uint8_t val);
|
||||
void cpu_outw(pio_addr_t addr, uint16_t val);
|
||||
void cpu_outl(pio_addr_t addr, uint32_t val);
|
||||
|
||||
+18
-1
@@ -106,7 +106,16 @@ PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size,
|
||||
#define PCI_HOST_PROP_PCI_HOLE64_START "pci-hole64-start"
|
||||
#define PCI_HOST_PROP_PCI_HOLE64_END "pci-hole64-end"
|
||||
#define PCI_HOST_PROP_PCI_HOLE64_SIZE "pci-hole64-size"
|
||||
#define DEFAULT_PCI_HOLE64_SIZE (1ULL << 31)
|
||||
#define DEFAULT_PCI_HOLE64_SIZE (~0x0ULL)
|
||||
|
||||
static inline uint64_t pci_host_get_hole64_size(uint64_t pci_hole64_size)
|
||||
{
|
||||
if (pci_hole64_size == DEFAULT_PCI_HOLE64_SIZE) {
|
||||
return 1ULL << 62;
|
||||
} else {
|
||||
return pci_hole64_size;
|
||||
}
|
||||
}
|
||||
|
||||
void pc_init_pci64_hole(PcPciInfo *pci_info, uint64_t pci_hole64_start,
|
||||
uint64_t pci_hole64_size);
|
||||
@@ -249,6 +258,14 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t);
|
||||
.driver = TYPE_X86_CPU,\
|
||||
.property = "pmu",\
|
||||
.value = "on",\
|
||||
},{\
|
||||
.driver = "i440FX-pcihost",\
|
||||
.property = "short_root_bus",\
|
||||
.value = stringify(0),\
|
||||
},{\
|
||||
.driver = "q35-pcihost",\
|
||||
.property = "short_root_bus",\
|
||||
.value = stringify(0),\
|
||||
}
|
||||
|
||||
#define PC_COMPAT_1_4 \
|
||||
|
||||
@@ -61,6 +61,7 @@ typedef struct MCHPCIState {
|
||||
ram_addr_t above_4g_mem_size;
|
||||
uint64_t pci_hole64_size;
|
||||
PcGuestInfo *guest_info;
|
||||
uint32_t short_root_bus;
|
||||
} MCHPCIState;
|
||||
|
||||
typedef struct Q35PCIHost {
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#define MAX_SCSI_DEVS 255
|
||||
|
||||
#define SCSI_CMD_BUF_SIZE 16
|
||||
#define SCSI_SENSE_LEN 18
|
||||
#define SCSI_INQUIRY_LEN 36
|
||||
|
||||
typedef struct SCSIBus SCSIBus;
|
||||
typedef struct SCSIBusInfo SCSIBusInfo;
|
||||
|
||||
@@ -123,6 +123,7 @@ typedef struct VirtIOBlock {
|
||||
BlockConf *conf;
|
||||
VirtIOBlkConf blk;
|
||||
unsigned short sector_mask;
|
||||
bool original_wce;
|
||||
VMChangeStateEntry *change;
|
||||
#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
|
||||
Notifier migration_state_notifier;
|
||||
|
||||
@@ -37,17 +37,15 @@ void xen_cmos_set_s3_resume(void *opaque, int irq, int level);
|
||||
qemu_irq *xen_interrupt_controller_init(void);
|
||||
|
||||
int xen_init(void);
|
||||
int xen_hvm_init(void);
|
||||
int xen_hvm_init(MemoryRegion **ram_memory);
|
||||
void xenstore_store_pv_console_info(int i, struct CharDriverState *chr);
|
||||
|
||||
#if defined(NEED_CPU_H) && !defined(CONFIG_USER_ONLY)
|
||||
struct MemoryRegion;
|
||||
void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size,
|
||||
struct MemoryRegion *mr);
|
||||
void xen_modified_memory(ram_addr_t start, ram_addr_t length);
|
||||
#endif
|
||||
|
||||
struct MemoryRegion;
|
||||
void xen_register_framebuffer(struct MemoryRegion *mr);
|
||||
|
||||
#if defined(CONFIG_XEN) && CONFIG_XEN_CTRL_INTERFACE_VERSION < 400
|
||||
|
||||
@@ -183,6 +183,86 @@ static inline unsigned long hweight_long(unsigned long w)
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* rol8 - rotate an 8-bit value left
|
||||
* @word: value to rotate
|
||||
* @shift: bits to roll
|
||||
*/
|
||||
static inline uint8_t rol8(uint8_t word, unsigned int shift)
|
||||
{
|
||||
return (word << shift) | (word >> (8 - shift));
|
||||
}
|
||||
|
||||
/**
|
||||
* ror8 - rotate an 8-bit value right
|
||||
* @word: value to rotate
|
||||
* @shift: bits to roll
|
||||
*/
|
||||
static inline uint8_t ror8(uint8_t word, unsigned int shift)
|
||||
{
|
||||
return (word >> shift) | (word << (8 - shift));
|
||||
}
|
||||
|
||||
/**
|
||||
* rol16 - rotate a 16-bit value left
|
||||
* @word: value to rotate
|
||||
* @shift: bits to roll
|
||||
*/
|
||||
static inline uint16_t rol16(uint16_t word, unsigned int shift)
|
||||
{
|
||||
return (word << shift) | (word >> (16 - shift));
|
||||
}
|
||||
|
||||
/**
|
||||
* ror16 - rotate a 16-bit value right
|
||||
* @word: value to rotate
|
||||
* @shift: bits to roll
|
||||
*/
|
||||
static inline uint16_t ror16(uint16_t word, unsigned int shift)
|
||||
{
|
||||
return (word >> shift) | (word << (16 - shift));
|
||||
}
|
||||
|
||||
/**
|
||||
* rol32 - rotate a 32-bit value left
|
||||
* @word: value to rotate
|
||||
* @shift: bits to roll
|
||||
*/
|
||||
static inline uint32_t rol32(uint32_t word, unsigned int shift)
|
||||
{
|
||||
return (word << shift) | (word >> (32 - shift));
|
||||
}
|
||||
|
||||
/**
|
||||
* ror32 - rotate a 32-bit value right
|
||||
* @word: value to rotate
|
||||
* @shift: bits to roll
|
||||
*/
|
||||
static inline uint32_t ror32(uint32_t word, unsigned int shift)
|
||||
{
|
||||
return (word >> shift) | (word << (32 - shift));
|
||||
}
|
||||
|
||||
/**
|
||||
* rol64 - rotate a 64-bit value left
|
||||
* @word: value to rotate
|
||||
* @shift: bits to roll
|
||||
*/
|
||||
static inline uint64_t rol64(uint64_t word, unsigned int shift)
|
||||
{
|
||||
return (word << shift) | (word >> (64 - shift));
|
||||
}
|
||||
|
||||
/**
|
||||
* ror64 - rotate a 64-bit value right
|
||||
* @word: value to rotate
|
||||
* @shift: bits to roll
|
||||
*/
|
||||
static inline uint64_t ror64(uint64_t word, unsigned int shift)
|
||||
{
|
||||
return (word >> shift) | (word << (64 - shift));
|
||||
}
|
||||
|
||||
/**
|
||||
* extract32:
|
||||
* @value: the value to extract the bit field from
|
||||
|
||||
@@ -152,6 +152,7 @@ struct kvm_run;
|
||||
* @current_tb: Currently executing TB.
|
||||
* @gdb_regs: Additional GDB registers.
|
||||
* @gdb_num_regs: Number of total registers accessible to GDB.
|
||||
* @gdb_num_g_regs: Number of registers in GDB 'g' packets.
|
||||
* @next_cpu: Next CPU sharing TB cache.
|
||||
* @kvm_fd: vCPU file descriptor for KVM.
|
||||
*
|
||||
@@ -188,6 +189,7 @@ struct CPUState {
|
||||
struct TranslationBlock *current_tb;
|
||||
struct GDBRegisterState *gdb_regs;
|
||||
int gdb_num_regs;
|
||||
int gdb_num_g_regs;
|
||||
CPUState *next_cpu;
|
||||
|
||||
int kvm_fd;
|
||||
|
||||
@@ -78,6 +78,7 @@ struct CharDriverState {
|
||||
int explicit_be_open;
|
||||
int avail_connections;
|
||||
int is_mux;
|
||||
guint fd_in_tag;
|
||||
QemuOpts *opts;
|
||||
QTAILQ_ENTRY(CharDriverState) next;
|
||||
};
|
||||
|
||||
@@ -39,9 +39,11 @@ int vm_stop(RunState state);
|
||||
int vm_stop_force_state(RunState state);
|
||||
|
||||
typedef enum WakeupReason {
|
||||
QEMU_WAKEUP_REASON_OTHER = 0,
|
||||
/* Always keep QEMU_WAKEUP_REASON_NONE = 0 */
|
||||
QEMU_WAKEUP_REASON_NONE = 0,
|
||||
QEMU_WAKEUP_REASON_RTC,
|
||||
QEMU_WAKEUP_REASON_PMTIMER,
|
||||
QEMU_WAKEUP_REASON_OTHER,
|
||||
} WakeupReason;
|
||||
|
||||
void qemu_system_reset_request(void);
|
||||
|
||||
@@ -44,6 +44,22 @@ typedef struct MemoryRegionPortioList {
|
||||
MemoryRegionPortio ports[];
|
||||
} MemoryRegionPortioList;
|
||||
|
||||
static uint64_t unassigned_io_read(void *opaque, hwaddr addr, unsigned size)
|
||||
{
|
||||
return -1ULL;
|
||||
}
|
||||
|
||||
static void unassigned_io_write(void *opaque, hwaddr addr, uint64_t val,
|
||||
unsigned size)
|
||||
{
|
||||
}
|
||||
|
||||
const MemoryRegionOps unassigned_io_ops = {
|
||||
.read = unassigned_io_read,
|
||||
.write = unassigned_io_write,
|
||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
};
|
||||
|
||||
void cpu_outb(pio_addr_t addr, uint8_t val)
|
||||
{
|
||||
LOG_IOPORT("outb: %04"FMT_pioaddr" %02"PRIx8"\n", addr, val);
|
||||
|
||||
@@ -4764,10 +4764,10 @@ static inline abi_long host_to_target_stat64(void *cpu_env,
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
#if TARGET_ABI_BITS == 64 && !defined(TARGET_ALPHA)
|
||||
struct target_stat *target_st;
|
||||
#else
|
||||
#if defined(TARGET_HAS_STRUCT_STAT64)
|
||||
struct target_stat64 *target_st;
|
||||
#else
|
||||
struct target_stat *target_st;
|
||||
#endif
|
||||
|
||||
if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
|
||||
|
||||
@@ -1165,6 +1165,7 @@ struct target_stat {
|
||||
/* This matches struct stat64 in glibc2.1, hence the absolutely
|
||||
* insane amounts of padding around dev_t's.
|
||||
*/
|
||||
#define TARGET_HAS_STRUCT_STAT64
|
||||
struct target_stat64 {
|
||||
unsigned short st_dev;
|
||||
unsigned char __pad0[10];
|
||||
@@ -1200,6 +1201,7 @@ struct target_stat64 {
|
||||
} QEMU_PACKED;
|
||||
|
||||
#ifdef TARGET_ARM
|
||||
#define TARGET_HAS_STRUCT_STAT64
|
||||
struct target_eabi_stat64 {
|
||||
unsigned long long st_dev;
|
||||
unsigned int __pad1;
|
||||
@@ -1249,6 +1251,7 @@ struct target_stat {
|
||||
abi_ulong __unused4[2];
|
||||
};
|
||||
|
||||
#define TARGET_HAS_STRUCT_STAT64
|
||||
struct target_stat64 {
|
||||
unsigned char __pad0[6];
|
||||
unsigned short st_dev;
|
||||
@@ -1304,6 +1307,7 @@ struct target_stat {
|
||||
abi_ulong __unused4[2];
|
||||
};
|
||||
|
||||
#define TARGET_HAS_STRUCT_STAT64
|
||||
struct target_stat64 {
|
||||
unsigned char __pad0[6];
|
||||
unsigned short st_dev;
|
||||
@@ -1371,6 +1375,8 @@ struct target_stat {
|
||||
#endif
|
||||
};
|
||||
|
||||
#if !defined(TARGET_PPC64) || defined(TARGET_ABI32)
|
||||
#define TARGET_HAS_STRUCT_STAT64
|
||||
struct QEMU_PACKED target_stat64 {
|
||||
unsigned long long st_dev;
|
||||
unsigned long long st_ino;
|
||||
@@ -1393,6 +1399,7 @@ struct QEMU_PACKED target_stat64 {
|
||||
unsigned int __unused4;
|
||||
unsigned int __unused5;
|
||||
};
|
||||
#endif
|
||||
|
||||
#elif defined(TARGET_MICROBLAZE)
|
||||
|
||||
@@ -1418,6 +1425,7 @@ struct target_stat {
|
||||
};
|
||||
|
||||
/* FIXME: Microblaze no-mmu user-space has a difference stat64 layout... */
|
||||
#define TARGET_HAS_STRUCT_STAT64
|
||||
struct QEMU_PACKED target_stat64 {
|
||||
uint64_t st_dev;
|
||||
#define TARGET_STAT64_HAS_BROKEN_ST_INO 1
|
||||
@@ -1473,6 +1481,7 @@ struct target_stat {
|
||||
/* This matches struct stat64 in glibc2.1, hence the absolutely
|
||||
* insane amounts of padding around dev_t's.
|
||||
*/
|
||||
#define TARGET_HAS_STRUCT_STAT64
|
||||
struct target_stat64 {
|
||||
unsigned long long st_dev;
|
||||
unsigned char __pad1[2];
|
||||
@@ -1581,6 +1590,7 @@ struct target_stat {
|
||||
* struct stat of the 64-bit kernel.
|
||||
*/
|
||||
|
||||
#define TARGET_HAS_STRUCT_STAT64
|
||||
struct target_stat64 {
|
||||
unsigned int st_dev;
|
||||
unsigned int st_pad0[3]; /* Reserved for st_dev expansion */
|
||||
@@ -1652,6 +1662,7 @@ struct target_stat {
|
||||
* struct stat of the 64-bit kernel.
|
||||
*/
|
||||
|
||||
#define TARGET_HAS_STRUCT_STAT64
|
||||
struct target_stat64 {
|
||||
abi_ulong st_dev;
|
||||
abi_ulong st_pad0[3]; /* Reserved for st_dev expansion */
|
||||
@@ -1708,6 +1719,7 @@ struct target_stat {
|
||||
unsigned int st_gen;
|
||||
};
|
||||
|
||||
#define TARGET_HAS_STRUCT_STAT64
|
||||
struct target_stat64 {
|
||||
abi_ulong st_dev;
|
||||
abi_ulong st_ino;
|
||||
@@ -1757,6 +1769,7 @@ struct target_stat {
|
||||
/* This matches struct stat64 in glibc2.1, hence the absolutely
|
||||
* insane amounts of padding around dev_t's.
|
||||
*/
|
||||
#define TARGET_HAS_STRUCT_STAT64
|
||||
struct QEMU_PACKED target_stat64 {
|
||||
unsigned long long st_dev;
|
||||
unsigned char __pad0[4];
|
||||
@@ -1862,6 +1875,7 @@ struct target_stat {
|
||||
unsigned int __unused5;
|
||||
};
|
||||
|
||||
#define TARGET_HAS_STRUCT_STAT64
|
||||
struct target_stat64 {
|
||||
uint64_t st_dev;
|
||||
uint64_t st_ino;
|
||||
|
||||
@@ -872,7 +872,7 @@ static uint64_t unassigned_mem_read(void *opaque, hwaddr addr,
|
||||
if (current_cpu != NULL) {
|
||||
cpu_unassigned_access(current_cpu, addr, false, false, 0, size);
|
||||
}
|
||||
return -1ULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void unassigned_mem_write(void *opaque, hwaddr addr,
|
||||
@@ -1809,7 +1809,9 @@ static void mtree_print_mr(fprintf_function mon_printf, void *f,
|
||||
mr->alias->name,
|
||||
mr->alias_offset,
|
||||
mr->alias_offset
|
||||
+ (hwaddr)int128_get64(mr->size) - 1);
|
||||
+ (int128_nz(mr->size) ?
|
||||
(hwaddr)int128_get64(int128_sub(mr->size,
|
||||
int128_one())) : 0));
|
||||
} else {
|
||||
mon_printf(f,
|
||||
TARGET_FMT_plx "-" TARGET_FMT_plx " (prio %d, %c%c): %s\n",
|
||||
|
||||
+5
-3
@@ -920,9 +920,11 @@ static int qemu_rdma_resolve_host(RDMAContext *rdma, Error **errp)
|
||||
ret = rdma_resolve_addr(rdma->cm_id, NULL, e->ai_dst_addr,
|
||||
RDMA_RESOLVE_TIMEOUT_MS);
|
||||
if (!ret) {
|
||||
ret = qemu_rdma_broken_ipv6_kernel(errp, rdma->cm_id->verbs);
|
||||
if (ret) {
|
||||
continue;
|
||||
if (e->ai_family == AF_INET6) {
|
||||
ret = qemu_rdma_broken_ipv6_kernel(errp, rdma->cm_id->verbs);
|
||||
if (ret) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
goto route;
|
||||
}
|
||||
|
||||
@@ -508,7 +508,6 @@ static const char *monitor_event_names[] = {
|
||||
QEMU_BUILD_BUG_ON(ARRAY_SIZE(monitor_event_names) != QEVENT_MAX)
|
||||
|
||||
MonitorEventState monitor_event_state[QEVENT_MAX];
|
||||
QemuMutex monitor_event_state_lock;
|
||||
|
||||
/*
|
||||
* Emits the event to every monitor instance
|
||||
@@ -540,7 +539,6 @@ monitor_protocol_event_queue(MonitorEvent event,
|
||||
int64_t now = qemu_get_clock_ns(rt_clock);
|
||||
assert(event < QEVENT_MAX);
|
||||
|
||||
qemu_mutex_lock(&monitor_event_state_lock);
|
||||
evstate = &(monitor_event_state[event]);
|
||||
trace_monitor_protocol_event_queue(event,
|
||||
data,
|
||||
@@ -573,7 +571,6 @@ monitor_protocol_event_queue(MonitorEvent event,
|
||||
evstate->last = now;
|
||||
}
|
||||
}
|
||||
qemu_mutex_unlock(&monitor_event_state_lock);
|
||||
}
|
||||
|
||||
|
||||
@@ -586,7 +583,6 @@ static void monitor_protocol_event_handler(void *opaque)
|
||||
MonitorEventState *evstate = opaque;
|
||||
int64_t now = qemu_get_clock_ns(rt_clock);
|
||||
|
||||
qemu_mutex_lock(&monitor_event_state_lock);
|
||||
|
||||
trace_monitor_protocol_event_handler(evstate->event,
|
||||
evstate->data,
|
||||
@@ -598,7 +594,6 @@ static void monitor_protocol_event_handler(void *opaque)
|
||||
evstate->data = NULL;
|
||||
}
|
||||
evstate->last = now;
|
||||
qemu_mutex_unlock(&monitor_event_state_lock);
|
||||
}
|
||||
|
||||
|
||||
@@ -635,7 +630,6 @@ monitor_protocol_event_throttle(MonitorEvent event,
|
||||
* and initialize state */
|
||||
static void monitor_protocol_event_init(void)
|
||||
{
|
||||
qemu_mutex_init(&monitor_event_state_lock);
|
||||
/* Limit RTC & BALLOON events to 1 per second */
|
||||
monitor_protocol_event_throttle(QEVENT_RTC_CHANGE, 1000);
|
||||
monitor_protocol_event_throttle(QEVENT_BALLOON_CHANGE, 1000);
|
||||
|
||||
@@ -44,8 +44,6 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr,
|
||||
struct stat s;
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
|
||||
defined(__OpenBSD__) || defined(__APPLE__)
|
||||
/* if no ifname is given, always start the search from tap0/tun0. */
|
||||
int i;
|
||||
char dname[100];
|
||||
@@ -76,15 +74,6 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr,
|
||||
dname, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
TFR(fd = open("/dev/tap", O_RDWR));
|
||||
if (fd < 0) {
|
||||
fprintf(stderr,
|
||||
"warning: could not open /dev/tap: no virtual network emulation: %s\n",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TAPGIFNAME
|
||||
if (ioctl(fd, TAPGIFNAME, (void *)&ifr) < 0) {
|
||||
|
||||
@@ -76,6 +76,24 @@ static void qapi_dealloc_end_struct(Visitor *v, Error **errp)
|
||||
}
|
||||
}
|
||||
|
||||
static void qapi_dealloc_start_implicit_struct(Visitor *v,
|
||||
void **obj,
|
||||
size_t size,
|
||||
Error **errp)
|
||||
{
|
||||
QapiDeallocVisitor *qov = to_qov(v);
|
||||
qapi_dealloc_push(qov, obj);
|
||||
}
|
||||
|
||||
static void qapi_dealloc_end_implicit_struct(Visitor *v, Error **errp)
|
||||
{
|
||||
QapiDeallocVisitor *qov = to_qov(v);
|
||||
void **obj = qapi_dealloc_pop(qov);
|
||||
if (obj) {
|
||||
g_free(*obj);
|
||||
}
|
||||
}
|
||||
|
||||
static void qapi_dealloc_start_list(Visitor *v, const char *name, Error **errp)
|
||||
{
|
||||
QapiDeallocVisitor *qov = to_qov(v);
|
||||
@@ -162,6 +180,8 @@ QapiDeallocVisitor *qapi_dealloc_visitor_new(void)
|
||||
|
||||
v->visitor.start_struct = qapi_dealloc_start_struct;
|
||||
v->visitor.end_struct = qapi_dealloc_end_struct;
|
||||
v->visitor.start_implicit_struct = qapi_dealloc_start_implicit_struct;
|
||||
v->visitor.end_implicit_struct = qapi_dealloc_end_implicit_struct;
|
||||
v->visitor.start_list = qapi_dealloc_start_list;
|
||||
v->visitor.next_list = qapi_dealloc_next_list;
|
||||
v->visitor.end_list = qapi_dealloc_end_list;
|
||||
|
||||
@@ -472,6 +472,12 @@ DeviceState *qdev_device_add(QemuOpts *opts)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (object_class_is_abstract(obj)) {
|
||||
qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver",
|
||||
"non-abstract device type");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
k = DEVICE_CLASS(obj);
|
||||
|
||||
/* find bus */
|
||||
@@ -512,6 +518,7 @@ DeviceState *qdev_device_add(QemuOpts *opts)
|
||||
}
|
||||
if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
|
||||
qdev_free(qdev);
|
||||
object_unref(OBJECT(qdev));
|
||||
return NULL;
|
||||
}
|
||||
if (qdev->id) {
|
||||
@@ -525,6 +532,7 @@ DeviceState *qdev_device_add(QemuOpts *opts)
|
||||
g_free(name);
|
||||
}
|
||||
if (qdev_init(qdev) < 0) {
|
||||
object_unref(OBJECT(qdev));
|
||||
qerror_report(QERR_DEVICE_INIT_FAILED, driver);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+37
-61
@@ -193,6 +193,8 @@ void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
static void remove_fd_in_watch(CharDriverState *chr);
|
||||
|
||||
void qemu_chr_add_handlers(CharDriverState *s,
|
||||
IOCanReadHandler *fd_can_read,
|
||||
IOReadHandler *fd_read,
|
||||
@@ -203,6 +205,7 @@ void qemu_chr_add_handlers(CharDriverState *s,
|
||||
|
||||
if (!opaque && !fd_can_read && !fd_read && !fd_event) {
|
||||
fe_open = 0;
|
||||
remove_fd_in_watch(s);
|
||||
} else {
|
||||
fe_open = 1;
|
||||
}
|
||||
@@ -725,6 +728,14 @@ static void io_remove_watch_poll(guint tag)
|
||||
g_source_destroy(&iwp->parent);
|
||||
}
|
||||
|
||||
static void remove_fd_in_watch(CharDriverState *chr)
|
||||
{
|
||||
if (chr->fd_in_tag) {
|
||||
io_remove_watch_poll(chr->fd_in_tag);
|
||||
chr->fd_in_tag = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
static GIOChannel *io_channel_from_fd(int fd)
|
||||
{
|
||||
@@ -798,7 +809,6 @@ static int io_channel_send(GIOChannel *fd, const void *buf, size_t len)
|
||||
typedef struct FDCharDriver {
|
||||
CharDriverState *chr;
|
||||
GIOChannel *fd_in, *fd_out;
|
||||
guint fd_in_tag;
|
||||
int max_size;
|
||||
QTAILQ_ENTRY(FDCharDriver) node;
|
||||
} FDCharDriver;
|
||||
@@ -830,10 +840,7 @@ static gboolean fd_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque)
|
||||
status = g_io_channel_read_chars(chan, (gchar *)buf,
|
||||
len, &bytes_read, NULL);
|
||||
if (status == G_IO_STATUS_EOF) {
|
||||
if (s->fd_in_tag) {
|
||||
io_remove_watch_poll(s->fd_in_tag);
|
||||
s->fd_in_tag = 0;
|
||||
}
|
||||
remove_fd_in_watch(chr);
|
||||
qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
|
||||
return FALSE;
|
||||
}
|
||||
@@ -863,13 +870,10 @@ static void fd_chr_update_read_handler(CharDriverState *chr)
|
||||
{
|
||||
FDCharDriver *s = chr->opaque;
|
||||
|
||||
if (s->fd_in_tag) {
|
||||
io_remove_watch_poll(s->fd_in_tag);
|
||||
s->fd_in_tag = 0;
|
||||
}
|
||||
|
||||
remove_fd_in_watch(chr);
|
||||
if (s->fd_in) {
|
||||
s->fd_in_tag = io_add_watch_poll(s->fd_in, fd_chr_read_poll, fd_chr_read, chr);
|
||||
chr->fd_in_tag = io_add_watch_poll(s->fd_in, fd_chr_read_poll,
|
||||
fd_chr_read, chr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -877,11 +881,7 @@ static void fd_chr_close(struct CharDriverState *chr)
|
||||
{
|
||||
FDCharDriver *s = chr->opaque;
|
||||
|
||||
if (s->fd_in_tag) {
|
||||
io_remove_watch_poll(s->fd_in_tag);
|
||||
s->fd_in_tag = 0;
|
||||
}
|
||||
|
||||
remove_fd_in_watch(chr);
|
||||
if (s->fd_in) {
|
||||
g_io_channel_unref(s->fd_in);
|
||||
}
|
||||
@@ -1012,7 +1012,6 @@ static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts)
|
||||
|
||||
typedef struct {
|
||||
GIOChannel *fd;
|
||||
guint fd_tag;
|
||||
int connected;
|
||||
int read_bytes;
|
||||
guint timer_tag;
|
||||
@@ -1026,15 +1025,11 @@ static gboolean pty_chr_timer(gpointer opaque)
|
||||
struct CharDriverState *chr = opaque;
|
||||
PtyCharDriver *s = chr->opaque;
|
||||
|
||||
if (s->connected) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Next poll ... */
|
||||
pty_chr_update_read_handler(chr);
|
||||
|
||||
out:
|
||||
s->timer_tag = 0;
|
||||
if (!s->connected) {
|
||||
/* Next poll ... */
|
||||
pty_chr_update_read_handler(chr);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1127,10 +1122,7 @@ static void pty_chr_state(CharDriverState *chr, int connected)
|
||||
PtyCharDriver *s = chr->opaque;
|
||||
|
||||
if (!connected) {
|
||||
if (s->fd_tag) {
|
||||
io_remove_watch_poll(s->fd_tag);
|
||||
s->fd_tag = 0;
|
||||
}
|
||||
remove_fd_in_watch(chr);
|
||||
s->connected = 0;
|
||||
/* (re-)connect poll interval for idle guests: once per second.
|
||||
* We check more frequently in case the guests sends data to
|
||||
@@ -1144,7 +1136,8 @@ static void pty_chr_state(CharDriverState *chr, int connected)
|
||||
if (!s->connected) {
|
||||
s->connected = 1;
|
||||
qemu_chr_be_generic_open(chr);
|
||||
s->fd_tag = io_add_watch_poll(s->fd, pty_chr_read_poll, pty_chr_read, chr);
|
||||
chr->fd_in_tag = io_add_watch_poll(s->fd, pty_chr_read_poll,
|
||||
pty_chr_read, chr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1155,10 +1148,7 @@ static void pty_chr_close(struct CharDriverState *chr)
|
||||
PtyCharDriver *s = chr->opaque;
|
||||
int fd;
|
||||
|
||||
if (s->fd_tag) {
|
||||
io_remove_watch_poll(s->fd_tag);
|
||||
s->fd_tag = 0;
|
||||
}
|
||||
remove_fd_in_watch(chr);
|
||||
fd = g_io_channel_unix_get_fd(s->fd);
|
||||
g_io_channel_unref(s->fd);
|
||||
close(fd);
|
||||
@@ -2165,7 +2155,6 @@ static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts)
|
||||
typedef struct {
|
||||
int fd;
|
||||
GIOChannel *chan;
|
||||
guint tag;
|
||||
uint8_t buf[READ_BUF_LEN];
|
||||
int bufcnt;
|
||||
int bufptr;
|
||||
@@ -2221,10 +2210,7 @@ static gboolean udp_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque)
|
||||
s->bufcnt = bytes_read;
|
||||
s->bufptr = s->bufcnt;
|
||||
if (status != G_IO_STATUS_NORMAL) {
|
||||
if (s->tag) {
|
||||
io_remove_watch_poll(s->tag);
|
||||
s->tag = 0;
|
||||
}
|
||||
remove_fd_in_watch(chr);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -2242,23 +2228,18 @@ static void udp_chr_update_read_handler(CharDriverState *chr)
|
||||
{
|
||||
NetCharDriver *s = chr->opaque;
|
||||
|
||||
if (s->tag) {
|
||||
io_remove_watch_poll(s->tag);
|
||||
s->tag = 0;
|
||||
}
|
||||
|
||||
remove_fd_in_watch(chr);
|
||||
if (s->chan) {
|
||||
s->tag = io_add_watch_poll(s->chan, udp_chr_read_poll, udp_chr_read, chr);
|
||||
chr->fd_in_tag = io_add_watch_poll(s->chan, udp_chr_read_poll,
|
||||
udp_chr_read, chr);
|
||||
}
|
||||
}
|
||||
|
||||
static void udp_chr_close(CharDriverState *chr)
|
||||
{
|
||||
NetCharDriver *s = chr->opaque;
|
||||
if (s->tag) {
|
||||
io_remove_watch_poll(s->tag);
|
||||
s->tag = 0;
|
||||
}
|
||||
|
||||
remove_fd_in_watch(chr);
|
||||
if (s->chan) {
|
||||
g_io_channel_unref(s->chan);
|
||||
closesocket(s->fd);
|
||||
@@ -2308,7 +2289,7 @@ static CharDriverState *qemu_chr_open_udp(QemuOpts *opts)
|
||||
typedef struct {
|
||||
|
||||
GIOChannel *chan, *listen_chan;
|
||||
guint tag, listen_tag;
|
||||
guint listen_tag;
|
||||
int fd, listen_fd;
|
||||
int connected;
|
||||
int max_size;
|
||||
@@ -2493,10 +2474,7 @@ static gboolean tcp_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque)
|
||||
if (s->listen_chan) {
|
||||
s->listen_tag = g_io_add_watch(s->listen_chan, G_IO_IN, tcp_chr_accept, chr);
|
||||
}
|
||||
if (s->tag) {
|
||||
io_remove_watch_poll(s->tag);
|
||||
s->tag = 0;
|
||||
}
|
||||
remove_fd_in_watch(chr);
|
||||
g_io_channel_unref(s->chan);
|
||||
s->chan = NULL;
|
||||
closesocket(s->fd);
|
||||
@@ -2526,7 +2504,8 @@ static void tcp_chr_connect(void *opaque)
|
||||
|
||||
s->connected = 1;
|
||||
if (s->chan) {
|
||||
s->tag = io_add_watch_poll(s->chan, tcp_chr_read_poll, tcp_chr_read, chr);
|
||||
chr->fd_in_tag = io_add_watch_poll(s->chan, tcp_chr_read_poll,
|
||||
tcp_chr_read, chr);
|
||||
}
|
||||
qemu_chr_be_generic_open(chr);
|
||||
}
|
||||
@@ -2609,10 +2588,7 @@ static void tcp_chr_close(CharDriverState *chr)
|
||||
{
|
||||
TCPCharDriver *s = chr->opaque;
|
||||
if (s->fd >= 0) {
|
||||
if (s->tag) {
|
||||
io_remove_watch_poll(s->tag);
|
||||
s->tag = 0;
|
||||
}
|
||||
remove_fd_in_watch(chr);
|
||||
if (s->chan) {
|
||||
g_io_channel_unref(s->chan);
|
||||
}
|
||||
@@ -2993,11 +2969,11 @@ QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
|
||||
if (strstart(filename, "vc", &p)) {
|
||||
qemu_opt_set(opts, "backend", "vc");
|
||||
if (*p == ':') {
|
||||
if (sscanf(p+1, "%8[0-9]x%8[0-9]", width, height) == 2) {
|
||||
if (sscanf(p+1, "%7[0-9]x%7[0-9]", width, height) == 2) {
|
||||
/* pixels */
|
||||
qemu_opt_set(opts, "width", width);
|
||||
qemu_opt_set(opts, "height", height);
|
||||
} else if (sscanf(p+1, "%8[0-9]Cx%8[0-9]C", width, height) == 2) {
|
||||
} else if (sscanf(p+1, "%7[0-9]Cx%7[0-9]C", width, height) == 2) {
|
||||
/* chars */
|
||||
qemu_opt_set(opts, "cols", width);
|
||||
qemu_opt_set(opts, "rows", height);
|
||||
|
||||
+18
-14
@@ -30,15 +30,17 @@ static unsigned int pool_size;
|
||||
|
||||
Coroutine *qemu_coroutine_create(CoroutineEntry *entry)
|
||||
{
|
||||
Coroutine *co;
|
||||
Coroutine *co = NULL;
|
||||
|
||||
qemu_mutex_lock(&pool_lock);
|
||||
co = QSLIST_FIRST(&pool);
|
||||
if (co) {
|
||||
QSLIST_REMOVE_HEAD(&pool, pool_next);
|
||||
pool_size--;
|
||||
if (CONFIG_COROUTINE_POOL) {
|
||||
qemu_mutex_lock(&pool_lock);
|
||||
co = QSLIST_FIRST(&pool);
|
||||
if (co) {
|
||||
QSLIST_REMOVE_HEAD(&pool, pool_next);
|
||||
pool_size--;
|
||||
}
|
||||
qemu_mutex_unlock(&pool_lock);
|
||||
}
|
||||
qemu_mutex_unlock(&pool_lock);
|
||||
|
||||
if (!co) {
|
||||
co = qemu_coroutine_new();
|
||||
@@ -51,15 +53,17 @@ Coroutine *qemu_coroutine_create(CoroutineEntry *entry)
|
||||
|
||||
static void coroutine_delete(Coroutine *co)
|
||||
{
|
||||
qemu_mutex_lock(&pool_lock);
|
||||
if (pool_size < POOL_MAX_SIZE) {
|
||||
QSLIST_INSERT_HEAD(&pool, co, pool_next);
|
||||
co->caller = NULL;
|
||||
pool_size++;
|
||||
if (CONFIG_COROUTINE_POOL) {
|
||||
qemu_mutex_lock(&pool_lock);
|
||||
if (pool_size < POOL_MAX_SIZE) {
|
||||
QSLIST_INSERT_HEAD(&pool, co, pool_next);
|
||||
co->caller = NULL;
|
||||
pool_size++;
|
||||
qemu_mutex_unlock(&pool_lock);
|
||||
return;
|
||||
}
|
||||
qemu_mutex_unlock(&pool_lock);
|
||||
return;
|
||||
}
|
||||
qemu_mutex_unlock(&pool_lock);
|
||||
|
||||
qemu_coroutine_delete(co);
|
||||
}
|
||||
|
||||
+14
-2
@@ -1485,8 +1485,15 @@ static int img_convert(int argc, char **argv)
|
||||
are present in both the output's and input's base images (no
|
||||
need to copy them). */
|
||||
if (out_baseimg) {
|
||||
if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
|
||||
n, &n1)) {
|
||||
ret = bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
|
||||
n, &n1);
|
||||
if (ret < 0) {
|
||||
error_report("error while reading metadata for sector "
|
||||
"%" PRId64 ": %s",
|
||||
sector_num - bs_offset, strerror(-ret));
|
||||
goto out;
|
||||
}
|
||||
if (!ret) {
|
||||
sector_num += n1;
|
||||
continue;
|
||||
}
|
||||
@@ -2076,6 +2083,11 @@ static int img_rebase(int argc, char **argv)
|
||||
|
||||
/* If the cluster is allocated, we don't need to take action */
|
||||
ret = bdrv_is_allocated(bs, sector, n, &n);
|
||||
if (ret < 0) {
|
||||
error_report("error while reading image metadata: %s",
|
||||
strerror(-ret));
|
||||
goto out;
|
||||
}
|
||||
if (ret) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1829,6 +1829,10 @@ static int alloc_f(BlockDriverState *bs, int argc, char **argv)
|
||||
sector_num = offset >> 9;
|
||||
while (remaining) {
|
||||
ret = bdrv_is_allocated(bs, sector_num, remaining, &num);
|
||||
if (ret < 0) {
|
||||
printf("is_allocated failed: %s\n", strerror(-ret));
|
||||
return 0;
|
||||
}
|
||||
sector_num += num;
|
||||
remaining -= num;
|
||||
if (ret) {
|
||||
|
||||
@@ -113,6 +113,7 @@ static const struct QemuSeccompSyscall seccomp_whitelist[] = {
|
||||
{ SCMP_SYS(write), 244 },
|
||||
{ SCMP_SYS(fcntl), 243 },
|
||||
{ SCMP_SYS(tgkill), 242 },
|
||||
{ SCMP_SYS(kill), 242 },
|
||||
{ SCMP_SYS(rt_sigaction), 242 },
|
||||
{ SCMP_SYS(pipe2), 242 },
|
||||
{ SCMP_SYS(munmap), 242 },
|
||||
|
||||
@@ -566,7 +566,7 @@ typedef struct FsMount {
|
||||
QTAILQ_ENTRY(FsMount) next;
|
||||
} FsMount;
|
||||
|
||||
typedef QTAILQ_HEAD(, FsMount) FsMountList;
|
||||
typedef QTAILQ_HEAD(FsMountList, FsMount) FsMountList;
|
||||
|
||||
static void free_fs_mount_list(FsMountList *mounts)
|
||||
{
|
||||
@@ -728,7 +728,7 @@ int64_t qmp_guest_fsfreeze_freeze(Error **err)
|
||||
/* cannot risk guest agent blocking itself on a write in this state */
|
||||
ga_set_frozen(ga_state);
|
||||
|
||||
QTAILQ_FOREACH(mount, &mounts, next) {
|
||||
QTAILQ_FOREACH_REVERSE(mount, &mounts, FsMountList, next) {
|
||||
fd = qemu_open(mount->dirname, O_RDONLY);
|
||||
if (fd == -1) {
|
||||
error_setg_errno(err, errno, "failed to open %s", mount->dirname);
|
||||
|
||||
@@ -240,7 +240,7 @@ static void cpu_common_initfn(Object *obj)
|
||||
CPUState *cpu = CPU(obj);
|
||||
CPUClass *cc = CPU_GET_CLASS(obj);
|
||||
|
||||
cpu->gdb_num_regs = cc->gdb_num_core_regs;
|
||||
cpu->gdb_num_regs = cpu->gdb_num_g_regs = cc->gdb_num_core_regs;
|
||||
}
|
||||
|
||||
static int64_t cpu_common_get_arch_id(CPUState *cpu)
|
||||
|
||||
+3
-2
@@ -823,8 +823,9 @@ char *object_property_get_str(Object *obj, const char *name,
|
||||
void object_property_set_link(Object *obj, Object *value,
|
||||
const char *name, Error **errp)
|
||||
{
|
||||
object_property_set_str(obj, object_get_canonical_path(value),
|
||||
name, errp);
|
||||
gchar *path = object_get_canonical_path(value);
|
||||
object_property_set_str(obj, path, name, errp);
|
||||
g_free(path);
|
||||
}
|
||||
|
||||
Object *object_property_get_link(Object *obj, const char *name,
|
||||
|
||||
@@ -51,7 +51,10 @@ def generate_fwd_enum_struct(name, members):
|
||||
return mcgen('''
|
||||
typedef struct %(name)sList
|
||||
{
|
||||
%(name)s value;
|
||||
union {
|
||||
%(name)s value;
|
||||
uint64_t padding;
|
||||
};
|
||||
struct %(name)sList *next;
|
||||
} %(name)sList;
|
||||
''',
|
||||
|
||||
+14
-3
@@ -20,7 +20,10 @@ import errno
|
||||
def generate_visit_struct_fields(name, field_prefix, fn_prefix, members):
|
||||
substructs = []
|
||||
ret = ''
|
||||
full_name = name if not fn_prefix else "%s_%s" % (name, fn_prefix)
|
||||
if not fn_prefix:
|
||||
full_name = name
|
||||
else:
|
||||
full_name = "%s_%s" % (name, fn_prefix)
|
||||
|
||||
for argname, argentry, optional, structured in parse_args(members):
|
||||
if structured:
|
||||
@@ -84,7 +87,10 @@ if (!error_is_set(errp)) {
|
||||
''')
|
||||
push_indent()
|
||||
|
||||
full_name = name if not field_prefix else "%s_%s" % (field_prefix, name)
|
||||
if not field_prefix:
|
||||
full_name = name
|
||||
else:
|
||||
full_name = "%s_%s" % (field_prefix, name)
|
||||
|
||||
if len(field_prefix):
|
||||
ret += mcgen('''
|
||||
@@ -265,12 +271,17 @@ void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **
|
||||
name=name)
|
||||
|
||||
pop_indent()
|
||||
|
||||
if not discriminator:
|
||||
desc_type = "type"
|
||||
else:
|
||||
desc_type = discriminator
|
||||
ret += mcgen('''
|
||||
visit_type_%(name)sKind(m, &(*obj)->kind, "%(type)s", &err);
|
||||
if (!err) {
|
||||
switch ((*obj)->kind) {
|
||||
''',
|
||||
name=name, type="type" if not discriminator else discriminator)
|
||||
name=name, type=desc_type)
|
||||
|
||||
for key in members:
|
||||
if not discriminator:
|
||||
|
||||
+1
-1
@@ -161,7 +161,7 @@ class QAPISchema:
|
||||
def parse_schema(fp):
|
||||
try:
|
||||
schema = QAPISchema(fp)
|
||||
except QAPISchemaError as e:
|
||||
except QAPISchemaError, e:
|
||||
print >>sys.stderr, e
|
||||
exit(1)
|
||||
|
||||
|
||||
@@ -577,7 +577,7 @@ uint64_t HELPER(iwmmxt_rorl)(CPUARMState *env, uint64_t x, uint32_t n)
|
||||
|
||||
uint64_t HELPER(iwmmxt_rorq)(CPUARMState *env, uint64_t x, uint32_t n)
|
||||
{
|
||||
x = (x >> n) | (x << (64 - n));
|
||||
x = ror64(x, n);
|
||||
env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = NZBIT64(x);
|
||||
return x;
|
||||
}
|
||||
|
||||
+16
-18
@@ -894,7 +894,10 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
||||
uint32_t page_offset;
|
||||
int page_size;
|
||||
|
||||
if (env->cr[4] & CR4_PAE_MASK) {
|
||||
if (!(env->cr[0] & CR0_PG_MASK)) {
|
||||
pte = addr & env->a20_mask;
|
||||
page_size = 4096;
|
||||
} else if (env->cr[4] & CR4_PAE_MASK) {
|
||||
target_ulong pdpe_addr;
|
||||
uint64_t pde, pdpe;
|
||||
|
||||
@@ -952,26 +955,21 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
||||
} else {
|
||||
uint32_t pde;
|
||||
|
||||
if (!(env->cr[0] & CR0_PG_MASK)) {
|
||||
pte = addr;
|
||||
page_size = 4096;
|
||||
/* page directory entry */
|
||||
pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & env->a20_mask;
|
||||
pde = ldl_phys(pde_addr);
|
||||
if (!(pde & PG_PRESENT_MASK))
|
||||
return -1;
|
||||
if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
|
||||
pte = pde & ~0x003ff000; /* align to 4MB */
|
||||
page_size = 4096 * 1024;
|
||||
} else {
|
||||
/* page directory entry */
|
||||
pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & env->a20_mask;
|
||||
pde = ldl_phys(pde_addr);
|
||||
if (!(pde & PG_PRESENT_MASK))
|
||||
pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask;
|
||||
pte = ldl_phys(pte_addr);
|
||||
if (!(pte & PG_PRESENT_MASK))
|
||||
return -1;
|
||||
if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
|
||||
pte = pde & ~0x003ff000; /* align to 4MB */
|
||||
page_size = 4096 * 1024;
|
||||
} else {
|
||||
/* page directory entry */
|
||||
pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask;
|
||||
pte = ldl_phys(pte_addr);
|
||||
if (!(pte & PG_PRESENT_MASK))
|
||||
return -1;
|
||||
page_size = 4096;
|
||||
}
|
||||
page_size = 4096;
|
||||
}
|
||||
pte = pte & env->a20_mask;
|
||||
}
|
||||
|
||||
@@ -15988,10 +15988,13 @@ void cpu_state_reset(CPUMIPSState *env)
|
||||
if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
|
||||
env->CP0_Status |= (1 << CP0St_MX);
|
||||
}
|
||||
/* Enable 64-bit FPU if the target cpu supports it. */
|
||||
if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
|
||||
# if defined(TARGET_MIPS64)
|
||||
/* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
|
||||
if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
|
||||
(env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
|
||||
env->CP0_Status |= (1 << CP0St_FR);
|
||||
}
|
||||
# endif
|
||||
#else
|
||||
if (env->hflags & MIPS_HFLAG_BMASK) {
|
||||
/* If the exception was raised from a delay slot,
|
||||
|
||||
@@ -428,9 +428,9 @@ EXTRACT_HELPER(CRM, 12, 8);
|
||||
EXTRACT_HELPER(SR, 16, 4);
|
||||
|
||||
/* mtfsf/mtfsfi */
|
||||
EXTRACT_HELPER(FPBF, 19, 3);
|
||||
EXTRACT_HELPER(FPBF, 23, 3);
|
||||
EXTRACT_HELPER(FPIMM, 12, 4);
|
||||
EXTRACT_HELPER(FPL, 21, 1);
|
||||
EXTRACT_HELPER(FPL, 25, 1);
|
||||
EXTRACT_HELPER(FPFLM, 17, 8);
|
||||
EXTRACT_HELPER(FPW, 16, 1);
|
||||
|
||||
|
||||
+4
-8
@@ -236,20 +236,16 @@ static TCGArg do_constant_folding_2(TCGOpcode op, TCGArg x, TCGArg y)
|
||||
return (int64_t)x >> (int64_t)y;
|
||||
|
||||
case INDEX_op_rotr_i32:
|
||||
x = ((uint32_t)x << (32 - y)) | ((uint32_t)x >> y);
|
||||
return x;
|
||||
return ror32(x, y);
|
||||
|
||||
case INDEX_op_rotr_i64:
|
||||
x = ((uint64_t)x << (64 - y)) | ((uint64_t)x >> y);
|
||||
return x;
|
||||
return ror64(x, y);
|
||||
|
||||
case INDEX_op_rotl_i32:
|
||||
x = ((uint32_t)x << y) | ((uint32_t)x >> (32 - y));
|
||||
return x;
|
||||
return rol32(x, y);
|
||||
|
||||
case INDEX_op_rotl_i64:
|
||||
x = ((uint64_t)x << y) | ((uint64_t)x >> (64 - y));
|
||||
return x;
|
||||
return rol64(x, y);
|
||||
|
||||
CASE_OP_32_64(not):
|
||||
return ~x;
|
||||
|
||||
@@ -677,7 +677,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
|
||||
case INDEX_op_shl_i64:
|
||||
case INDEX_op_shr_i64:
|
||||
case INDEX_op_sar_i64:
|
||||
/* TODO: Implementation of rotl_i64, rotr_i64 missing in tci.c. */
|
||||
case INDEX_op_rotl_i64: /* Optional (TCG_TARGET_HAS_rot_i64). */
|
||||
case INDEX_op_rotr_i64: /* Optional (TCG_TARGET_HAS_rot_i64). */
|
||||
tcg_out_r(s, args[0]);
|
||||
|
||||
@@ -688,13 +688,13 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr)
|
||||
t0 = *tb_ptr++;
|
||||
t1 = tci_read_ri32(&tb_ptr);
|
||||
t2 = tci_read_ri32(&tb_ptr);
|
||||
tci_write_reg32(t0, (t1 << t2) | (t1 >> (32 - t2)));
|
||||
tci_write_reg32(t0, rol32(t1, t2));
|
||||
break;
|
||||
case INDEX_op_rotr_i32:
|
||||
t0 = *tb_ptr++;
|
||||
t1 = tci_read_ri32(&tb_ptr);
|
||||
t2 = tci_read_ri32(&tb_ptr);
|
||||
tci_write_reg32(t0, (t1 >> t2) | (t1 << (32 - t2)));
|
||||
tci_write_reg32(t0, ror32(t1, t2));
|
||||
break;
|
||||
#endif
|
||||
#if TCG_TARGET_HAS_deposit_i32
|
||||
@@ -952,8 +952,16 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr)
|
||||
break;
|
||||
#if TCG_TARGET_HAS_rot_i64
|
||||
case INDEX_op_rotl_i64:
|
||||
t0 = *tb_ptr++;
|
||||
t1 = tci_read_ri64(&tb_ptr);
|
||||
t2 = tci_read_ri64(&tb_ptr);
|
||||
tci_write_reg64(t0, rol64(t1, t2));
|
||||
break;
|
||||
case INDEX_op_rotr_i64:
|
||||
TODO();
|
||||
t0 = *tb_ptr++;
|
||||
t1 = tci_read_ri64(&tb_ptr);
|
||||
t2 = tci_read_ri64(&tb_ptr);
|
||||
tci_write_reg64(t0, ror64(t1, t2));
|
||||
break;
|
||||
#endif
|
||||
#if TCG_TARGET_HAS_deposit_i64
|
||||
@@ -1085,7 +1093,6 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr)
|
||||
tmp8 = helper_ldb_mmu(env, taddr, tci_read_i(&tb_ptr));
|
||||
#else
|
||||
host_addr = (tcg_target_ulong)taddr;
|
||||
assert(taddr == host_addr);
|
||||
tmp8 = *(uint8_t *)(host_addr + GUEST_BASE);
|
||||
#endif
|
||||
tci_write_reg8(t0, tmp8);
|
||||
@@ -1097,7 +1104,6 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr)
|
||||
tmp8 = helper_ldb_mmu(env, taddr, tci_read_i(&tb_ptr));
|
||||
#else
|
||||
host_addr = (tcg_target_ulong)taddr;
|
||||
assert(taddr == host_addr);
|
||||
tmp8 = *(uint8_t *)(host_addr + GUEST_BASE);
|
||||
#endif
|
||||
tci_write_reg8s(t0, tmp8);
|
||||
@@ -1109,7 +1115,6 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr)
|
||||
tmp16 = helper_ldw_mmu(env, taddr, tci_read_i(&tb_ptr));
|
||||
#else
|
||||
host_addr = (tcg_target_ulong)taddr;
|
||||
assert(taddr == host_addr);
|
||||
tmp16 = tswap16(*(uint16_t *)(host_addr + GUEST_BASE));
|
||||
#endif
|
||||
tci_write_reg16(t0, tmp16);
|
||||
@@ -1121,7 +1126,6 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr)
|
||||
tmp16 = helper_ldw_mmu(env, taddr, tci_read_i(&tb_ptr));
|
||||
#else
|
||||
host_addr = (tcg_target_ulong)taddr;
|
||||
assert(taddr == host_addr);
|
||||
tmp16 = tswap16(*(uint16_t *)(host_addr + GUEST_BASE));
|
||||
#endif
|
||||
tci_write_reg16s(t0, tmp16);
|
||||
@@ -1134,7 +1138,6 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr)
|
||||
tmp32 = helper_ldl_mmu(env, taddr, tci_read_i(&tb_ptr));
|
||||
#else
|
||||
host_addr = (tcg_target_ulong)taddr;
|
||||
assert(taddr == host_addr);
|
||||
tmp32 = tswap32(*(uint32_t *)(host_addr + GUEST_BASE));
|
||||
#endif
|
||||
tci_write_reg32(t0, tmp32);
|
||||
@@ -1146,7 +1149,6 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr)
|
||||
tmp32 = helper_ldl_mmu(env, taddr, tci_read_i(&tb_ptr));
|
||||
#else
|
||||
host_addr = (tcg_target_ulong)taddr;
|
||||
assert(taddr == host_addr);
|
||||
tmp32 = tswap32(*(uint32_t *)(host_addr + GUEST_BASE));
|
||||
#endif
|
||||
tci_write_reg32s(t0, tmp32);
|
||||
@@ -1159,7 +1161,6 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr)
|
||||
tmp32 = helper_ldl_mmu(env, taddr, tci_read_i(&tb_ptr));
|
||||
#else
|
||||
host_addr = (tcg_target_ulong)taddr;
|
||||
assert(taddr == host_addr);
|
||||
tmp32 = tswap32(*(uint32_t *)(host_addr + GUEST_BASE));
|
||||
#endif
|
||||
tci_write_reg32(t0, tmp32);
|
||||
@@ -1174,7 +1175,6 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr)
|
||||
tmp64 = helper_ldq_mmu(env, taddr, tci_read_i(&tb_ptr));
|
||||
#else
|
||||
host_addr = (tcg_target_ulong)taddr;
|
||||
assert(taddr == host_addr);
|
||||
tmp64 = tswap64(*(uint64_t *)(host_addr + GUEST_BASE));
|
||||
#endif
|
||||
tci_write_reg(t0, tmp64);
|
||||
@@ -1190,7 +1190,6 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr)
|
||||
helper_stb_mmu(env, taddr, t0, t2);
|
||||
#else
|
||||
host_addr = (tcg_target_ulong)taddr;
|
||||
assert(taddr == host_addr);
|
||||
*(uint8_t *)(host_addr + GUEST_BASE) = t0;
|
||||
#endif
|
||||
break;
|
||||
@@ -1202,7 +1201,6 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr)
|
||||
helper_stw_mmu(env, taddr, t0, t2);
|
||||
#else
|
||||
host_addr = (tcg_target_ulong)taddr;
|
||||
assert(taddr == host_addr);
|
||||
*(uint16_t *)(host_addr + GUEST_BASE) = tswap16(t0);
|
||||
#endif
|
||||
break;
|
||||
@@ -1214,7 +1212,6 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr)
|
||||
helper_stl_mmu(env, taddr, t0, t2);
|
||||
#else
|
||||
host_addr = (tcg_target_ulong)taddr;
|
||||
assert(taddr == host_addr);
|
||||
*(uint32_t *)(host_addr + GUEST_BASE) = tswap32(t0);
|
||||
#endif
|
||||
break;
|
||||
@@ -1226,7 +1223,6 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr)
|
||||
helper_stq_mmu(env, taddr, tmp64, t2);
|
||||
#else
|
||||
host_addr = (tcg_target_ulong)taddr;
|
||||
assert(taddr == host_addr);
|
||||
*(uint64_t *)(host_addr + GUEST_BASE) = tswap64(tmp64);
|
||||
#endif
|
||||
break;
|
||||
|
||||
@@ -5,8 +5,10 @@ check-qjson
|
||||
check-qlist
|
||||
check-qstring
|
||||
test-aio
|
||||
test-bitops
|
||||
test-cutils
|
||||
test-hbitmap
|
||||
test-int128
|
||||
test-iov
|
||||
test-mul64
|
||||
test-qapi-types.[ch]
|
||||
@@ -19,3 +21,4 @@ test-thread-pool
|
||||
test-x86-cpuid
|
||||
test-xbzrle
|
||||
*-test
|
||||
qapi-schema/*.test.*
|
||||
|
||||
+4
-4
@@ -247,10 +247,10 @@ check-tests/test-qapi.py: tests/test-qapi.py
|
||||
|
||||
.PHONY: $(patsubst %, check-%, $(check-qapi-schema-y))
|
||||
$(patsubst %, check-%, $(check-qapi-schema-y)): check-%.json: $(SRC_PATH)/%.json
|
||||
$(call quiet-command, PYTHONPATH=$(SRC_PATH)/scripts $(PYTHON) $(SRC_PATH)/tests/qapi-schema/test-qapi.py <$^ >$*.out 2>$*.err; echo $$? >$*.exit, " TEST $*.out")
|
||||
@diff -q $(SRC_PATH)/$*.out $*.out
|
||||
@diff -q $(SRC_PATH)/$*.err $*.err
|
||||
@diff -q $(SRC_PATH)/$*.exit $*.exit
|
||||
$(call quiet-command, PYTHONPATH=$(SRC_PATH)/scripts $(PYTHON) $(SRC_PATH)/tests/qapi-schema/test-qapi.py <$^ >$*.test.out 2>$*.test.err; echo $$? >$*.test.exit, " TEST $*.out")
|
||||
@diff -q $(SRC_PATH)/$*.out $*.test.out
|
||||
@diff -q $(SRC_PATH)/$*.err $*.test.err
|
||||
@diff -q $(SRC_PATH)/$*.exit $*.test.exit
|
||||
|
||||
# Consolidated targets
|
||||
|
||||
|
||||
@@ -66,6 +66,11 @@ poke_file "$TEST_IMG" "$capacity_offset" "\xff\xff\xff\xff"
|
||||
poke_file "$TEST_IMG" "$grain_table_size_offset" "\x01\x00\x00\x00"
|
||||
{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
|
||||
|
||||
echo
|
||||
echo "=== Testing big twoGbMaxExtentFlat ==="
|
||||
IMGOPTS="subformat=twoGbMaxExtentFlat" _make_test_img 1000G
|
||||
$QEMU_IMG info $TEST_IMG | _filter_testdir | sed -e 's/cid: [0-9]*/cid: XXXXXXXX/'
|
||||
|
||||
# success, all done
|
||||
echo "*** done"
|
||||
rm -f $seq.full
|
||||
|
||||
+2019
-8
File diff suppressed because it is too large
Load Diff
@@ -604,6 +604,7 @@ static void test_visitor_in_errors(TestInputVisitorData *data,
|
||||
g_assert(error_is_set(&errp));
|
||||
g_assert(p->string == NULL);
|
||||
|
||||
error_free(errp);
|
||||
g_free(p->string);
|
||||
g_free(p);
|
||||
}
|
||||
|
||||
+4
-6
@@ -181,13 +181,11 @@ ssize_t iov_send_recv(int sockfd, struct iovec *iov, unsigned iov_cnt,
|
||||
assert(iov[niov].iov_len > tail);
|
||||
orig_len = iov[niov].iov_len;
|
||||
iov[niov++].iov_len = tail;
|
||||
}
|
||||
|
||||
ret = do_send_recv(sockfd, iov, niov, do_send);
|
||||
|
||||
/* Undo the changes above before checking for errors */
|
||||
if (tail) {
|
||||
ret = do_send_recv(sockfd, iov, niov, do_send);
|
||||
/* Undo the changes above before checking for errors */
|
||||
iov[niov-1].iov_len = orig_len;
|
||||
} else {
|
||||
ret = do_send_recv(sockfd, iov, niov, do_send);
|
||||
}
|
||||
if (offset) {
|
||||
iov[0].iov_base -= offset;
|
||||
|
||||
@@ -1792,14 +1792,14 @@ static pid_t shutdown_pid;
|
||||
static int powerdown_requested;
|
||||
static int debug_requested;
|
||||
static int suspend_requested;
|
||||
static int wakeup_requested;
|
||||
static WakeupReason wakeup_reason;
|
||||
static NotifierList powerdown_notifiers =
|
||||
NOTIFIER_LIST_INITIALIZER(powerdown_notifiers);
|
||||
static NotifierList suspend_notifiers =
|
||||
NOTIFIER_LIST_INITIALIZER(suspend_notifiers);
|
||||
static NotifierList wakeup_notifiers =
|
||||
NOTIFIER_LIST_INITIALIZER(wakeup_notifiers);
|
||||
static uint32_t wakeup_reason_mask = ~0;
|
||||
static uint32_t wakeup_reason_mask = ~(1 << QEMU_WAKEUP_REASON_NONE);
|
||||
static RunState vmstop_requested = RUN_STATE_MAX;
|
||||
|
||||
int qemu_shutdown_requested_get(void)
|
||||
@@ -1849,11 +1849,9 @@ static int qemu_suspend_requested(void)
|
||||
return r;
|
||||
}
|
||||
|
||||
static int qemu_wakeup_requested(void)
|
||||
static WakeupReason qemu_wakeup_requested(void)
|
||||
{
|
||||
int r = wakeup_requested;
|
||||
wakeup_requested = 0;
|
||||
return r;
|
||||
return wakeup_reason;
|
||||
}
|
||||
|
||||
static int qemu_powerdown_requested(void)
|
||||
@@ -1970,8 +1968,7 @@ void qemu_system_wakeup_request(WakeupReason reason)
|
||||
return;
|
||||
}
|
||||
runstate_set(RUN_STATE_RUNNING);
|
||||
notifier_list_notify(&wakeup_notifiers, &reason);
|
||||
wakeup_requested = 1;
|
||||
wakeup_reason = reason;
|
||||
qemu_notify_event();
|
||||
}
|
||||
|
||||
@@ -2063,6 +2060,8 @@ static bool main_loop_should_exit(void)
|
||||
pause_all_vcpus();
|
||||
cpu_synchronize_all_states();
|
||||
qemu_system_reset(VMRESET_SILENT);
|
||||
notifier_list_notify(&wakeup_notifiers, &wakeup_reason);
|
||||
wakeup_reason = QEMU_WAKEUP_REASON_NONE;
|
||||
resume_all_vcpus();
|
||||
monitor_protocol_event(QEVENT_WAKEUP, NULL);
|
||||
}
|
||||
|
||||
@@ -98,6 +98,7 @@ typedef struct XenIOState {
|
||||
|
||||
Notifier exit;
|
||||
Notifier suspend;
|
||||
Notifier wakeup;
|
||||
} XenIOState;
|
||||
|
||||
/* Xen specific function for piix pci */
|
||||
@@ -154,7 +155,7 @@ qemu_irq *xen_interrupt_controller_init(void)
|
||||
|
||||
/* Memory Ops */
|
||||
|
||||
static void xen_ram_init(ram_addr_t ram_size)
|
||||
static void xen_ram_init(ram_addr_t ram_size, MemoryRegion **ram_memory_p)
|
||||
{
|
||||
MemoryRegion *sysmem = get_system_memory();
|
||||
ram_addr_t below_4g_mem_size, above_4g_mem_size = 0;
|
||||
@@ -168,6 +169,7 @@ static void xen_ram_init(ram_addr_t ram_size)
|
||||
block_len += HVM_BELOW_4G_MMIO_LENGTH;
|
||||
}
|
||||
memory_region_init_ram(&ram_memory, NULL, "xen.ram", block_len);
|
||||
*ram_memory_p = &ram_memory;
|
||||
vmstate_register_ram_global(&ram_memory);
|
||||
|
||||
if (ram_size >= HVM_BELOW_4G_RAM_END) {
|
||||
@@ -1059,7 +1061,12 @@ static void xen_read_physmap(XenIOState *state)
|
||||
free(entries);
|
||||
}
|
||||
|
||||
int xen_hvm_init(void)
|
||||
static void xen_wakeup_notifier(Notifier *notifier, void *data)
|
||||
{
|
||||
xc_set_hvm_param(xen_xc, xen_domid, HVM_PARAM_ACPI_S_STATE, 0);
|
||||
}
|
||||
|
||||
int xen_hvm_init(MemoryRegion **ram_memory)
|
||||
{
|
||||
int i, rc;
|
||||
unsigned long ioreq_pfn;
|
||||
@@ -1088,6 +1095,9 @@ int xen_hvm_init(void)
|
||||
state->suspend.notify = xen_suspend_notifier;
|
||||
qemu_register_suspend_notifier(&state->suspend);
|
||||
|
||||
state->wakeup.notify = xen_wakeup_notifier;
|
||||
qemu_register_wakeup_notifier(&state->wakeup);
|
||||
|
||||
xc_get_hvm_param(xen_xc, xen_domid, HVM_PARAM_IOREQ_PFN, &ioreq_pfn);
|
||||
DPRINTF("shared page at pfn %lx\n", ioreq_pfn);
|
||||
state->shared_page = xc_map_foreign_range(xen_xc, xen_domid, XC_PAGE_SIZE,
|
||||
@@ -1134,7 +1144,7 @@ int xen_hvm_init(void)
|
||||
|
||||
/* Init RAM management */
|
||||
xen_map_cache_init(xen_phys_offset_to_gaddr, state);
|
||||
xen_ram_init(ram_size);
|
||||
xen_ram_init(ram_size, ram_memory);
|
||||
|
||||
qemu_add_vm_change_state_handler(xen_hvm_change_state_handler, state);
|
||||
|
||||
|
||||
+1
-1
@@ -64,7 +64,7 @@ void xen_modified_memory(ram_addr_t start, ram_addr_t length)
|
||||
{
|
||||
}
|
||||
|
||||
int xen_hvm_init(void)
|
||||
int xen_hvm_init(MemoryRegion **ram_memory)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user