Compare commits
97 Commits
master
...
stable-2.1
Author | SHA1 | Date |
---|---|---|
Michael Roth | ba87166e14 | |
Laurent Vivier | b7d059b91f | |
Suraj Jitindar Singh | 2f3e3890c4 | |
Alex Williamson | 26c1b49d56 | |
David Gibson | 5f214279d4 | |
Gerd Hoffmann | 9c7714afd7 | |
Gerd Hoffmann | a0ad811956 | |
Eric Blake | b81833fe7d | |
Eric Blake | 0fd80ef569 | |
Vladimir Sementsov-Ogievskiy | b01b1609e6 | |
Greg Kurz | 82ded5166b | |
Eric Blake | 227196c1e7 | |
Eric Blake | 2ce8993512 | |
Jason Wang | c2269a0b54 | |
Peter Lieven | 30e499bdc9 | |
Michael Roth | e1a2a27327 | |
Greg Kurz | a77c5873fe | |
Daniel Henrique Barboza | 0a5a2b938a | |
Maxime Coquelin | 0bc76c8d08 | |
Maxime Coquelin | 059422ddbc | |
Max Reitz | d6c99e8ff5 | |
Eric Blake | 56a10ff664 | |
Jens Freimann | 69f562ad9e | |
Jens Freimann | 957bd48acf | |
Eric Auger | 3a82a03a2e | |
Peter Maydell | b637b865ed | |
Greg Kurz | 3342fd0286 | |
Daniel P. Berrange | e0809fcc4b | |
Paolo Bonzini | e31942b486 | |
Max Reitz | 5aa698ab5f | |
Max Reitz | 39475b8805 | |
Max Reitz | a25aca75f8 | |
Michael Olbrich | 64f62e4e90 | |
Maxime Coquelin | d765c5e577 | |
Peter Xu | ae13e2cfa8 | |
Peter Xu | c9dbe3e0fc | |
Alexey Kardashevskiy | 496f97293e | |
Paolo Bonzini | 639701e4f2 | |
Paolo Bonzini | 5dbd1f7884 | |
Alexey Kardashevskiy | 5b5e49ab5f | |
Alexey Kardashevskiy | a7bb94e784 | |
Alexey Kardashevskiy | 7dd7f7ef44 | |
Alexey Kardashevskiy | e8c7ea3e75 | |
Alexey Kardashevskiy | c943efe8b5 | |
Alexey Kardashevskiy | c14ce078b2 | |
Alexey Kardashevskiy | 260d3646b0 | |
Alexey Kardashevskiy | 08101db63b | |
Alexey Kardashevskiy | eff5ed4ae9 | |
Alexey Kardashevskiy | f7774e329b | |
Paolo Bonzini | 3568e11940 | |
Alexey Kardashevskiy | d0136db812 | |
Alexey Kardashevskiy | 4d2f8abb22 | |
Alexey Kardashevskiy | de7e6815b8 | |
Alexey Kardashevskiy | 1b04a15809 | |
Alexey Kardashevskiy | 6424975ce9 | |
Eric Blake | 4af42e3cf1 | |
Jim Somerville | 26914ce48d | |
Vladimir Sementsov-Ogievskiy | 49958d37e7 | |
Thomas Huth | b234266086 | |
Daniel Henrique Barboza | 62695f60c3 | |
Michael Roth | 7851197b81 | |
Peter Lieven | 547435f550 | |
Christian Borntraeger | 17cd46fbdf | |
Anthony PERARD | 6a903482b1 | |
Anthony PERARD | 8edf4c6adc | |
Anthony PERARD | 2c3a8cc581 | |
Stefan Hajnoczi | 0691b70a2a | |
Alex Bennée | 4d824886c8 | |
Vladimir Sementsov-Ogievskiy | 780fb4ce48 | |
Manos Pitsidianakis | 7496699ba6 | |
Eric Blake | 33a599667a | |
Christian Borntraeger | a432f419ab | |
Jan Dakinevich | a83858fdb5 | |
Jan Dakinevich | d13a0bde83 | |
Jan Dakinevich | e90997dc8f | |
Gerd Hoffmann | 7e1288cd0c | |
Igor Mammedov | 83b23fe55c | |
Thomas Huth | e96002e0d1 | |
Thomas Huth | cc7dd3ad3f | |
Thomas Huth | de4ad17a8e | |
Thomas Huth | 8a9d7f3063 | |
Thomas Huth | d3f05848fc | |
Prasad J Pandit | fca5f37fe9 | |
Gerd Hoffmann | 2965be1f00 | |
Gerd Hoffmann | d6f7f3b0cf | |
Marc-André Lureau | 2a2eab6660 | |
Marc-André Lureau | 48f65ce837 | |
Hannes Reinecke | b95fbe6f12 | |
Peter Maydell | b8cd978919 | |
Alex Williamson | b24304ca13 | |
Pavel Butsykin | c6841b112e | |
Thomas Huth | 65a24b5c44 | |
Pranith Kumar | 85cdc23e75 | |
Greg Kurz | 168ff32c5d | |
Richard Henderson | 728bfa3273 | |
Farhan Ali | e1b4750f06 | |
Samuel Thibault | 53d421dd9c |
|
@ -763,7 +763,7 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
|
|||
|
||||
cpu->mem_io_vaddr = addr;
|
||||
|
||||
if (mr->global_locking) {
|
||||
if (mr->global_locking && !qemu_mutex_iothread_locked()) {
|
||||
qemu_mutex_lock_iothread();
|
||||
locked = true;
|
||||
}
|
||||
|
@ -791,7 +791,7 @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
|
|||
cpu->mem_io_vaddr = addr;
|
||||
cpu->mem_io_pc = retaddr;
|
||||
|
||||
if (mr->global_locking) {
|
||||
if (mr->global_locking && !qemu_mutex_iothread_locked()) {
|
||||
qemu_mutex_lock_iothread();
|
||||
locked = true;
|
||||
}
|
||||
|
|
122
block/io.c
122
block/io.c
|
@ -34,6 +34,9 @@
|
|||
|
||||
#define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */
|
||||
|
||||
/* Maximum bounce buffer for copy-on-read and write zeroes, in bytes */
|
||||
#define MAX_BOUNCE_BUFFER (32768 << BDRV_SECTOR_BITS)
|
||||
|
||||
static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
|
||||
int64_t offset, int bytes, BdrvRequestFlags flags);
|
||||
|
||||
|
@ -945,11 +948,14 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child,
|
|||
|
||||
BlockDriver *drv = bs->drv;
|
||||
struct iovec iov;
|
||||
QEMUIOVector bounce_qiov;
|
||||
QEMUIOVector local_qiov;
|
||||
int64_t cluster_offset;
|
||||
unsigned int cluster_bytes;
|
||||
size_t skip_bytes;
|
||||
int ret;
|
||||
int max_transfer = MIN_NON_ZERO(bs->bl.max_transfer,
|
||||
BDRV_REQUEST_MAX_BYTES);
|
||||
unsigned int progress = 0;
|
||||
|
||||
/* FIXME We cannot require callers to have write permissions when all they
|
||||
* are doing is a read request. If we did things right, write permissions
|
||||
|
@ -961,52 +967,94 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child,
|
|||
// assert(child->perm & (BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE));
|
||||
|
||||
/* Cover entire cluster so no additional backing file I/O is required when
|
||||
* allocating cluster in the image file.
|
||||
* allocating cluster in the image file. Note that this value may exceed
|
||||
* BDRV_REQUEST_MAX_BYTES (even when the original read did not), which
|
||||
* is one reason we loop rather than doing it all at once.
|
||||
*/
|
||||
bdrv_round_to_clusters(bs, offset, bytes, &cluster_offset, &cluster_bytes);
|
||||
skip_bytes = offset - cluster_offset;
|
||||
|
||||
trace_bdrv_co_do_copy_on_readv(bs, offset, bytes,
|
||||
cluster_offset, cluster_bytes);
|
||||
|
||||
iov.iov_len = cluster_bytes;
|
||||
iov.iov_base = bounce_buffer = qemu_try_blockalign(bs, iov.iov_len);
|
||||
bounce_buffer = qemu_try_blockalign(bs,
|
||||
MIN(MIN(max_transfer, cluster_bytes),
|
||||
MAX_BOUNCE_BUFFER));
|
||||
if (bounce_buffer == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
qemu_iovec_init_external(&bounce_qiov, &iov, 1);
|
||||
while (cluster_bytes) {
|
||||
int64_t pnum;
|
||||
|
||||
ret = bdrv_driver_preadv(bs, cluster_offset, cluster_bytes,
|
||||
&bounce_qiov, 0);
|
||||
if (ret < 0) {
|
||||
goto err;
|
||||
ret = bdrv_is_allocated(bs, cluster_offset,
|
||||
MIN(cluster_bytes, max_transfer), &pnum);
|
||||
if (ret < 0) {
|
||||
/* Safe to treat errors in querying allocation as if
|
||||
* unallocated; we'll probably fail again soon on the
|
||||
* read, but at least that will set a decent errno.
|
||||
*/
|
||||
pnum = MIN(cluster_bytes, max_transfer);
|
||||
}
|
||||
|
||||
assert(skip_bytes < pnum);
|
||||
|
||||
if (ret <= 0) {
|
||||
/* Must copy-on-read; use the bounce buffer */
|
||||
iov.iov_base = bounce_buffer;
|
||||
iov.iov_len = pnum = MIN(pnum, MAX_BOUNCE_BUFFER);
|
||||
qemu_iovec_init_external(&local_qiov, &iov, 1);
|
||||
|
||||
ret = bdrv_driver_preadv(bs, cluster_offset, pnum,
|
||||
&local_qiov, 0);
|
||||
if (ret < 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (drv->bdrv_co_pwrite_zeroes &&
|
||||
buffer_is_zero(bounce_buffer, pnum)) {
|
||||
/* FIXME: Should we (perhaps conditionally) be setting
|
||||
* BDRV_REQ_MAY_UNMAP, if it will allow for a sparser copy
|
||||
* that still correctly reads as zero? */
|
||||
ret = bdrv_co_do_pwrite_zeroes(bs, cluster_offset, pnum, 0);
|
||||
} else {
|
||||
/* This does not change the data on the disk, it is not
|
||||
* necessary to flush even in cache=writethrough mode.
|
||||
*/
|
||||
ret = bdrv_driver_pwritev(bs, cluster_offset, pnum,
|
||||
&local_qiov, 0);
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
/* It might be okay to ignore write errors for guest
|
||||
* requests. If this is a deliberate copy-on-read
|
||||
* then we don't want to ignore the error. Simply
|
||||
* report it in all cases.
|
||||
*/
|
||||
goto err;
|
||||
}
|
||||
|
||||
qemu_iovec_from_buf(qiov, progress, bounce_buffer + skip_bytes,
|
||||
pnum - skip_bytes);
|
||||
} else {
|
||||
/* Read directly into the destination */
|
||||
qemu_iovec_init(&local_qiov, qiov->niov);
|
||||
qemu_iovec_concat(&local_qiov, qiov, progress, pnum - skip_bytes);
|
||||
ret = bdrv_driver_preadv(bs, offset + progress, local_qiov.size,
|
||||
&local_qiov, 0);
|
||||
qemu_iovec_destroy(&local_qiov);
|
||||
if (ret < 0) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
cluster_offset += pnum;
|
||||
cluster_bytes -= pnum;
|
||||
progress += pnum - skip_bytes;
|
||||
skip_bytes = 0;
|
||||
}
|
||||
|
||||
if (drv->bdrv_co_pwrite_zeroes &&
|
||||
buffer_is_zero(bounce_buffer, iov.iov_len)) {
|
||||
/* FIXME: Should we (perhaps conditionally) be setting
|
||||
* BDRV_REQ_MAY_UNMAP, if it will allow for a sparser copy
|
||||
* that still correctly reads as zero? */
|
||||
ret = bdrv_co_do_pwrite_zeroes(bs, cluster_offset, cluster_bytes, 0);
|
||||
} else {
|
||||
/* This does not change the data on the disk, it is not necessary
|
||||
* to flush even in cache=writethrough mode.
|
||||
*/
|
||||
ret = bdrv_driver_pwritev(bs, cluster_offset, cluster_bytes,
|
||||
&bounce_qiov, 0);
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
/* It might be okay to ignore write errors for guest requests. If this
|
||||
* is a deliberate copy-on-read then we don't want to ignore the error.
|
||||
* Simply report it in all cases.
|
||||
*/
|
||||
goto err;
|
||||
}
|
||||
|
||||
skip_bytes = offset - cluster_offset;
|
||||
qemu_iovec_from_buf(qiov, 0, bounce_buffer + skip_bytes, bytes);
|
||||
ret = 0;
|
||||
|
||||
err:
|
||||
qemu_vfree(bounce_buffer);
|
||||
|
@ -1212,9 +1260,6 @@ int coroutine_fn bdrv_co_readv(BdrvChild *child, int64_t sector_num,
|
|||
return bdrv_co_do_readv(child, sector_num, nb_sectors, qiov, 0);
|
||||
}
|
||||
|
||||
/* Maximum buffer for write zeroes fallback, in bytes */
|
||||
#define MAX_WRITE_ZEROES_BOUNCE_BUFFER (32768 << BDRV_SECTOR_BITS)
|
||||
|
||||
static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
|
||||
int64_t offset, int bytes, BdrvRequestFlags flags)
|
||||
{
|
||||
|
@ -1229,8 +1274,7 @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
|
|||
int max_write_zeroes = MIN_NON_ZERO(bs->bl.max_pwrite_zeroes, INT_MAX);
|
||||
int alignment = MAX(bs->bl.pwrite_zeroes_alignment,
|
||||
bs->bl.request_alignment);
|
||||
int max_transfer = MIN_NON_ZERO(bs->bl.max_transfer,
|
||||
MAX_WRITE_ZEROES_BOUNCE_BUFFER);
|
||||
int max_transfer = MIN_NON_ZERO(bs->bl.max_transfer, MAX_BOUNCE_BUFFER);
|
||||
|
||||
assert(alignment % bs->bl.request_alignment == 0);
|
||||
head = offset % alignment;
|
||||
|
|
|
@ -1056,6 +1056,10 @@ static int coroutine_fn bdrv_mirror_top_pwritev(BlockDriverState *bs,
|
|||
|
||||
static int coroutine_fn bdrv_mirror_top_flush(BlockDriverState *bs)
|
||||
{
|
||||
if (bs->backing == NULL) {
|
||||
/* we can be here after failed bdrv_append in mirror_start_job */
|
||||
return 0;
|
||||
}
|
||||
return bdrv_co_flush(bs->backing->bs);
|
||||
}
|
||||
|
||||
|
|
|
@ -144,12 +144,12 @@ static int nbd_co_send_request(BlockDriverState *bs,
|
|||
request->handle = INDEX_TO_HANDLE(s, i);
|
||||
|
||||
if (s->quit) {
|
||||
qemu_co_mutex_unlock(&s->send_mutex);
|
||||
return -EIO;
|
||||
rc = -EIO;
|
||||
goto err;
|
||||
}
|
||||
if (!s->ioc) {
|
||||
qemu_co_mutex_unlock(&s->send_mutex);
|
||||
return -EPIPE;
|
||||
rc = -EPIPE;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (qiov) {
|
||||
|
@ -166,8 +166,13 @@ static int nbd_co_send_request(BlockDriverState *bs,
|
|||
} else {
|
||||
rc = nbd_send_request(s->ioc, request);
|
||||
}
|
||||
|
||||
err:
|
||||
if (rc < 0) {
|
||||
s->quit = true;
|
||||
s->requests[i].coroutine = NULL;
|
||||
s->in_flight--;
|
||||
qemu_co_queue_next(&s->free_sema);
|
||||
}
|
||||
qemu_co_mutex_unlock(&s->send_mutex);
|
||||
return rc;
|
||||
|
@ -201,13 +206,6 @@ static void nbd_co_receive_reply(NBDClientSession *s,
|
|||
/* Tell the read handler to read another header. */
|
||||
s->reply.handle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void nbd_coroutine_end(BlockDriverState *bs,
|
||||
NBDRequest *request)
|
||||
{
|
||||
NBDClientSession *s = nbd_get_client_session(bs);
|
||||
int i = HANDLE_TO_INDEX(s, request->handle);
|
||||
|
||||
s->requests[i].coroutine = NULL;
|
||||
|
||||
|
@ -243,7 +241,6 @@ int nbd_client_co_preadv(BlockDriverState *bs, uint64_t offset,
|
|||
} else {
|
||||
nbd_co_receive_reply(client, &request, &reply, qiov);
|
||||
}
|
||||
nbd_coroutine_end(bs, &request);
|
||||
return -reply.error;
|
||||
}
|
||||
|
||||
|
@ -259,6 +256,7 @@ int nbd_client_co_pwritev(BlockDriverState *bs, uint64_t offset,
|
|||
NBDReply reply;
|
||||
ssize_t ret;
|
||||
|
||||
assert(!(client->info.flags & NBD_FLAG_READ_ONLY));
|
||||
if (flags & BDRV_REQ_FUA) {
|
||||
assert(client->info.flags & NBD_FLAG_SEND_FUA);
|
||||
request.flags |= NBD_CMD_FLAG_FUA;
|
||||
|
@ -272,7 +270,6 @@ int nbd_client_co_pwritev(BlockDriverState *bs, uint64_t offset,
|
|||
} else {
|
||||
nbd_co_receive_reply(client, &request, &reply, NULL);
|
||||
}
|
||||
nbd_coroutine_end(bs, &request);
|
||||
return -reply.error;
|
||||
}
|
||||
|
||||
|
@ -288,6 +285,7 @@ int nbd_client_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
|
|||
};
|
||||
NBDReply reply;
|
||||
|
||||
assert(!(client->info.flags & NBD_FLAG_READ_ONLY));
|
||||
if (!(client->info.flags & NBD_FLAG_SEND_WRITE_ZEROES)) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
@ -306,7 +304,6 @@ int nbd_client_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
|
|||
} else {
|
||||
nbd_co_receive_reply(client, &request, &reply, NULL);
|
||||
}
|
||||
nbd_coroutine_end(bs, &request);
|
||||
return -reply.error;
|
||||
}
|
||||
|
||||
|
@ -330,7 +327,6 @@ int nbd_client_co_flush(BlockDriverState *bs)
|
|||
} else {
|
||||
nbd_co_receive_reply(client, &request, &reply, NULL);
|
||||
}
|
||||
nbd_coroutine_end(bs, &request);
|
||||
return -reply.error;
|
||||
}
|
||||
|
||||
|
@ -345,6 +341,7 @@ int nbd_client_co_pdiscard(BlockDriverState *bs, int64_t offset, int bytes)
|
|||
NBDReply reply;
|
||||
ssize_t ret;
|
||||
|
||||
assert(!(client->info.flags & NBD_FLAG_READ_ONLY));
|
||||
if (!(client->info.flags & NBD_FLAG_SEND_TRIM)) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -355,7 +352,6 @@ int nbd_client_co_pdiscard(BlockDriverState *bs, int64_t offset, int bytes)
|
|||
} else {
|
||||
nbd_co_receive_reply(client, &request, &reply, NULL);
|
||||
}
|
||||
nbd_coroutine_end(bs, &request);
|
||||
return -reply.error;
|
||||
|
||||
}
|
||||
|
@ -410,6 +406,12 @@ int nbd_client_init(BlockDriverState *bs,
|
|||
logout("Failed to negotiate with the NBD server\n");
|
||||
return ret;
|
||||
}
|
||||
if (client->info.flags & NBD_FLAG_READ_ONLY &&
|
||||
!bdrv_is_read_only(bs)) {
|
||||
error_setg(errp,
|
||||
"request for write access conflicts with read-only export");
|
||||
return -EACCES;
|
||||
}
|
||||
if (client->info.flags & NBD_FLAG_SEND_FUA) {
|
||||
bs->supported_write_flags = BDRV_REQ_FUA;
|
||||
bs->supported_zero_flags |= BDRV_REQ_FUA;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* QEMU Block driver for native access to files on NFS shares
|
||||
*
|
||||
* Copyright (c) 2014-2016 Peter Lieven <pl@kamp.de>
|
||||
* Copyright (c) 2014-2017 Peter Lieven <pl@kamp.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -496,7 +496,7 @@ out:
|
|||
static int64_t nfs_client_open(NFSClient *client, QDict *options,
|
||||
int flags, int open_flags, Error **errp)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
int64_t ret = -EINVAL;
|
||||
QemuOpts *opts = NULL;
|
||||
Error *local_err = NULL;
|
||||
struct stat st;
|
||||
|
@ -686,8 +686,7 @@ static QemuOptsList nfs_create_opts = {
|
|||
|
||||
static int nfs_file_create(const char *url, QemuOpts *opts, Error **errp)
|
||||
{
|
||||
int ret = 0;
|
||||
int64_t total_size = 0;
|
||||
int64_t ret, total_size;
|
||||
NFSClient *client = g_new0(NFSClient, 1);
|
||||
QDict *options = NULL;
|
||||
|
||||
|
|
|
@ -602,7 +602,7 @@ static Qcow2BitmapList *bitmap_list_load(BlockDriverState *bs, uint64_t offset,
|
|||
goto fail;
|
||||
}
|
||||
|
||||
bm = g_new(Qcow2Bitmap, 1);
|
||||
bm = g_new0(Qcow2Bitmap, 1);
|
||||
bm->table.offset = e->bitmap_table_offset;
|
||||
bm->table.size = e->bitmap_table_size;
|
||||
bm->flags = e->flags;
|
||||
|
|
|
@ -2053,6 +2053,14 @@ static int qcow2_inactivate(BlockDriverState *bs)
|
|||
int ret, result = 0;
|
||||
Error *local_err = NULL;
|
||||
|
||||
qcow2_store_persistent_dirty_bitmaps(bs, &local_err);
|
||||
if (local_err != NULL) {
|
||||
result = -EINVAL;
|
||||
error_report_err(local_err);
|
||||
error_report("Persistent bitmaps are lost for node '%s'",
|
||||
bdrv_get_device_or_node_name(bs));
|
||||
}
|
||||
|
||||
ret = qcow2_cache_flush(bs, s->l2_table_cache);
|
||||
if (ret) {
|
||||
result = ret;
|
||||
|
@ -2067,14 +2075,6 @@ static int qcow2_inactivate(BlockDriverState *bs)
|
|||
strerror(-ret));
|
||||
}
|
||||
|
||||
qcow2_store_persistent_dirty_bitmaps(bs, &local_err);
|
||||
if (local_err != NULL) {
|
||||
result = -EINVAL;
|
||||
error_report_err(local_err);
|
||||
error_report("Persistent bitmaps are lost for node '%s'",
|
||||
bdrv_get_device_or_node_name(bs));
|
||||
}
|
||||
|
||||
if (result == 0) {
|
||||
qcow2_mark_clean(bs);
|
||||
}
|
||||
|
@ -2476,6 +2476,14 @@ static int qcow2_set_up_encryption(BlockDriverState *bs, const char *encryptfmt,
|
|||
}
|
||||
|
||||
|
||||
typedef struct PreallocCo {
|
||||
BlockDriverState *bs;
|
||||
uint64_t offset;
|
||||
uint64_t new_length;
|
||||
|
||||
int ret;
|
||||
} PreallocCo;
|
||||
|
||||
/**
|
||||
* Preallocates metadata structures for data clusters between @offset (in the
|
||||
* guest disk) and @new_length (which is thus generally the new guest disk
|
||||
|
@ -2483,9 +2491,12 @@ static int qcow2_set_up_encryption(BlockDriverState *bs, const char *encryptfmt,
|
|||
*
|
||||
* Returns: 0 on success, -errno on failure.
|
||||
*/
|
||||
static int preallocate(BlockDriverState *bs,
|
||||
uint64_t offset, uint64_t new_length)
|
||||
static void coroutine_fn preallocate_co(void *opaque)
|
||||
{
|
||||
PreallocCo *params = opaque;
|
||||
BlockDriverState *bs = params->bs;
|
||||
uint64_t offset = params->offset;
|
||||
uint64_t new_length = params->new_length;
|
||||
BDRVQcow2State *s = bs->opaque;
|
||||
uint64_t bytes;
|
||||
uint64_t host_offset = 0;
|
||||
|
@ -2493,9 +2504,7 @@ static int preallocate(BlockDriverState *bs,
|
|||
int ret;
|
||||
QCowL2Meta *meta;
|
||||
|
||||
if (qemu_in_coroutine()) {
|
||||
qemu_co_mutex_lock(&s->lock);
|
||||
}
|
||||
qemu_co_mutex_lock(&s->lock);
|
||||
|
||||
assert(offset <= new_length);
|
||||
bytes = new_length - offset;
|
||||
|
@ -2549,10 +2558,28 @@ static int preallocate(BlockDriverState *bs,
|
|||
ret = 0;
|
||||
|
||||
done:
|
||||
qemu_co_mutex_unlock(&s->lock);
|
||||
params->ret = ret;
|
||||
}
|
||||
|
||||
static int preallocate(BlockDriverState *bs,
|
||||
uint64_t offset, uint64_t new_length)
|
||||
{
|
||||
PreallocCo params = {
|
||||
.bs = bs,
|
||||
.offset = offset,
|
||||
.new_length = new_length,
|
||||
.ret = -EINPROGRESS,
|
||||
};
|
||||
|
||||
if (qemu_in_coroutine()) {
|
||||
qemu_co_mutex_unlock(&s->lock);
|
||||
preallocate_co(¶ms);
|
||||
} else {
|
||||
Coroutine *co = qemu_coroutine_create(preallocate_co, ¶ms);
|
||||
bdrv_coroutine_enter(bs, co);
|
||||
BDRV_POLL_WHILE(bs, params.ret == -EINPROGRESS);
|
||||
}
|
||||
return ret;
|
||||
return params.ret;
|
||||
}
|
||||
|
||||
/* qcow2_refcount_metadata_size:
|
||||
|
@ -3161,6 +3188,7 @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset,
|
|||
"Failed to inquire current file length");
|
||||
return ret;
|
||||
}
|
||||
old_file_size = ROUND_UP(old_file_size, s->cluster_size);
|
||||
|
||||
nb_new_data_clusters = DIV_ROUND_UP(offset - old_length,
|
||||
s->cluster_size);
|
||||
|
|
|
@ -392,17 +392,19 @@ static void coroutine_fn throttle_group_restart_queue_entry(void *opaque)
|
|||
schedule_next_request(blk, is_write);
|
||||
qemu_mutex_unlock(&tg->lock);
|
||||
}
|
||||
|
||||
g_free(data);
|
||||
}
|
||||
|
||||
static void throttle_group_restart_queue(BlockBackend *blk, bool is_write)
|
||||
{
|
||||
Coroutine *co;
|
||||
RestartData rd = {
|
||||
.blk = blk,
|
||||
.is_write = is_write
|
||||
};
|
||||
RestartData *rd = g_new0(RestartData, 1);
|
||||
|
||||
co = qemu_coroutine_create(throttle_group_restart_queue_entry, &rd);
|
||||
rd->blk = blk;
|
||||
rd->is_write = is_write;
|
||||
|
||||
co = qemu_coroutine_create(throttle_group_restart_queue_entry, rd);
|
||||
aio_co_enter(blk_get_aio_context(blk), co);
|
||||
}
|
||||
|
||||
|
|
|
@ -521,6 +521,19 @@ vu_set_vring_addr_exec(VuDev *dev, VhostUserMsg *vmsg)
|
|||
|
||||
vq->used_idx = vq->vring.used->idx;
|
||||
|
||||
if (vq->last_avail_idx != vq->used_idx) {
|
||||
bool resume = dev->iface->queue_is_processed_in_order &&
|
||||
dev->iface->queue_is_processed_in_order(dev, index);
|
||||
|
||||
DPRINT("Last avail index != used index: %u != %u%s\n",
|
||||
vq->last_avail_idx, vq->used_idx,
|
||||
resume ? ", resuming" : "");
|
||||
|
||||
if (resume) {
|
||||
vq->shadow_avail_idx = vq->last_avail_idx = vq->used_idx;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -132,6 +132,7 @@ typedef void (*vu_set_features_cb) (VuDev *dev, uint64_t features);
|
|||
typedef int (*vu_process_msg_cb) (VuDev *dev, VhostUserMsg *vmsg,
|
||||
int *do_reply);
|
||||
typedef void (*vu_queue_set_started_cb) (VuDev *dev, int qidx, bool started);
|
||||
typedef bool (*vu_queue_is_processed_in_order_cb) (VuDev *dev, int qidx);
|
||||
|
||||
typedef struct VuDevIface {
|
||||
/* called by VHOST_USER_GET_FEATURES to get the features bitmask */
|
||||
|
@ -148,6 +149,12 @@ typedef struct VuDevIface {
|
|||
vu_process_msg_cb process_msg;
|
||||
/* tells when queues can be processed */
|
||||
vu_queue_set_started_cb queue_set_started;
|
||||
/*
|
||||
* If the queue is processed in order, in which case it will be
|
||||
* resumed to vring.used->idx. This can help to support resuming
|
||||
* on unmanaged exit/crash.
|
||||
*/
|
||||
vu_queue_is_processed_in_order_cb queue_is_processed_in_order;
|
||||
} VuDevIface;
|
||||
|
||||
typedef void (*vu_queue_handler_cb) (VuDev *dev, int qidx);
|
||||
|
|
5
cpus.c
5
cpus.c
|
@ -1764,8 +1764,9 @@ void qemu_init_vcpu(CPUState *cpu)
|
|||
/* If the target cpu hasn't set up any address spaces itself,
|
||||
* give it the default one.
|
||||
*/
|
||||
AddressSpace *as = address_space_init_shareable(cpu->memory,
|
||||
"cpu-memory");
|
||||
AddressSpace *as = g_new0(AddressSpace, 1);
|
||||
|
||||
address_space_init(as, cpu->memory, "cpu-memory");
|
||||
cpu->num_ases = 1;
|
||||
cpu_address_space_init(cpu, as, 0);
|
||||
}
|
||||
|
|
|
@ -63,6 +63,7 @@ operations:
|
|||
typeof(*ptr) atomic_fetch_sub(ptr, val)
|
||||
typeof(*ptr) atomic_fetch_and(ptr, val)
|
||||
typeof(*ptr) atomic_fetch_or(ptr, val)
|
||||
typeof(*ptr) atomic_fetch_inc_nonzero(ptr)
|
||||
typeof(*ptr) atomic_xchg(ptr, val)
|
||||
typeof(*ptr) atomic_cmpxchg(ptr, old, new)
|
||||
|
||||
|
|
316
exec.c
316
exec.c
|
@ -188,21 +188,18 @@ typedef struct PhysPageMap {
|
|||
} PhysPageMap;
|
||||
|
||||
struct AddressSpaceDispatch {
|
||||
struct rcu_head rcu;
|
||||
|
||||
MemoryRegionSection *mru_section;
|
||||
/* This is a multi-level map on the physical address space.
|
||||
* The bottom level has pointers to MemoryRegionSections.
|
||||
*/
|
||||
PhysPageEntry phys_map;
|
||||
PhysPageMap map;
|
||||
AddressSpace *as;
|
||||
};
|
||||
|
||||
#define SUBPAGE_IDX(addr) ((addr) & ~TARGET_PAGE_MASK)
|
||||
typedef struct subpage_t {
|
||||
MemoryRegion iomem;
|
||||
AddressSpace *as;
|
||||
FlatView *fv;
|
||||
hwaddr base;
|
||||
uint16_t sub_section[];
|
||||
} subpage_t;
|
||||
|
@ -362,7 +359,7 @@ static void phys_page_compact(PhysPageEntry *lp, Node *nodes)
|
|||
}
|
||||
}
|
||||
|
||||
static void phys_page_compact_all(AddressSpaceDispatch *d, int nodes_nb)
|
||||
void address_space_dispatch_compact(AddressSpaceDispatch *d)
|
||||
{
|
||||
if (d->phys_map.skip) {
|
||||
phys_page_compact(&d->phys_map, d->map.nodes);
|
||||
|
@ -471,22 +468,48 @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x
|
|||
return section;
|
||||
}
|
||||
|
||||
/* Called from RCU critical section */
|
||||
static MemoryRegionSection address_space_do_translate(AddressSpace *as,
|
||||
hwaddr addr,
|
||||
hwaddr *xlat,
|
||||
hwaddr *plen,
|
||||
bool is_write,
|
||||
bool is_mmio)
|
||||
/**
|
||||
* flatview_do_translate - translate an address in FlatView
|
||||
*
|
||||
* @fv: the flat view that we want to translate on
|
||||
* @addr: the address to be translated in above address space
|
||||
* @xlat: the translated address offset within memory region. It
|
||||
* cannot be @NULL.
|
||||
* @plen_out: valid read/write length of the translated address. It
|
||||
* can be @NULL when we don't care about it.
|
||||
* @page_mask_out: page mask for the translated address. This
|
||||
* should only be meaningful for IOMMU translated
|
||||
* addresses, since there may be huge pages that this bit
|
||||
* would tell. It can be @NULL if we don't care about it.
|
||||
* @is_write: whether the translation operation is for write
|
||||
* @is_mmio: whether this can be MMIO, set true if it can
|
||||
*
|
||||
* This function is called from RCU critical section
|
||||
*/
|
||||
static MemoryRegionSection flatview_do_translate(FlatView *fv,
|
||||
hwaddr addr,
|
||||
hwaddr *xlat,
|
||||
hwaddr *plen_out,
|
||||
hwaddr *page_mask_out,
|
||||
bool is_write,
|
||||
bool is_mmio,
|
||||
AddressSpace **target_as)
|
||||
{
|
||||
IOMMUTLBEntry iotlb;
|
||||
MemoryRegionSection *section;
|
||||
IOMMUMemoryRegion *iommu_mr;
|
||||
IOMMUMemoryRegionClass *imrc;
|
||||
hwaddr page_mask = (hwaddr)(-1);
|
||||
hwaddr plen = (hwaddr)(-1);
|
||||
|
||||
if (plen_out) {
|
||||
plen = *plen_out;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
AddressSpaceDispatch *d = atomic_rcu_read(&as->dispatch);
|
||||
section = address_space_translate_internal(d, addr, &addr, plen, is_mmio);
|
||||
section = address_space_translate_internal(
|
||||
flatview_to_dispatch(fv), addr, &addr,
|
||||
&plen, is_mmio);
|
||||
|
||||
iommu_mr = memory_region_get_iommu(section->mr);
|
||||
if (!iommu_mr) {
|
||||
|
@ -498,16 +521,31 @@ static MemoryRegionSection address_space_do_translate(AddressSpace *as,
|
|||
IOMMU_WO : IOMMU_RO);
|
||||
addr = ((iotlb.translated_addr & ~iotlb.addr_mask)
|
||||
| (addr & iotlb.addr_mask));
|
||||
*plen = MIN(*plen, (addr | iotlb.addr_mask) - addr + 1);
|
||||
page_mask &= iotlb.addr_mask;
|
||||
plen = MIN(plen, (addr | iotlb.addr_mask) - addr + 1);
|
||||
if (!(iotlb.perm & (1 << is_write))) {
|
||||
goto translate_fail;
|
||||
}
|
||||
|
||||
as = iotlb.target_as;
|
||||
fv = address_space_to_flatview(iotlb.target_as);
|
||||
*target_as = iotlb.target_as;
|
||||
}
|
||||
|
||||
*xlat = addr;
|
||||
|
||||
if (page_mask == (hwaddr)(-1)) {
|
||||
/* Not behind an IOMMU, use default page size. */
|
||||
page_mask = ~TARGET_PAGE_MASK;
|
||||
}
|
||||
|
||||
if (page_mask_out) {
|
||||
*page_mask_out = page_mask;
|
||||
}
|
||||
|
||||
if (plen_out) {
|
||||
*plen_out = plen;
|
||||
}
|
||||
|
||||
return *section;
|
||||
|
||||
translate_fail:
|
||||
|
@ -519,14 +557,14 @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
|
|||
bool is_write)
|
||||
{
|
||||
MemoryRegionSection section;
|
||||
hwaddr xlat, plen;
|
||||
hwaddr xlat, page_mask;
|
||||
|
||||
/* Try to get maximum page mask during translation. */
|
||||
plen = (hwaddr)-1;
|
||||
|
||||
/* This can never be MMIO. */
|
||||
section = address_space_do_translate(as, addr, &xlat, &plen,
|
||||
is_write, false);
|
||||
/*
|
||||
* This can never be MMIO, and we don't really care about plen,
|
||||
* but page mask.
|
||||
*/
|
||||
section = flatview_do_translate(address_space_to_flatview(as), addr, &xlat,
|
||||
NULL, &page_mask, is_write, false, &as);
|
||||
|
||||
/* Illegal translation */
|
||||
if (section.mr == &io_mem_unassigned) {
|
||||
|
@ -537,22 +575,11 @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
|
|||
xlat += section.offset_within_address_space -
|
||||
section.offset_within_region;
|
||||
|
||||
if (plen == (hwaddr)-1) {
|
||||
/*
|
||||
* We use default page size here. Logically it only happens
|
||||
* for identity mappings.
|
||||
*/
|
||||
plen = TARGET_PAGE_SIZE;
|
||||
}
|
||||
|
||||
/* Convert to address mask */
|
||||
plen -= 1;
|
||||
|
||||
return (IOMMUTLBEntry) {
|
||||
.target_as = section.address_space,
|
||||
.iova = addr & ~plen,
|
||||
.translated_addr = xlat & ~plen,
|
||||
.addr_mask = plen,
|
||||
.target_as = as,
|
||||
.iova = addr & ~page_mask,
|
||||
.translated_addr = xlat & ~page_mask,
|
||||
.addr_mask = page_mask,
|
||||
/* IOTLBs are for DMAs, and DMA only allows on RAMs. */
|
||||
.perm = IOMMU_RW,
|
||||
};
|
||||
|
@ -562,15 +589,16 @@ iotlb_fail:
|
|||
}
|
||||
|
||||
/* Called from RCU critical section */
|
||||
MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
|
||||
hwaddr *xlat, hwaddr *plen,
|
||||
bool is_write)
|
||||
MemoryRegion *flatview_translate(FlatView *fv, hwaddr addr, hwaddr *xlat,
|
||||
hwaddr *plen, bool is_write)
|
||||
{
|
||||
MemoryRegion *mr;
|
||||
MemoryRegionSection section;
|
||||
AddressSpace *as = NULL;
|
||||
|
||||
/* This can be MMIO, so setup MMIO bit. */
|
||||
section = address_space_do_translate(as, addr, xlat, plen, is_write, true);
|
||||
section = flatview_do_translate(fv, addr, xlat, plen, NULL,
|
||||
is_write, true, &as);
|
||||
mr = section.mr;
|
||||
|
||||
if (xen_enabled() && memory_access_is_direct(mr, is_write)) {
|
||||
|
@ -1220,7 +1248,7 @@ hwaddr memory_region_section_get_iotlb(CPUState *cpu,
|
|||
} else {
|
||||
AddressSpaceDispatch *d;
|
||||
|
||||
d = atomic_rcu_read(§ion->address_space->dispatch);
|
||||
d = flatview_to_dispatch(section->fv);
|
||||
iotlb = section - d->map.sections;
|
||||
iotlb += xlat;
|
||||
}
|
||||
|
@ -1246,7 +1274,7 @@ hwaddr memory_region_section_get_iotlb(CPUState *cpu,
|
|||
|
||||
static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
|
||||
uint16_t section);
|
||||
static subpage_t *subpage_init(AddressSpace *as, hwaddr base);
|
||||
static subpage_t *subpage_init(FlatView *fv, hwaddr base);
|
||||
|
||||
static void *(*phys_mem_alloc)(size_t size, uint64_t *align) =
|
||||
qemu_anon_ram_alloc;
|
||||
|
@ -1303,8 +1331,9 @@ static void phys_sections_free(PhysPageMap *map)
|
|||
g_free(map->nodes);
|
||||
}
|
||||
|
||||
static void register_subpage(AddressSpaceDispatch *d, MemoryRegionSection *section)
|
||||
static void register_subpage(FlatView *fv, MemoryRegionSection *section)
|
||||
{
|
||||
AddressSpaceDispatch *d = flatview_to_dispatch(fv);
|
||||
subpage_t *subpage;
|
||||
hwaddr base = section->offset_within_address_space
|
||||
& TARGET_PAGE_MASK;
|
||||
|
@ -1318,8 +1347,8 @@ static void register_subpage(AddressSpaceDispatch *d, MemoryRegionSection *secti
|
|||
assert(existing->mr->subpage || existing->mr == &io_mem_unassigned);
|
||||
|
||||
if (!(existing->mr->subpage)) {
|
||||
subpage = subpage_init(d->as, base);
|
||||
subsection.address_space = d->as;
|
||||
subpage = subpage_init(fv, base);
|
||||
subsection.fv = fv;
|
||||
subsection.mr = &subpage->iomem;
|
||||
phys_page_set(d, base >> TARGET_PAGE_BITS, 1,
|
||||
phys_section_add(&d->map, &subsection));
|
||||
|
@ -1333,9 +1362,10 @@ static void register_subpage(AddressSpaceDispatch *d, MemoryRegionSection *secti
|
|||
}
|
||||
|
||||
|
||||
static void register_multipage(AddressSpaceDispatch *d,
|
||||
static void register_multipage(FlatView *fv,
|
||||
MemoryRegionSection *section)
|
||||
{
|
||||
AddressSpaceDispatch *d = flatview_to_dispatch(fv);
|
||||
hwaddr start_addr = section->offset_within_address_space;
|
||||
uint16_t section_index = phys_section_add(&d->map, section);
|
||||
uint64_t num_pages = int128_get64(int128_rshift(section->size,
|
||||
|
@ -1345,10 +1375,8 @@ static void register_multipage(AddressSpaceDispatch *d,
|
|||
phys_page_set(d, start_addr >> TARGET_PAGE_BITS, num_pages, section_index);
|
||||
}
|
||||
|
||||
static void mem_add(MemoryListener *listener, MemoryRegionSection *section)
|
||||
void flatview_add_to_dispatch(FlatView *fv, MemoryRegionSection *section)
|
||||
{
|
||||
AddressSpace *as = container_of(listener, AddressSpace, dispatch_listener);
|
||||
AddressSpaceDispatch *d = as->next_dispatch;
|
||||
MemoryRegionSection now = *section, remain = *section;
|
||||
Int128 page_size = int128_make64(TARGET_PAGE_SIZE);
|
||||
|
||||
|
@ -1357,7 +1385,7 @@ static void mem_add(MemoryListener *listener, MemoryRegionSection *section)
|
|||
- now.offset_within_address_space;
|
||||
|
||||
now.size = int128_min(int128_make64(left), now.size);
|
||||
register_subpage(d, &now);
|
||||
register_subpage(fv, &now);
|
||||
} else {
|
||||
now.size = int128_zero();
|
||||
}
|
||||
|
@ -1367,13 +1395,13 @@ static void mem_add(MemoryListener *listener, MemoryRegionSection *section)
|
|||
remain.offset_within_region += int128_get64(now.size);
|
||||
now = remain;
|
||||
if (int128_lt(remain.size, page_size)) {
|
||||
register_subpage(d, &now);
|
||||
register_subpage(fv, &now);
|
||||
} else if (remain.offset_within_address_space & ~TARGET_PAGE_MASK) {
|
||||
now.size = page_size;
|
||||
register_subpage(d, &now);
|
||||
register_subpage(fv, &now);
|
||||
} else {
|
||||
now.size = int128_and(now.size, int128_neg(page_size));
|
||||
register_multipage(d, &now);
|
||||
register_multipage(fv, &now);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2501,6 +2529,11 @@ static const MemoryRegionOps watch_mem_ops = {
|
|||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
};
|
||||
|
||||
static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs,
|
||||
const uint8_t *buf, int len);
|
||||
static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
|
||||
bool is_write);
|
||||
|
||||
static MemTxResult subpage_read(void *opaque, hwaddr addr, uint64_t *data,
|
||||
unsigned len, MemTxAttrs attrs)
|
||||
{
|
||||
|
@ -2512,8 +2545,7 @@ static MemTxResult subpage_read(void *opaque, hwaddr addr, uint64_t *data,
|
|||
printf("%s: subpage %p len %u addr " TARGET_FMT_plx "\n", __func__,
|
||||
subpage, len, addr);
|
||||
#endif
|
||||
res = address_space_read(subpage->as, addr + subpage->base,
|
||||
attrs, buf, len);
|
||||
res = flatview_read(subpage->fv, addr + subpage->base, attrs, buf, len);
|
||||
if (res) {
|
||||
return res;
|
||||
}
|
||||
|
@ -2562,8 +2594,7 @@ static MemTxResult subpage_write(void *opaque, hwaddr addr,
|
|||
default:
|
||||
abort();
|
||||
}
|
||||
return address_space_write(subpage->as, addr + subpage->base,
|
||||
attrs, buf, len);
|
||||
return flatview_write(subpage->fv, addr + subpage->base, attrs, buf, len);
|
||||
}
|
||||
|
||||
static bool subpage_accepts(void *opaque, hwaddr addr,
|
||||
|
@ -2575,8 +2606,8 @@ static bool subpage_accepts(void *opaque, hwaddr addr,
|
|||
__func__, subpage, is_write ? 'w' : 'r', len, addr);
|
||||
#endif
|
||||
|
||||
return address_space_access_valid(subpage->as, addr + subpage->base,
|
||||
len, is_write);
|
||||
return flatview_access_valid(subpage->fv, addr + subpage->base,
|
||||
len, is_write);
|
||||
}
|
||||
|
||||
static const MemoryRegionOps subpage_ops = {
|
||||
|
@ -2610,12 +2641,12 @@ static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static subpage_t *subpage_init(AddressSpace *as, hwaddr base)
|
||||
static subpage_t *subpage_init(FlatView *fv, hwaddr base)
|
||||
{
|
||||
subpage_t *mmio;
|
||||
|
||||
mmio = g_malloc0(sizeof(subpage_t) + TARGET_PAGE_SIZE * sizeof(uint16_t));
|
||||
mmio->as = as;
|
||||
mmio->fv = fv;
|
||||
mmio->base = base;
|
||||
memory_region_init_io(&mmio->iomem, NULL, &subpage_ops, mmio,
|
||||
NULL, TARGET_PAGE_SIZE);
|
||||
|
@ -2629,12 +2660,11 @@ static subpage_t *subpage_init(AddressSpace *as, hwaddr base)
|
|||
return mmio;
|
||||
}
|
||||
|
||||
static uint16_t dummy_section(PhysPageMap *map, AddressSpace *as,
|
||||
MemoryRegion *mr)
|
||||
static uint16_t dummy_section(PhysPageMap *map, FlatView *fv, MemoryRegion *mr)
|
||||
{
|
||||
assert(as);
|
||||
assert(fv);
|
||||
MemoryRegionSection section = {
|
||||
.address_space = as,
|
||||
.fv = fv,
|
||||
.mr = mr,
|
||||
.offset_within_address_space = 0,
|
||||
.offset_within_region = 0,
|
||||
|
@ -2671,46 +2701,31 @@ static void io_mem_init(void)
|
|||
NULL, UINT64_MAX);
|
||||
}
|
||||
|
||||
static void mem_begin(MemoryListener *listener)
|
||||
AddressSpaceDispatch *address_space_dispatch_new(FlatView *fv)
|
||||
{
|
||||
AddressSpace *as = container_of(listener, AddressSpace, dispatch_listener);
|
||||
AddressSpaceDispatch *d = g_new0(AddressSpaceDispatch, 1);
|
||||
uint16_t n;
|
||||
|
||||
n = dummy_section(&d->map, as, &io_mem_unassigned);
|
||||
n = dummy_section(&d->map, fv, &io_mem_unassigned);
|
||||
assert(n == PHYS_SECTION_UNASSIGNED);
|
||||
n = dummy_section(&d->map, as, &io_mem_notdirty);
|
||||
n = dummy_section(&d->map, fv, &io_mem_notdirty);
|
||||
assert(n == PHYS_SECTION_NOTDIRTY);
|
||||
n = dummy_section(&d->map, as, &io_mem_rom);
|
||||
n = dummy_section(&d->map, fv, &io_mem_rom);
|
||||
assert(n == PHYS_SECTION_ROM);
|
||||
n = dummy_section(&d->map, as, &io_mem_watch);
|
||||
n = dummy_section(&d->map, fv, &io_mem_watch);
|
||||
assert(n == PHYS_SECTION_WATCH);
|
||||
|
||||
d->phys_map = (PhysPageEntry) { .ptr = PHYS_MAP_NODE_NIL, .skip = 1 };
|
||||
d->as = as;
|
||||
as->next_dispatch = d;
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
static void address_space_dispatch_free(AddressSpaceDispatch *d)
|
||||
void address_space_dispatch_free(AddressSpaceDispatch *d)
|
||||
{
|
||||
phys_sections_free(&d->map);
|
||||
g_free(d);
|
||||
}
|
||||
|
||||
static void mem_commit(MemoryListener *listener)
|
||||
{
|
||||
AddressSpace *as = container_of(listener, AddressSpace, dispatch_listener);
|
||||
AddressSpaceDispatch *cur = as->dispatch;
|
||||
AddressSpaceDispatch *next = as->next_dispatch;
|
||||
|
||||
phys_page_compact_all(next, next->map.nodes_nb);
|
||||
|
||||
atomic_rcu_set(&as->dispatch, next);
|
||||
if (cur) {
|
||||
call_rcu(cur, address_space_dispatch_free, rcu);
|
||||
}
|
||||
}
|
||||
|
||||
static void tcg_commit(MemoryListener *listener)
|
||||
{
|
||||
CPUAddressSpace *cpuas;
|
||||
|
@ -2724,39 +2739,11 @@ static void tcg_commit(MemoryListener *listener)
|
|||
* We reload the dispatch pointer now because cpu_reloading_memory_map()
|
||||
* may have split the RCU critical section.
|
||||
*/
|
||||
d = atomic_rcu_read(&cpuas->as->dispatch);
|
||||
d = address_space_to_dispatch(cpuas->as);
|
||||
atomic_rcu_set(&cpuas->memory_dispatch, d);
|
||||
tlb_flush(cpuas->cpu);
|
||||
}
|
||||
|
||||
void address_space_init_dispatch(AddressSpace *as)
|
||||
{
|
||||
as->dispatch = NULL;
|
||||
as->dispatch_listener = (MemoryListener) {
|
||||
.begin = mem_begin,
|
||||
.commit = mem_commit,
|
||||
.region_add = mem_add,
|
||||
.region_nop = mem_add,
|
||||
.priority = 0,
|
||||
};
|
||||
memory_listener_register(&as->dispatch_listener, as);
|
||||
}
|
||||
|
||||
void address_space_unregister(AddressSpace *as)
|
||||
{
|
||||
memory_listener_unregister(&as->dispatch_listener);
|
||||
}
|
||||
|
||||
void address_space_destroy_dispatch(AddressSpace *as)
|
||||
{
|
||||
AddressSpaceDispatch *d = as->dispatch;
|
||||
|
||||
atomic_rcu_set(&as->dispatch, NULL);
|
||||
if (d) {
|
||||
call_rcu(d, address_space_dispatch_free, rcu);
|
||||
}
|
||||
}
|
||||
|
||||
static void memory_map_init(void)
|
||||
{
|
||||
system_memory = g_malloc(sizeof(*system_memory));
|
||||
|
@ -2900,11 +2887,11 @@ static bool prepare_mmio_access(MemoryRegion *mr)
|
|||
}
|
||||
|
||||
/* Called within RCU critical section. */
|
||||
static MemTxResult address_space_write_continue(AddressSpace *as, hwaddr addr,
|
||||
MemTxAttrs attrs,
|
||||
const uint8_t *buf,
|
||||
int len, hwaddr addr1,
|
||||
hwaddr l, MemoryRegion *mr)
|
||||
static MemTxResult flatview_write_continue(FlatView *fv, hwaddr addr,
|
||||
MemTxAttrs attrs,
|
||||
const uint8_t *buf,
|
||||
int len, hwaddr addr1,
|
||||
hwaddr l, MemoryRegion *mr)
|
||||
{
|
||||
uint8_t *ptr;
|
||||
uint64_t val;
|
||||
|
@ -2966,14 +2953,14 @@ static MemTxResult address_space_write_continue(AddressSpace *as, hwaddr addr,
|
|||
}
|
||||
|
||||
l = len;
|
||||
mr = address_space_translate(as, addr, &addr1, &l, true);
|
||||
mr = flatview_translate(fv, addr, &addr1, &l, true);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
MemTxResult address_space_write(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
|
||||
const uint8_t *buf, int len)
|
||||
static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs,
|
||||
const uint8_t *buf, int len)
|
||||
{
|
||||
hwaddr l;
|
||||
hwaddr addr1;
|
||||
|
@ -2983,20 +2970,27 @@ MemTxResult address_space_write(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
|
|||
if (len > 0) {
|
||||
rcu_read_lock();
|
||||
l = len;
|
||||
mr = address_space_translate(as, addr, &addr1, &l, true);
|
||||
result = address_space_write_continue(as, addr, attrs, buf, len,
|
||||
addr1, l, mr);
|
||||
mr = flatview_translate(fv, addr, &addr1, &l, true);
|
||||
result = flatview_write_continue(fv, addr, attrs, buf, len,
|
||||
addr1, l, mr);
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
MemTxResult address_space_write(AddressSpace *as, hwaddr addr,
|
||||
MemTxAttrs attrs,
|
||||
const uint8_t *buf, int len)
|
||||
{
|
||||
return flatview_write(address_space_to_flatview(as), addr, attrs, buf, len);
|
||||
}
|
||||
|
||||
/* Called within RCU critical section. */
|
||||
MemTxResult address_space_read_continue(AddressSpace *as, hwaddr addr,
|
||||
MemTxAttrs attrs, uint8_t *buf,
|
||||
int len, hwaddr addr1, hwaddr l,
|
||||
MemoryRegion *mr)
|
||||
MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr,
|
||||
MemTxAttrs attrs, uint8_t *buf,
|
||||
int len, hwaddr addr1, hwaddr l,
|
||||
MemoryRegion *mr)
|
||||
{
|
||||
uint8_t *ptr;
|
||||
uint64_t val;
|
||||
|
@ -3056,14 +3050,14 @@ MemTxResult address_space_read_continue(AddressSpace *as, hwaddr addr,
|
|||
}
|
||||
|
||||
l = len;
|
||||
mr = address_space_translate(as, addr, &addr1, &l, false);
|
||||
mr = flatview_translate(fv, addr, &addr1, &l, false);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
MemTxResult address_space_read_full(AddressSpace *as, hwaddr addr,
|
||||
MemTxAttrs attrs, uint8_t *buf, int len)
|
||||
MemTxResult flatview_read_full(FlatView *fv, hwaddr addr,
|
||||
MemTxAttrs attrs, uint8_t *buf, int len)
|
||||
{
|
||||
hwaddr l;
|
||||
hwaddr addr1;
|
||||
|
@ -3073,25 +3067,33 @@ MemTxResult address_space_read_full(AddressSpace *as, hwaddr addr,
|
|||
if (len > 0) {
|
||||
rcu_read_lock();
|
||||
l = len;
|
||||
mr = address_space_translate(as, addr, &addr1, &l, false);
|
||||
result = address_space_read_continue(as, addr, attrs, buf, len,
|
||||
addr1, l, mr);
|
||||
mr = flatview_translate(fv, addr, &addr1, &l, false);
|
||||
result = flatview_read_continue(fv, addr, attrs, buf, len,
|
||||
addr1, l, mr);
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
MemTxResult address_space_rw(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
|
||||
uint8_t *buf, int len, bool is_write)
|
||||
static MemTxResult flatview_rw(FlatView *fv, hwaddr addr, MemTxAttrs attrs,
|
||||
uint8_t *buf, int len, bool is_write)
|
||||
{
|
||||
if (is_write) {
|
||||
return address_space_write(as, addr, attrs, (uint8_t *)buf, len);
|
||||
return flatview_write(fv, addr, attrs, (uint8_t *)buf, len);
|
||||
} else {
|
||||
return address_space_read(as, addr, attrs, (uint8_t *)buf, len);
|
||||
return flatview_read(fv, addr, attrs, (uint8_t *)buf, len);
|
||||
}
|
||||
}
|
||||
|
||||
MemTxResult address_space_rw(AddressSpace *as, hwaddr addr,
|
||||
MemTxAttrs attrs, uint8_t *buf,
|
||||
int len, bool is_write)
|
||||
{
|
||||
return flatview_rw(address_space_to_flatview(as),
|
||||
addr, attrs, buf, len, is_write);
|
||||
}
|
||||
|
||||
void cpu_physical_memory_rw(hwaddr addr, uint8_t *buf,
|
||||
int len, int is_write)
|
||||
{
|
||||
|
@ -3249,7 +3251,8 @@ static void cpu_notify_map_clients(void)
|
|||
qemu_mutex_unlock(&map_client_list_lock);
|
||||
}
|
||||
|
||||
bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_write)
|
||||
static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
|
||||
bool is_write)
|
||||
{
|
||||
MemoryRegion *mr;
|
||||
hwaddr l, xlat;
|
||||
|
@ -3257,7 +3260,7 @@ bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_
|
|||
rcu_read_lock();
|
||||
while (len > 0) {
|
||||
l = len;
|
||||
mr = address_space_translate(as, addr, &xlat, &l, is_write);
|
||||
mr = flatview_translate(fv, addr, &xlat, &l, is_write);
|
||||
if (!memory_access_is_direct(mr, is_write)) {
|
||||
l = memory_access_size(mr, l, addr);
|
||||
if (!memory_region_access_valid(mr, xlat, l, is_write)) {
|
||||
|
@ -3273,8 +3276,16 @@ bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_
|
|||
return true;
|
||||
}
|
||||
|
||||
bool address_space_access_valid(AddressSpace *as, hwaddr addr,
|
||||
int len, bool is_write)
|
||||
{
|
||||
return flatview_access_valid(address_space_to_flatview(as),
|
||||
addr, len, is_write);
|
||||
}
|
||||
|
||||
static hwaddr
|
||||
address_space_extend_translation(AddressSpace *as, hwaddr addr, hwaddr target_len,
|
||||
flatview_extend_translation(FlatView *fv, hwaddr addr,
|
||||
hwaddr target_len,
|
||||
MemoryRegion *mr, hwaddr base, hwaddr len,
|
||||
bool is_write)
|
||||
{
|
||||
|
@ -3291,7 +3302,8 @@ address_space_extend_translation(AddressSpace *as, hwaddr addr, hwaddr target_le
|
|||
}
|
||||
|
||||
len = target_len;
|
||||
this_mr = address_space_translate(as, addr, &xlat, &len, is_write);
|
||||
this_mr = flatview_translate(fv, addr, &xlat,
|
||||
&len, is_write);
|
||||
if (this_mr != mr || xlat != base + done) {
|
||||
return done;
|
||||
}
|
||||
|
@ -3314,6 +3326,7 @@ void *address_space_map(AddressSpace *as,
|
|||
hwaddr l, xlat;
|
||||
MemoryRegion *mr;
|
||||
void *ptr;
|
||||
FlatView *fv = address_space_to_flatview(as);
|
||||
|
||||
if (len == 0) {
|
||||
return NULL;
|
||||
|
@ -3321,7 +3334,7 @@ void *address_space_map(AddressSpace *as,
|
|||
|
||||
l = len;
|
||||
rcu_read_lock();
|
||||
mr = address_space_translate(as, addr, &xlat, &l, is_write);
|
||||
mr = flatview_translate(fv, addr, &xlat, &l, is_write);
|
||||
|
||||
if (!memory_access_is_direct(mr, is_write)) {
|
||||
if (atomic_xchg(&bounce.in_use, true)) {
|
||||
|
@ -3337,7 +3350,7 @@ void *address_space_map(AddressSpace *as,
|
|||
memory_region_ref(mr);
|
||||
bounce.mr = mr;
|
||||
if (!is_write) {
|
||||
address_space_read(as, addr, MEMTXATTRS_UNSPECIFIED,
|
||||
flatview_read(fv, addr, MEMTXATTRS_UNSPECIFIED,
|
||||
bounce.buffer, l);
|
||||
}
|
||||
|
||||
|
@ -3348,7 +3361,8 @@ void *address_space_map(AddressSpace *as,
|
|||
|
||||
|
||||
memory_region_ref(mr);
|
||||
*plen = address_space_extend_translation(as, addr, len, mr, xlat, l, is_write);
|
||||
*plen = flatview_extend_translation(fv, addr, len, mr, xlat,
|
||||
l, is_write);
|
||||
ptr = qemu_ram_ptr_length(mr->ram_block, xlat, plen, true);
|
||||
rcu_read_unlock();
|
||||
|
||||
|
|
64
hw/9pfs/9p.c
64
hw/9pfs/9p.c
|
@ -803,12 +803,12 @@ static uint32_t stat_to_v9mode(const struct stat *stbuf)
|
|||
return mode;
|
||||
}
|
||||
|
||||
static int coroutine_fn stat_to_v9stat(V9fsPDU *pdu, V9fsPath *name,
|
||||
static int coroutine_fn stat_to_v9stat(V9fsPDU *pdu, V9fsPath *path,
|
||||
const char *basename,
|
||||
const struct stat *stbuf,
|
||||
V9fsStat *v9stat)
|
||||
{
|
||||
int err;
|
||||
const char *str;
|
||||
|
||||
memset(v9stat, 0, sizeof(*v9stat));
|
||||
|
||||
|
@ -829,7 +829,7 @@ static int coroutine_fn stat_to_v9stat(V9fsPDU *pdu, V9fsPath *name,
|
|||
v9fs_string_free(&v9stat->extension);
|
||||
|
||||
if (v9stat->mode & P9_STAT_MODE_SYMLINK) {
|
||||
err = v9fs_co_readlink(pdu, name, &v9stat->extension);
|
||||
err = v9fs_co_readlink(pdu, path, &v9stat->extension);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
@ -842,14 +842,7 @@ static int coroutine_fn stat_to_v9stat(V9fsPDU *pdu, V9fsPath *name,
|
|||
"HARDLINKCOUNT", (unsigned long)stbuf->st_nlink);
|
||||
}
|
||||
|
||||
str = strrchr(name->data, '/');
|
||||
if (str) {
|
||||
str += 1;
|
||||
} else {
|
||||
str = name->data;
|
||||
}
|
||||
|
||||
v9fs_string_sprintf(&v9stat->name, "%s", str);
|
||||
v9fs_string_sprintf(&v9stat->name, "%s", basename);
|
||||
|
||||
v9stat->size = 61 +
|
||||
v9fs_string_size(&v9stat->name) +
|
||||
|
@ -1058,6 +1051,7 @@ static void coroutine_fn v9fs_stat(void *opaque)
|
|||
struct stat stbuf;
|
||||
V9fsFidState *fidp;
|
||||
V9fsPDU *pdu = opaque;
|
||||
char *basename;
|
||||
|
||||
err = pdu_unmarshal(pdu, offset, "d", &fid);
|
||||
if (err < 0) {
|
||||
|
@ -1074,7 +1068,9 @@ static void coroutine_fn v9fs_stat(void *opaque)
|
|||
if (err < 0) {
|
||||
goto out;
|
||||
}
|
||||
err = stat_to_v9stat(pdu, &fidp->path, &stbuf, &v9stat);
|
||||
basename = g_path_get_basename(fidp->path.data);
|
||||
err = stat_to_v9stat(pdu, &fidp->path, basename, &stbuf, &v9stat);
|
||||
g_free(basename);
|
||||
if (err < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
@ -1750,22 +1746,31 @@ static int coroutine_fn v9fs_do_readdir_with_stat(V9fsPDU *pdu,
|
|||
if (err < 0) {
|
||||
break;
|
||||
}
|
||||
err = stat_to_v9stat(pdu, &path, &stbuf, &v9stat);
|
||||
err = stat_to_v9stat(pdu, &path, dent->d_name, &stbuf, &v9stat);
|
||||
if (err < 0) {
|
||||
break;
|
||||
}
|
||||
/* 11 = 7 + 4 (7 = start offset, 4 = space for storing count) */
|
||||
len = pdu_marshal(pdu, 11 + count, "S", &v9stat);
|
||||
if ((count + v9stat.size + 2) > max_count) {
|
||||
v9fs_readdir_unlock(&fidp->fs.dir);
|
||||
|
||||
v9fs_readdir_unlock(&fidp->fs.dir);
|
||||
|
||||
if ((len != (v9stat.size + 2)) || ((count + len) > max_count)) {
|
||||
/* Ran out of buffer. Set dir back to old position and return */
|
||||
v9fs_co_seekdir(pdu, fidp, saved_dir_pos);
|
||||
v9fs_stat_free(&v9stat);
|
||||
v9fs_path_free(&path);
|
||||
return count;
|
||||
}
|
||||
|
||||
/* 11 = 7 + 4 (7 = start offset, 4 = space for storing count) */
|
||||
len = pdu_marshal(pdu, 11 + count, "S", &v9stat);
|
||||
|
||||
v9fs_readdir_unlock(&fidp->fs.dir);
|
||||
|
||||
if (len < 0) {
|
||||
v9fs_co_seekdir(pdu, fidp, saved_dir_pos);
|
||||
v9fs_stat_free(&v9stat);
|
||||
v9fs_path_free(&path);
|
||||
return len;
|
||||
}
|
||||
count += len;
|
||||
v9fs_stat_free(&v9stat);
|
||||
v9fs_path_free(&path);
|
||||
|
@ -2559,13 +2564,11 @@ static int coroutine_fn v9fs_complete_rename(V9fsPDU *pdu, V9fsFidState *fidp,
|
|||
int32_t newdirfid,
|
||||
V9fsString *name)
|
||||
{
|
||||
char *end;
|
||||
int err = 0;
|
||||
V9fsPath new_path;
|
||||
V9fsFidState *tfidp;
|
||||
V9fsState *s = pdu->s;
|
||||
V9fsFidState *dirfidp = NULL;
|
||||
char *old_name, *new_name;
|
||||
|
||||
v9fs_path_init(&new_path);
|
||||
if (newdirfid != -1) {
|
||||
|
@ -2583,18 +2586,15 @@ static int coroutine_fn v9fs_complete_rename(V9fsPDU *pdu, V9fsFidState *fidp,
|
|||
goto out;
|
||||
}
|
||||
} else {
|
||||
old_name = fidp->path.data;
|
||||
end = strrchr(old_name, '/');
|
||||
if (end) {
|
||||
end++;
|
||||
} else {
|
||||
end = old_name;
|
||||
}
|
||||
new_name = g_malloc0(end - old_name + name->size + 1);
|
||||
strncat(new_name, old_name, end - old_name);
|
||||
strncat(new_name + (end - old_name), name->data, name->size);
|
||||
err = v9fs_co_name_to_path(pdu, NULL, new_name, &new_path);
|
||||
g_free(new_name);
|
||||
char *dir_name = g_path_get_dirname(fidp->path.data);
|
||||
V9fsPath dir_path;
|
||||
|
||||
v9fs_path_init(&dir_path);
|
||||
v9fs_path_sprintf(&dir_path, "%s", dir_name);
|
||||
g_free(dir_name);
|
||||
|
||||
err = v9fs_co_name_to_path(pdu, &dir_path, name->data, &new_path);
|
||||
v9fs_path_free(&dir_path);
|
||||
if (err < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
|
|
@ -75,6 +75,43 @@ static int acpi_pcihp_get_bsel(PCIBus *bus)
|
|||
}
|
||||
}
|
||||
|
||||
/* Assign BSEL property to all buses. In the future, this can be changed
|
||||
* to only assign to buses that support hotplug.
|
||||
*/
|
||||
static void *acpi_set_bsel(PCIBus *bus, void *opaque)
|
||||
{
|
||||
unsigned *bsel_alloc = opaque;
|
||||
unsigned *bus_bsel;
|
||||
|
||||
if (qbus_is_hotpluggable(BUS(bus))) {
|
||||
bus_bsel = g_malloc(sizeof *bus_bsel);
|
||||
|
||||
*bus_bsel = (*bsel_alloc)++;
|
||||
object_property_add_uint32_ptr(OBJECT(bus), ACPI_PCIHP_PROP_BSEL,
|
||||
bus_bsel, &error_abort);
|
||||
}
|
||||
|
||||
return bsel_alloc;
|
||||
}
|
||||
|
||||
static void acpi_set_pci_info(void)
|
||||
{
|
||||
static bool bsel_is_set;
|
||||
PCIBus *bus;
|
||||
unsigned bsel_alloc = ACPI_PCIHP_BSEL_DEFAULT;
|
||||
|
||||
if (bsel_is_set) {
|
||||
return;
|
||||
}
|
||||
bsel_is_set = true;
|
||||
|
||||
bus = find_i440fx(); /* TODO: Q35 support */
|
||||
if (bus) {
|
||||
/* Scan all PCI buses. Set property to enable acpi based hotplug. */
|
||||
pci_for_each_bus_depth_first(bus, acpi_set_bsel, NULL, &bsel_alloc);
|
||||
}
|
||||
}
|
||||
|
||||
static void acpi_pcihp_test_hotplug_bus(PCIBus *bus, void *opaque)
|
||||
{
|
||||
AcpiPciHpFind *find = opaque;
|
||||
|
@ -177,6 +214,7 @@ static void acpi_pcihp_update(AcpiPciHpState *s)
|
|||
|
||||
void acpi_pcihp_reset(AcpiPciHpState *s)
|
||||
{
|
||||
acpi_set_pci_info();
|
||||
acpi_pcihp_update(s);
|
||||
}
|
||||
|
||||
|
@ -273,7 +311,7 @@ static void pci_write(void *opaque, hwaddr addr, uint64_t data,
|
|||
addr, data);
|
||||
break;
|
||||
case PCI_SEL_BASE:
|
||||
s->hotplug_select = data;
|
||||
s->hotplug_select = s->legacy_piix ? ACPI_PCIHP_BSEL_DEFAULT : data;
|
||||
ACPI_PCIHP_DPRINTF("pcisel write %" HWADDR_PRIx " <== %" PRIu64 "\n",
|
||||
addr, data);
|
||||
default:
|
||||
|
|
|
@ -385,10 +385,7 @@ static void piix4_device_plug_cb(HotplugHandler *hotplug_dev,
|
|||
dev, errp);
|
||||
}
|
||||
} else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
|
||||
if (!xen_enabled()) {
|
||||
acpi_pcihp_device_plug_cb(hotplug_dev, &s->acpi_pci_hotplug, dev,
|
||||
errp);
|
||||
}
|
||||
acpi_pcihp_device_plug_cb(hotplug_dev, &s->acpi_pci_hotplug, dev, errp);
|
||||
} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
|
||||
if (s->cpu_hotplug_legacy) {
|
||||
legacy_acpi_cpu_plug_cb(hotplug_dev, &s->gpe_cpu, dev, errp);
|
||||
|
@ -411,10 +408,8 @@ static void piix4_device_unplug_request_cb(HotplugHandler *hotplug_dev,
|
|||
acpi_memory_unplug_request_cb(hotplug_dev, &s->acpi_memory_hotplug,
|
||||
dev, errp);
|
||||
} else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
|
||||
if (!xen_enabled()) {
|
||||
acpi_pcihp_device_unplug_cb(hotplug_dev, &s->acpi_pci_hotplug, dev,
|
||||
errp);
|
||||
}
|
||||
acpi_pcihp_device_unplug_cb(hotplug_dev, &s->acpi_pci_hotplug, dev,
|
||||
errp);
|
||||
} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU) &&
|
||||
!s->cpu_hotplug_legacy) {
|
||||
acpi_cpu_unplug_request_cb(hotplug_dev, &s->cpuhp_state, dev, errp);
|
||||
|
|
|
@ -118,6 +118,8 @@ static void aw_a10_class_init(ObjectClass *oc, void *data)
|
|||
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
|
||||
dc->realize = aw_a10_realize;
|
||||
/* Reason: Uses serial_hds in realize and nd_table in instance_init */
|
||||
dc->user_creatable = false;
|
||||
}
|
||||
|
||||
static const TypeInfo aw_a10_type_info = {
|
||||
|
|
|
@ -41,7 +41,7 @@ static MemTxResult bitband_read(void *opaque, hwaddr offset,
|
|||
|
||||
/* Find address in underlying memory and round down to multiple of size */
|
||||
addr = bitband_addr(s, offset) & (-size);
|
||||
res = address_space_read(s->source_as, addr, attrs, buf, size);
|
||||
res = address_space_read(&s->source_as, addr, attrs, buf, size);
|
||||
if (res) {
|
||||
return res;
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ static MemTxResult bitband_write(void *opaque, hwaddr offset, uint64_t value,
|
|||
|
||||
/* Find address in underlying memory and round down to multiple of size */
|
||||
addr = bitband_addr(s, offset) & (-size);
|
||||
res = address_space_read(s->source_as, addr, attrs, buf, size);
|
||||
res = address_space_read(&s->source_as, addr, attrs, buf, size);
|
||||
if (res) {
|
||||
return res;
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ static MemTxResult bitband_write(void *opaque, hwaddr offset, uint64_t value,
|
|||
} else {
|
||||
buf[bitpos >> 3] &= ~bit;
|
||||
}
|
||||
return address_space_write(s->source_as, addr, attrs, buf, size);
|
||||
return address_space_write(&s->source_as, addr, attrs, buf, size);
|
||||
}
|
||||
|
||||
static const MemoryRegionOps bitband_ops = {
|
||||
|
@ -117,8 +117,7 @@ static void bitband_realize(DeviceState *dev, Error **errp)
|
|||
return;
|
||||
}
|
||||
|
||||
s->source_as = address_space_init_shareable(s->source_memory,
|
||||
"bitband-source");
|
||||
address_space_init(&s->source_as, s->source_memory, "bitband-source");
|
||||
}
|
||||
|
||||
/* Board init. */
|
||||
|
|
|
@ -338,6 +338,8 @@ static void aspeed_soc_class_init(ObjectClass *oc, void *data)
|
|||
|
||||
sc->info = (AspeedSoCInfo *) data;
|
||||
dc->realize = aspeed_soc_realize;
|
||||
/* Reason: Uses serial_hds and nd_table in realize() directly */
|
||||
dc->user_creatable = false;
|
||||
}
|
||||
|
||||
static const TypeInfo aspeed_soc_type_info = {
|
||||
|
|
|
@ -101,6 +101,8 @@ static void digic_class_init(ObjectClass *oc, void *data)
|
|||
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
|
||||
dc->realize = digic_realize;
|
||||
/* Reason: Uses serial_hds in the realize function --> not usable twice */
|
||||
dc->user_creatable = false;
|
||||
}
|
||||
|
||||
static const TypeInfo digic_type_info = {
|
||||
|
|
|
@ -287,8 +287,8 @@ static void mps2_common_init(MachineState *machine)
|
|||
cmsdk_apb_uart_create(uartbase[i],
|
||||
qdev_get_gpio_in(txrx_orgate_dev, 0),
|
||||
qdev_get_gpio_in(txrx_orgate_dev, 1),
|
||||
qdev_get_gpio_in(orgate_dev, 0),
|
||||
qdev_get_gpio_in(orgate_dev, 1),
|
||||
qdev_get_gpio_in(orgate_dev, i * 2),
|
||||
qdev_get_gpio_in(orgate_dev, i * 2 + 1),
|
||||
NULL,
|
||||
uartchr, SYSCLK_FRQ);
|
||||
}
|
||||
|
|
|
@ -95,20 +95,46 @@ static void vga_draw_glyph9(uint8_t *d, int linesize,
|
|||
} while (--h);
|
||||
}
|
||||
|
||||
static inline uint8_t vga_read_byte(VGACommonState *vga, uint32_t addr)
|
||||
{
|
||||
return vga->vram_ptr[addr & vga->vbe_size_mask];
|
||||
}
|
||||
|
||||
static inline uint16_t vga_read_word_le(VGACommonState *vga, uint32_t addr)
|
||||
{
|
||||
uint32_t offset = addr & vga->vbe_size_mask & ~1;
|
||||
uint16_t *ptr = (uint16_t *)(vga->vram_ptr + offset);
|
||||
return lduw_le_p(ptr);
|
||||
}
|
||||
|
||||
static inline uint16_t vga_read_word_be(VGACommonState *vga, uint32_t addr)
|
||||
{
|
||||
uint32_t offset = addr & vga->vbe_size_mask & ~1;
|
||||
uint16_t *ptr = (uint16_t *)(vga->vram_ptr + offset);
|
||||
return lduw_be_p(ptr);
|
||||
}
|
||||
|
||||
static inline uint32_t vga_read_dword_le(VGACommonState *vga, uint32_t addr)
|
||||
{
|
||||
uint32_t offset = addr & vga->vbe_size_mask & ~3;
|
||||
uint32_t *ptr = (uint32_t *)(vga->vram_ptr + offset);
|
||||
return ldl_le_p(ptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* 4 color mode
|
||||
*/
|
||||
static void vga_draw_line2(VGACommonState *s1, uint8_t *d,
|
||||
const uint8_t *s, int width)
|
||||
static void vga_draw_line2(VGACommonState *vga, uint8_t *d,
|
||||
uint32_t addr, int width)
|
||||
{
|
||||
uint32_t plane_mask, *palette, data, v;
|
||||
int x;
|
||||
|
||||
palette = s1->last_palette;
|
||||
plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
|
||||
palette = vga->last_palette;
|
||||
plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
|
||||
width >>= 3;
|
||||
for(x = 0; x < width; x++) {
|
||||
data = ((uint32_t *)s)[0];
|
||||
data = vga_read_dword_le(vga, addr);
|
||||
data &= plane_mask;
|
||||
v = expand2[GET_PLANE(data, 0)];
|
||||
v |= expand2[GET_PLANE(data, 2)] << 2;
|
||||
|
@ -124,7 +150,7 @@ static void vga_draw_line2(VGACommonState *s1, uint8_t *d,
|
|||
((uint32_t *)d)[6] = palette[(v >> 4) & 0xf];
|
||||
((uint32_t *)d)[7] = palette[(v >> 0) & 0xf];
|
||||
d += 32;
|
||||
s += 4;
|
||||
addr += 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,17 +160,17 @@ static void vga_draw_line2(VGACommonState *s1, uint8_t *d,
|
|||
/*
|
||||
* 4 color mode, dup2 horizontal
|
||||
*/
|
||||
static void vga_draw_line2d2(VGACommonState *s1, uint8_t *d,
|
||||
const uint8_t *s, int width)
|
||||
static void vga_draw_line2d2(VGACommonState *vga, uint8_t *d,
|
||||
uint32_t addr, int width)
|
||||
{
|
||||
uint32_t plane_mask, *palette, data, v;
|
||||
int x;
|
||||
|
||||
palette = s1->last_palette;
|
||||
plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
|
||||
palette = vga->last_palette;
|
||||
plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
|
||||
width >>= 3;
|
||||
for(x = 0; x < width; x++) {
|
||||
data = ((uint32_t *)s)[0];
|
||||
data = vga_read_dword_le(vga, addr);
|
||||
data &= plane_mask;
|
||||
v = expand2[GET_PLANE(data, 0)];
|
||||
v |= expand2[GET_PLANE(data, 2)] << 2;
|
||||
|
@ -160,24 +186,24 @@ static void vga_draw_line2d2(VGACommonState *s1, uint8_t *d,
|
|||
PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
|
||||
PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
|
||||
d += 64;
|
||||
s += 4;
|
||||
addr += 4;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 16 color mode
|
||||
*/
|
||||
static void vga_draw_line4(VGACommonState *s1, uint8_t *d,
|
||||
const uint8_t *s, int width)
|
||||
static void vga_draw_line4(VGACommonState *vga, uint8_t *d,
|
||||
uint32_t addr, int width)
|
||||
{
|
||||
uint32_t plane_mask, data, v, *palette;
|
||||
int x;
|
||||
|
||||
palette = s1->last_palette;
|
||||
plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
|
||||
palette = vga->last_palette;
|
||||
plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
|
||||
width >>= 3;
|
||||
for(x = 0; x < width; x++) {
|
||||
data = ((uint32_t *)s)[0];
|
||||
data = vga_read_dword_le(vga, addr);
|
||||
data &= plane_mask;
|
||||
v = expand4[GET_PLANE(data, 0)];
|
||||
v |= expand4[GET_PLANE(data, 1)] << 1;
|
||||
|
@ -192,24 +218,24 @@ static void vga_draw_line4(VGACommonState *s1, uint8_t *d,
|
|||
((uint32_t *)d)[6] = palette[(v >> 4) & 0xf];
|
||||
((uint32_t *)d)[7] = palette[(v >> 0) & 0xf];
|
||||
d += 32;
|
||||
s += 4;
|
||||
addr += 4;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 16 color mode, dup2 horizontal
|
||||
*/
|
||||
static void vga_draw_line4d2(VGACommonState *s1, uint8_t *d,
|
||||
const uint8_t *s, int width)
|
||||
static void vga_draw_line4d2(VGACommonState *vga, uint8_t *d,
|
||||
uint32_t addr, int width)
|
||||
{
|
||||
uint32_t plane_mask, data, v, *palette;
|
||||
int x;
|
||||
|
||||
palette = s1->last_palette;
|
||||
plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
|
||||
palette = vga->last_palette;
|
||||
plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
|
||||
width >>= 3;
|
||||
for(x = 0; x < width; x++) {
|
||||
data = ((uint32_t *)s)[0];
|
||||
data = vga_read_dword_le(vga, addr);
|
||||
data &= plane_mask;
|
||||
v = expand4[GET_PLANE(data, 0)];
|
||||
v |= expand4[GET_PLANE(data, 1)] << 1;
|
||||
|
@ -224,7 +250,7 @@ static void vga_draw_line4d2(VGACommonState *s1, uint8_t *d,
|
|||
PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
|
||||
PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
|
||||
d += 64;
|
||||
s += 4;
|
||||
addr += 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -233,21 +259,21 @@ static void vga_draw_line4d2(VGACommonState *s1, uint8_t *d,
|
|||
*
|
||||
* XXX: add plane_mask support (never used in standard VGA modes)
|
||||
*/
|
||||
static void vga_draw_line8d2(VGACommonState *s1, uint8_t *d,
|
||||
const uint8_t *s, int width)
|
||||
static void vga_draw_line8d2(VGACommonState *vga, uint8_t *d,
|
||||
uint32_t addr, int width)
|
||||
{
|
||||
uint32_t *palette;
|
||||
int x;
|
||||
|
||||
palette = s1->last_palette;
|
||||
palette = vga->last_palette;
|
||||
width >>= 3;
|
||||
for(x = 0; x < width; x++) {
|
||||
PUT_PIXEL2(d, 0, palette[s[0]]);
|
||||
PUT_PIXEL2(d, 1, palette[s[1]]);
|
||||
PUT_PIXEL2(d, 2, palette[s[2]]);
|
||||
PUT_PIXEL2(d, 3, palette[s[3]]);
|
||||
PUT_PIXEL2(d, 0, palette[vga_read_byte(vga, addr + 0)]);
|
||||
PUT_PIXEL2(d, 1, palette[vga_read_byte(vga, addr + 1)]);
|
||||
PUT_PIXEL2(d, 2, palette[vga_read_byte(vga, addr + 2)]);
|
||||
PUT_PIXEL2(d, 3, palette[vga_read_byte(vga, addr + 3)]);
|
||||
d += 32;
|
||||
s += 4;
|
||||
addr += 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -256,63 +282,63 @@ static void vga_draw_line8d2(VGACommonState *s1, uint8_t *d,
|
|||
*
|
||||
* XXX: add plane_mask support (never used in standard VGA modes)
|
||||
*/
|
||||
static void vga_draw_line8(VGACommonState *s1, uint8_t *d,
|
||||
const uint8_t *s, int width)
|
||||
static void vga_draw_line8(VGACommonState *vga, uint8_t *d,
|
||||
uint32_t addr, int width)
|
||||
{
|
||||
uint32_t *palette;
|
||||
int x;
|
||||
|
||||
palette = s1->last_palette;
|
||||
palette = vga->last_palette;
|
||||
width >>= 3;
|
||||
for(x = 0; x < width; x++) {
|
||||
((uint32_t *)d)[0] = palette[s[0]];
|
||||
((uint32_t *)d)[1] = palette[s[1]];
|
||||
((uint32_t *)d)[2] = palette[s[2]];
|
||||
((uint32_t *)d)[3] = palette[s[3]];
|
||||
((uint32_t *)d)[4] = palette[s[4]];
|
||||
((uint32_t *)d)[5] = palette[s[5]];
|
||||
((uint32_t *)d)[6] = palette[s[6]];
|
||||
((uint32_t *)d)[7] = palette[s[7]];
|
||||
((uint32_t *)d)[0] = palette[vga_read_byte(vga, addr + 0)];
|
||||
((uint32_t *)d)[1] = palette[vga_read_byte(vga, addr + 1)];
|
||||
((uint32_t *)d)[2] = palette[vga_read_byte(vga, addr + 2)];
|
||||
((uint32_t *)d)[3] = palette[vga_read_byte(vga, addr + 3)];
|
||||
((uint32_t *)d)[4] = palette[vga_read_byte(vga, addr + 4)];
|
||||
((uint32_t *)d)[5] = palette[vga_read_byte(vga, addr + 5)];
|
||||
((uint32_t *)d)[6] = palette[vga_read_byte(vga, addr + 6)];
|
||||
((uint32_t *)d)[7] = palette[vga_read_byte(vga, addr + 7)];
|
||||
d += 32;
|
||||
s += 8;
|
||||
addr += 8;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 15 bit color
|
||||
*/
|
||||
static void vga_draw_line15_le(VGACommonState *s1, uint8_t *d,
|
||||
const uint8_t *s, int width)
|
||||
static void vga_draw_line15_le(VGACommonState *vga, uint8_t *d,
|
||||
uint32_t addr, int width)
|
||||
{
|
||||
int w;
|
||||
uint32_t v, r, g, b;
|
||||
|
||||
w = width;
|
||||
do {
|
||||
v = lduw_le_p((void *)s);
|
||||
v = vga_read_word_le(vga, addr);
|
||||
r = (v >> 7) & 0xf8;
|
||||
g = (v >> 2) & 0xf8;
|
||||
b = (v << 3) & 0xf8;
|
||||
((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
|
||||
s += 2;
|
||||
addr += 2;
|
||||
d += 4;
|
||||
} while (--w != 0);
|
||||
}
|
||||
|
||||
static void vga_draw_line15_be(VGACommonState *s1, uint8_t *d,
|
||||
const uint8_t *s, int width)
|
||||
static void vga_draw_line15_be(VGACommonState *vga, uint8_t *d,
|
||||
uint32_t addr, int width)
|
||||
{
|
||||
int w;
|
||||
uint32_t v, r, g, b;
|
||||
|
||||
w = width;
|
||||
do {
|
||||
v = lduw_be_p((void *)s);
|
||||
v = vga_read_word_be(vga, addr);
|
||||
r = (v >> 7) & 0xf8;
|
||||
g = (v >> 2) & 0xf8;
|
||||
b = (v << 3) & 0xf8;
|
||||
((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
|
||||
s += 2;
|
||||
addr += 2;
|
||||
d += 4;
|
||||
} while (--w != 0);
|
||||
}
|
||||
|
@ -320,38 +346,38 @@ static void vga_draw_line15_be(VGACommonState *s1, uint8_t *d,
|
|||
/*
|
||||
* 16 bit color
|
||||
*/
|
||||
static void vga_draw_line16_le(VGACommonState *s1, uint8_t *d,
|
||||
const uint8_t *s, int width)
|
||||
static void vga_draw_line16_le(VGACommonState *vga, uint8_t *d,
|
||||
uint32_t addr, int width)
|
||||
{
|
||||
int w;
|
||||
uint32_t v, r, g, b;
|
||||
|
||||
w = width;
|
||||
do {
|
||||
v = lduw_le_p((void *)s);
|
||||
v = vga_read_word_le(vga, addr);
|
||||
r = (v >> 8) & 0xf8;
|
||||
g = (v >> 3) & 0xfc;
|
||||
b = (v << 3) & 0xf8;
|
||||
((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
|
||||
s += 2;
|
||||
addr += 2;
|
||||
d += 4;
|
||||
} while (--w != 0);
|
||||
}
|
||||
|
||||
static void vga_draw_line16_be(VGACommonState *s1, uint8_t *d,
|
||||
const uint8_t *s, int width)
|
||||
static void vga_draw_line16_be(VGACommonState *vga, uint8_t *d,
|
||||
uint32_t addr, int width)
|
||||
{
|
||||
int w;
|
||||
uint32_t v, r, g, b;
|
||||
|
||||
w = width;
|
||||
do {
|
||||
v = lduw_be_p((void *)s);
|
||||
v = vga_read_word_be(vga, addr);
|
||||
r = (v >> 8) & 0xf8;
|
||||
g = (v >> 3) & 0xfc;
|
||||
b = (v << 3) & 0xf8;
|
||||
((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
|
||||
s += 2;
|
||||
addr += 2;
|
||||
d += 4;
|
||||
} while (--w != 0);
|
||||
}
|
||||
|
@ -359,36 +385,36 @@ static void vga_draw_line16_be(VGACommonState *s1, uint8_t *d,
|
|||
/*
|
||||
* 24 bit color
|
||||
*/
|
||||
static void vga_draw_line24_le(VGACommonState *s1, uint8_t *d,
|
||||
const uint8_t *s, int width)
|
||||
static void vga_draw_line24_le(VGACommonState *vga, uint8_t *d,
|
||||
uint32_t addr, int width)
|
||||
{
|
||||
int w;
|
||||
uint32_t r, g, b;
|
||||
|
||||
w = width;
|
||||
do {
|
||||
b = s[0];
|
||||
g = s[1];
|
||||
r = s[2];
|
||||
b = vga_read_byte(vga, addr + 0);
|
||||
g = vga_read_byte(vga, addr + 1);
|
||||
r = vga_read_byte(vga, addr + 2);
|
||||
((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
|
||||
s += 3;
|
||||
addr += 3;
|
||||
d += 4;
|
||||
} while (--w != 0);
|
||||
}
|
||||
|
||||
static void vga_draw_line24_be(VGACommonState *s1, uint8_t *d,
|
||||
const uint8_t *s, int width)
|
||||
static void vga_draw_line24_be(VGACommonState *vga, uint8_t *d,
|
||||
uint32_t addr, int width)
|
||||
{
|
||||
int w;
|
||||
uint32_t r, g, b;
|
||||
|
||||
w = width;
|
||||
do {
|
||||
r = s[0];
|
||||
g = s[1];
|
||||
b = s[2];
|
||||
r = vga_read_byte(vga, addr + 0);
|
||||
g = vga_read_byte(vga, addr + 1);
|
||||
b = vga_read_byte(vga, addr + 2);
|
||||
((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
|
||||
s += 3;
|
||||
addr += 3;
|
||||
d += 4;
|
||||
} while (--w != 0);
|
||||
}
|
||||
|
@ -396,44 +422,36 @@ static void vga_draw_line24_be(VGACommonState *s1, uint8_t *d,
|
|||
/*
|
||||
* 32 bit color
|
||||
*/
|
||||
static void vga_draw_line32_le(VGACommonState *s1, uint8_t *d,
|
||||
const uint8_t *s, int width)
|
||||
static void vga_draw_line32_le(VGACommonState *vga, uint8_t *d,
|
||||
uint32_t addr, int width)
|
||||
{
|
||||
#ifndef HOST_WORDS_BIGENDIAN
|
||||
memcpy(d, s, width * 4);
|
||||
#else
|
||||
int w;
|
||||
uint32_t r, g, b;
|
||||
|
||||
w = width;
|
||||
do {
|
||||
b = s[0];
|
||||
g = s[1];
|
||||
r = s[2];
|
||||
b = vga_read_byte(vga, addr + 0);
|
||||
g = vga_read_byte(vga, addr + 1);
|
||||
r = vga_read_byte(vga, addr + 2);
|
||||
((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
|
||||
s += 4;
|
||||
addr += 4;
|
||||
d += 4;
|
||||
} while (--w != 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void vga_draw_line32_be(VGACommonState *s1, uint8_t *d,
|
||||
const uint8_t *s, int width)
|
||||
static void vga_draw_line32_be(VGACommonState *vga, uint8_t *d,
|
||||
uint32_t addr, int width)
|
||||
{
|
||||
#ifdef HOST_WORDS_BIGENDIAN
|
||||
memcpy(d, s, width * 4);
|
||||
#else
|
||||
int w;
|
||||
uint32_t r, g, b;
|
||||
|
||||
w = width;
|
||||
do {
|
||||
r = s[1];
|
||||
g = s[2];
|
||||
b = s[3];
|
||||
r = vga_read_byte(vga, addr + 1);
|
||||
g = vga_read_byte(vga, addr + 2);
|
||||
b = vga_read_byte(vga, addr + 3);
|
||||
((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
|
||||
s += 4;
|
||||
addr += 4;
|
||||
d += 4;
|
||||
} while (--w != 0);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1005,7 +1005,7 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
|
|||
}
|
||||
|
||||
typedef void vga_draw_line_func(VGACommonState *s1, uint8_t *d,
|
||||
const uint8_t *s, int width);
|
||||
uint32_t srcaddr, int width);
|
||||
|
||||
#include "vga-helpers.h"
|
||||
|
||||
|
@ -1464,14 +1464,14 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
|
|||
{
|
||||
DisplaySurface *surface = qemu_console_surface(s->con);
|
||||
int y1, y, update, linesize, y_start, double_scan, mask, depth;
|
||||
int width, height, shift_control, line_offset, bwidth, bits;
|
||||
ram_addr_t page0, page1;
|
||||
int width, height, shift_control, bwidth, bits;
|
||||
ram_addr_t page0, page1, region_start, region_end;
|
||||
DirtyBitmapSnapshot *snap = NULL;
|
||||
int disp_width, multi_scan, multi_run;
|
||||
uint8_t *d;
|
||||
uint32_t v, addr1, addr;
|
||||
vga_draw_line_func *vga_draw_line = NULL;
|
||||
bool share_surface;
|
||||
bool share_surface, force_shadow = false;
|
||||
pixman_format_code_t format;
|
||||
#ifdef HOST_WORDS_BIGENDIAN
|
||||
bool byteswap = !s->big_endian_fb;
|
||||
|
@ -1484,6 +1484,15 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
|
|||
s->get_resolution(s, &width, &height);
|
||||
disp_width = width;
|
||||
|
||||
region_start = (s->start_addr * 4);
|
||||
region_end = region_start + s->line_offset * height;
|
||||
if (region_end > s->vbe_size) {
|
||||
/* wraps around (can happen with cirrus vbe modes) */
|
||||
region_start = 0;
|
||||
region_end = s->vbe_size;
|
||||
force_shadow = true;
|
||||
}
|
||||
|
||||
shift_control = (s->gr[VGA_GFX_MODE] >> 5) & 3;
|
||||
double_scan = (s->cr[VGA_CRTC_MAX_SCAN] >> 7);
|
||||
if (shift_control != 1) {
|
||||
|
@ -1523,7 +1532,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
|
|||
format = qemu_default_pixman_format(depth, !byteswap);
|
||||
if (format) {
|
||||
share_surface = dpy_gfx_check_format(s->con, format)
|
||||
&& !s->force_shadow;
|
||||
&& !s->force_shadow && !force_shadow;
|
||||
} else {
|
||||
share_surface = false;
|
||||
}
|
||||
|
@ -1614,7 +1623,6 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
|
|||
s->cursor_invalidate(s);
|
||||
}
|
||||
|
||||
line_offset = s->line_offset;
|
||||
#if 0
|
||||
printf("w=%d h=%d v=%d line_offset=%d cr[0x09]=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=0x%02x\n",
|
||||
width, height, v, line_offset, s->cr[9], s->cr[VGA_CRTC_MODE],
|
||||
|
@ -1629,8 +1637,12 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
|
|||
|
||||
if (!full_update) {
|
||||
vga_sync_dirty_bitmap(s);
|
||||
snap = memory_region_snapshot_and_clear_dirty(&s->vram, addr1,
|
||||
line_offset * height,
|
||||
if (s->line_compare < height) {
|
||||
/* split screen mode */
|
||||
region_start = 0;
|
||||
}
|
||||
snap = memory_region_snapshot_and_clear_dirty(&s->vram, region_start,
|
||||
region_end - region_start,
|
||||
DIRTY_MEMORY_VGA);
|
||||
}
|
||||
|
||||
|
@ -1646,10 +1658,17 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
|
|||
addr = (addr & ~0x8000) | ((y1 & 2) << 14);
|
||||
}
|
||||
update = full_update;
|
||||
page0 = addr;
|
||||
page1 = addr + bwidth - 1;
|
||||
page0 = addr & s->vbe_size_mask;
|
||||
page1 = (addr + bwidth - 1) & s->vbe_size_mask;
|
||||
if (full_update) {
|
||||
update = 1;
|
||||
} else if (page1 < page0) {
|
||||
/* scanline wraps from end of video memory to the start */
|
||||
assert(force_shadow);
|
||||
update = memory_region_snapshot_get_dirty(&s->vram, snap,
|
||||
page0, 0);
|
||||
update |= memory_region_snapshot_get_dirty(&s->vram, snap,
|
||||
page1, 0);
|
||||
} else {
|
||||
update = memory_region_snapshot_get_dirty(&s->vram, snap,
|
||||
page0, page1 - page0);
|
||||
|
@ -1660,7 +1679,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
|
|||
if (y_start < 0)
|
||||
y_start = y;
|
||||
if (!(is_buffer_shared(surface))) {
|
||||
vga_draw_line(s, d, s->vram_ptr + addr, width);
|
||||
vga_draw_line(s, d, addr, width);
|
||||
if (s->cursor_draw_line)
|
||||
s->cursor_draw_line(s, d, y);
|
||||
}
|
||||
|
@ -1675,7 +1694,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
|
|||
if (!multi_run) {
|
||||
mask = (s->cr[VGA_CRTC_MODE] & 3) ^ 3;
|
||||
if ((y1 & mask) == mask)
|
||||
addr1 += line_offset;
|
||||
addr1 += s->line_offset;
|
||||
y1++;
|
||||
multi_run = multi_scan;
|
||||
} else {
|
||||
|
@ -2164,6 +2183,7 @@ void vga_common_init(VGACommonState *s, Object *obj, bool global_vmstate)
|
|||
if (!s->vbe_size) {
|
||||
s->vbe_size = s->vram_size;
|
||||
}
|
||||
s->vbe_size_mask = s->vbe_size - 1;
|
||||
|
||||
s->is_vbe_vmstate = 1;
|
||||
memory_region_init_ram_nomigrate(&s->vram, obj, "vga.vram", s->vram_size,
|
||||
|
|
|
@ -94,6 +94,7 @@ typedef struct VGACommonState {
|
|||
uint32_t vram_size;
|
||||
uint32_t vram_size_mb; /* property */
|
||||
uint32_t vbe_size;
|
||||
uint32_t vbe_size_mask;
|
||||
uint32_t latch;
|
||||
bool has_chain4_alias;
|
||||
MemoryRegion chain4_alias;
|
||||
|
|
|
@ -493,36 +493,6 @@ build_madt(GArray *table_data, BIOSLinker *linker, PCMachineState *pcms)
|
|||
table_data->len - madt_start, 1, NULL, NULL);
|
||||
}
|
||||
|
||||
/* Assign BSEL property to all buses. In the future, this can be changed
|
||||
* to only assign to buses that support hotplug.
|
||||
*/
|
||||
static void *acpi_set_bsel(PCIBus *bus, void *opaque)
|
||||
{
|
||||
unsigned *bsel_alloc = opaque;
|
||||
unsigned *bus_bsel;
|
||||
|
||||
if (qbus_is_hotpluggable(BUS(bus))) {
|
||||
bus_bsel = g_malloc(sizeof *bus_bsel);
|
||||
|
||||
*bus_bsel = (*bsel_alloc)++;
|
||||
object_property_add_uint32_ptr(OBJECT(bus), ACPI_PCIHP_PROP_BSEL,
|
||||
bus_bsel, &error_abort);
|
||||
}
|
||||
|
||||
return bsel_alloc;
|
||||
}
|
||||
|
||||
static void acpi_set_pci_info(void)
|
||||
{
|
||||
PCIBus *bus = find_i440fx(); /* TODO: Q35 support */
|
||||
unsigned bsel_alloc = ACPI_PCIHP_BSEL_DEFAULT;
|
||||
|
||||
if (bus) {
|
||||
/* Scan all PCI buses. Set property to enable acpi based hotplug. */
|
||||
pci_for_each_bus_depth_first(bus, acpi_set_bsel, NULL, &bsel_alloc);
|
||||
}
|
||||
}
|
||||
|
||||
static void build_append_pcihp_notify_entry(Aml *method, int slot)
|
||||
{
|
||||
Aml *if_ctx;
|
||||
|
@ -2888,8 +2858,6 @@ void acpi_setup(void)
|
|||
|
||||
build_state = g_malloc0(sizeof *build_state);
|
||||
|
||||
acpi_set_pci_info();
|
||||
|
||||
acpi_build_tables_init(&tables);
|
||||
acpi_build(&tables, MACHINE(pcms));
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ static uint64_t kvmclock_current_nsec(KVMClockState *s)
|
|||
{
|
||||
CPUState *cpu = first_cpu;
|
||||
CPUX86State *env = cpu->env_ptr;
|
||||
hwaddr kvmclock_struct_pa = env->system_time_msr & ~1ULL;
|
||||
hwaddr kvmclock_struct_pa;
|
||||
uint64_t migration_tsc = env->tsc;
|
||||
struct pvclock_vcpu_time_info time;
|
||||
uint64_t delta;
|
||||
|
@ -77,6 +77,7 @@ static uint64_t kvmclock_current_nsec(KVMClockState *s)
|
|||
return 0;
|
||||
}
|
||||
|
||||
kvmclock_struct_pa = env->system_time_msr & ~1ULL;
|
||||
cpu_physical_memory_read(kvmclock_struct_pa, &time, sizeof(time));
|
||||
|
||||
assert(time.tsc_timestamp <= migration_tsc);
|
||||
|
|
|
@ -221,15 +221,34 @@ int load_multiboot(FWCfgState *fw_cfg,
|
|||
uint32_t mh_header_addr = ldl_p(header+i+12);
|
||||
uint32_t mh_load_end_addr = ldl_p(header+i+20);
|
||||
uint32_t mh_bss_end_addr = ldl_p(header+i+24);
|
||||
|
||||
mh_load_addr = ldl_p(header+i+16);
|
||||
if (mh_header_addr < mh_load_addr) {
|
||||
fprintf(stderr, "invalid mh_load_addr address\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uint32_t mb_kernel_text_offset = i - (mh_header_addr - mh_load_addr);
|
||||
uint32_t mb_load_size = 0;
|
||||
mh_entry_addr = ldl_p(header+i+28);
|
||||
|
||||
if (mh_load_end_addr) {
|
||||
if (mh_bss_end_addr < mh_load_addr) {
|
||||
fprintf(stderr, "invalid mh_bss_end_addr address\n");
|
||||
exit(1);
|
||||
}
|
||||
mb_kernel_size = mh_bss_end_addr - mh_load_addr;
|
||||
|
||||
if (mh_load_end_addr < mh_load_addr) {
|
||||
fprintf(stderr, "invalid mh_load_end_addr address\n");
|
||||
exit(1);
|
||||
}
|
||||
mb_load_size = mh_load_end_addr - mh_load_addr;
|
||||
} else {
|
||||
if (kernel_file_size < mb_kernel_text_offset) {
|
||||
fprintf(stderr, "invalid kernel_file_size\n");
|
||||
exit(1);
|
||||
}
|
||||
mb_kernel_size = kernel_file_size - mb_kernel_text_offset;
|
||||
mb_load_size = mb_kernel_size;
|
||||
}
|
||||
|
|
|
@ -1495,6 +1495,7 @@ void ahci_uninit(AHCIState *s)
|
|||
|
||||
ide_exit(s);
|
||||
}
|
||||
object_unparent(OBJECT(&ad->port));
|
||||
}
|
||||
|
||||
g_free(s->dev);
|
||||
|
|
|
@ -575,12 +575,15 @@ PCMCIACardState *dscm1xxxx_init(DriveInfo *dinfo)
|
|||
static void dscm1xxxx_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
PCMCIACardClass *pcc = PCMCIA_CARD_CLASS(oc);
|
||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
|
||||
pcc->cis = dscm1xxxx_cis;
|
||||
pcc->cis_len = sizeof(dscm1xxxx_cis);
|
||||
|
||||
pcc->attach = dscm1xxxx_attach;
|
||||
pcc->detach = dscm1xxxx_detach;
|
||||
/* Reason: Needs to be wired-up in code, see dscm1xxxx_init() */
|
||||
dc->user_creatable = false;
|
||||
}
|
||||
|
||||
static const TypeInfo dscm1xxxx_type_info = {
|
||||
|
|
|
@ -64,20 +64,16 @@ static void vm_change_state_handler(void *opaque, int running,
|
|||
{
|
||||
GICv3ITSState *s = (GICv3ITSState *)opaque;
|
||||
Error *err = NULL;
|
||||
int ret;
|
||||
|
||||
if (running) {
|
||||
return;
|
||||
}
|
||||
|
||||
ret = kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
|
||||
KVM_DEV_ARM_ITS_SAVE_TABLES, NULL, true, &err);
|
||||
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
|
||||
KVM_DEV_ARM_ITS_SAVE_TABLES, NULL, true, &err);
|
||||
if (err) {
|
||||
error_report_err(err);
|
||||
}
|
||||
if (ret < 0 && ret != -EFAULT) {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
static void kvm_arm_its_realize(DeviceState *dev, Error **errp)
|
||||
|
|
|
@ -293,7 +293,7 @@ static void kvm_arm_gicv3_put(GICv3State *s)
|
|||
kvm_gicr_access(s, GICR_PROPBASER + 4, ncpu, ®h, true);
|
||||
|
||||
reg64 = c->gicr_pendbaser;
|
||||
if (!c->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) {
|
||||
if (!(c->gicr_ctlr & GICR_CTLR_ENABLE_LPIS)) {
|
||||
/* Setting PTZ is advised if LPIs are disabled, to reduce
|
||||
* GIC initialization time.
|
||||
*/
|
||||
|
|
|
@ -124,7 +124,7 @@ static void kvm_openpic_region_add(MemoryListener *listener,
|
|||
uint64_t reg_base;
|
||||
int ret;
|
||||
|
||||
if (section->address_space != &address_space_memory) {
|
||||
if (section->fv != address_space_to_flatview(&address_space_memory)) {
|
||||
abort();
|
||||
}
|
||||
|
||||
|
|
|
@ -288,7 +288,8 @@ static void virtio_net_set_status(struct VirtIODevice *vdev, uint8_t status)
|
|||
qemu_bh_cancel(q->tx_bh);
|
||||
}
|
||||
if ((n->status & VIRTIO_NET_S_LINK_UP) == 0 &&
|
||||
(queue_status & VIRTIO_CONFIG_S_DRIVER_OK)) {
|
||||
(queue_status & VIRTIO_CONFIG_S_DRIVER_OK) &&
|
||||
vdev->vm_running) {
|
||||
/* if tx is waiting we are likely have some packets in tx queue
|
||||
* and disabled notification */
|
||||
q->tx_waiting = 0;
|
||||
|
|
102
hw/ppc/spapr.c
102
hw/ppc/spapr.c
|
@ -43,6 +43,7 @@
|
|||
#include "migration/register.h"
|
||||
#include "mmu-hash64.h"
|
||||
#include "mmu-book3s-v3.h"
|
||||
#include "cpu-models.h"
|
||||
#include "qom/cpu.h"
|
||||
|
||||
#include "hw/boards.h"
|
||||
|
@ -251,9 +252,10 @@ static int spapr_fixup_cpu_numa_dt(void *fdt, int offset, PowerPCCPU *cpu)
|
|||
}
|
||||
|
||||
/* Populate the "ibm,pa-features" property */
|
||||
static void spapr_populate_pa_features(CPUPPCState *env, void *fdt, int offset,
|
||||
bool legacy_guest)
|
||||
static void spapr_populate_pa_features(PowerPCCPU *cpu, void *fdt, int offset,
|
||||
bool legacy_guest)
|
||||
{
|
||||
CPUPPCState *env = &cpu->env;
|
||||
uint8_t pa_features_206[] = { 6, 0,
|
||||
0xf6, 0x1f, 0xc7, 0x00, 0x80, 0xc0 };
|
||||
uint8_t pa_features_207[] = { 24, 0,
|
||||
|
@ -286,23 +288,22 @@ static void spapr_populate_pa_features(CPUPPCState *env, void *fdt, int offset,
|
|||
/* 60: NM atomic, 62: RNG */
|
||||
0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 60 - 65 */
|
||||
};
|
||||
uint8_t *pa_features;
|
||||
uint8_t *pa_features = NULL;
|
||||
size_t pa_size;
|
||||
|
||||
switch (POWERPC_MMU_VER(env->mmu_model)) {
|
||||
case POWERPC_MMU_VER_2_06:
|
||||
if (ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_2_06, 0, cpu->compat_pvr)) {
|
||||
pa_features = pa_features_206;
|
||||
pa_size = sizeof(pa_features_206);
|
||||
break;
|
||||
case POWERPC_MMU_VER_2_07:
|
||||
}
|
||||
if (ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_2_07, 0, cpu->compat_pvr)) {
|
||||
pa_features = pa_features_207;
|
||||
pa_size = sizeof(pa_features_207);
|
||||
break;
|
||||
case POWERPC_MMU_VER_3_00:
|
||||
}
|
||||
if (ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_3_00, 0, cpu->compat_pvr)) {
|
||||
pa_features = pa_features_300;
|
||||
pa_size = sizeof(pa_features_300);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
if (!pa_features) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -339,7 +340,6 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPRMachineState *spapr)
|
|||
|
||||
CPU_FOREACH(cs) {
|
||||
PowerPCCPU *cpu = POWERPC_CPU(cs);
|
||||
CPUPPCState *env = &cpu->env;
|
||||
DeviceClass *dc = DEVICE_GET_CLASS(cs);
|
||||
int index = ppc_get_vcpu_dt_id(cpu);
|
||||
int compat_smt = MIN(smp_threads, ppc_compat_max_threads(cpu));
|
||||
|
@ -384,7 +384,7 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPRMachineState *spapr)
|
|||
return ret;
|
||||
}
|
||||
|
||||
spapr_populate_pa_features(env, fdt, offset,
|
||||
spapr_populate_pa_features(cpu, fdt, offset,
|
||||
spapr->cas_legacy_guest_workaround);
|
||||
}
|
||||
return ret;
|
||||
|
@ -581,7 +581,7 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
|
|||
page_sizes_prop, page_sizes_prop_size)));
|
||||
}
|
||||
|
||||
spapr_populate_pa_features(env, fdt, offset, false);
|
||||
spapr_populate_pa_features(cpu, fdt, offset, false);
|
||||
|
||||
_FDT((fdt_setprop_cell(fdt, offset, "ibm,chip-id",
|
||||
cs->cpu_index / vcpus_per_socket)));
|
||||
|
@ -790,6 +790,26 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static bool spapr_hotplugged_dev_before_cas(void)
|
||||
{
|
||||
Object *drc_container, *obj;
|
||||
ObjectProperty *prop;
|
||||
ObjectPropertyIterator iter;
|
||||
|
||||
drc_container = container_get(object_get_root(), "/dr-connector");
|
||||
object_property_iter_init(&iter, drc_container);
|
||||
while ((prop = object_property_iter_next(&iter))) {
|
||||
if (!strstart(prop->type, "link<", NULL)) {
|
||||
continue;
|
||||
}
|
||||
obj = object_property_get_link(drc_container, prop->name, NULL);
|
||||
if (spapr_drc_needed(obj)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int spapr_h_cas_compose_response(sPAPRMachineState *spapr,
|
||||
target_ulong addr, target_ulong size,
|
||||
sPAPROptionVector *ov5_updates)
|
||||
|
@ -797,9 +817,13 @@ int spapr_h_cas_compose_response(sPAPRMachineState *spapr,
|
|||
void *fdt, *fdt_skel;
|
||||
sPAPRDeviceTreeUpdateHeader hdr = { .version_id = 1 };
|
||||
|
||||
if (spapr_hotplugged_dev_before_cas()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
size -= sizeof(hdr);
|
||||
|
||||
/* Create sceleton */
|
||||
/* Create skeleton */
|
||||
fdt_skel = g_malloc0(size);
|
||||
_FDT((fdt_create(fdt_skel, size)));
|
||||
_FDT((fdt_begin_node(fdt_skel, "")));
|
||||
|
@ -920,7 +944,11 @@ static void spapr_dt_ov5_platform_support(void *fdt, int chosen)
|
|||
26, 0x40, /* Radix options: GTSE == yes. */
|
||||
};
|
||||
|
||||
if (kvm_enabled()) {
|
||||
if (!ppc_check_compat(first_ppc_cpu, CPU_POWERPC_LOGICAL_3_00, 0,
|
||||
first_ppc_cpu->compat_pvr)) {
|
||||
/* If we're in a pre POWER9 compat mode then the guest should do hash */
|
||||
val[3] = 0x00; /* Hash */
|
||||
} else if (kvm_enabled()) {
|
||||
if (kvmppc_has_cap_mmu_radix() && kvmppc_has_cap_mmu_hash_v3()) {
|
||||
val[3] = 0x80; /* OV5_MMU_BOTH */
|
||||
} else if (kvmppc_has_cap_mmu_radix()) {
|
||||
|
@ -929,13 +957,8 @@ static void spapr_dt_ov5_platform_support(void *fdt, int chosen)
|
|||
val[3] = 0x00; /* Hash */
|
||||
}
|
||||
} else {
|
||||
if (first_ppc_cpu->env.mmu_model & POWERPC_MMU_V3) {
|
||||
/* V3 MMU supports both hash and radix (with dynamic switching) */
|
||||
val[3] = 0xC0;
|
||||
} else {
|
||||
/* Otherwise we can only do hash */
|
||||
val[3] = 0x00;
|
||||
}
|
||||
/* V3 MMU supports both hash and radix in tcg (with dynamic switching) */
|
||||
val[3] = 0xC0;
|
||||
}
|
||||
_FDT(fdt_setprop(fdt, chosen, "ibm,arch-vec-5-platform-support",
|
||||
val, sizeof(val)));
|
||||
|
@ -1342,7 +1365,10 @@ void spapr_setup_hpt_and_vrma(sPAPRMachineState *spapr)
|
|||
&& !spapr_ovec_test(spapr->ov5_cas, OV5_HPT_RESIZE))) {
|
||||
hpt_shift = spapr_hpt_shift_for_ramsize(MACHINE(spapr)->maxram_size);
|
||||
} else {
|
||||
hpt_shift = spapr_hpt_shift_for_ramsize(MACHINE(spapr)->ram_size);
|
||||
uint64_t current_ram_size;
|
||||
|
||||
current_ram_size = MACHINE(spapr)->ram_size + pc_existing_dimms_capacity(&error_abort);
|
||||
hpt_shift = spapr_hpt_shift_for_ramsize(current_ram_size);
|
||||
}
|
||||
spapr_reallocate_hpt(spapr, hpt_shift, &error_fatal);
|
||||
|
||||
|
@ -1369,6 +1395,19 @@ static void find_unknown_sysbus_device(SysBusDevice *sbdev, void *opaque)
|
|||
}
|
||||
}
|
||||
|
||||
static int spapr_reset_drcs(Object *child, void *opaque)
|
||||
{
|
||||
sPAPRDRConnector *drc =
|
||||
(sPAPRDRConnector *) object_dynamic_cast(child,
|
||||
TYPE_SPAPR_DR_CONNECTOR);
|
||||
|
||||
if (drc) {
|
||||
spapr_drc_reset(drc);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ppc_spapr_reset(void)
|
||||
{
|
||||
MachineState *machine = MACHINE(qdev_get_machine());
|
||||
|
@ -1382,7 +1421,10 @@ static void ppc_spapr_reset(void)
|
|||
/* Check for unknown sysbus devices */
|
||||
foreach_dynamic_sysbus_device(find_unknown_sysbus_device, NULL);
|
||||
|
||||
if (kvm_enabled() && kvmppc_has_cap_mmu_radix()) {
|
||||
first_ppc_cpu = POWERPC_CPU(first_cpu);
|
||||
if (kvm_enabled() && kvmppc_has_cap_mmu_radix() &&
|
||||
ppc_check_compat(first_ppc_cpu, CPU_POWERPC_LOGICAL_3_00, 0,
|
||||
spapr->max_compat_pvr)) {
|
||||
/* If using KVM with radix mode available, VCPUs can be started
|
||||
* without a HPT because KVM will start them in radix mode.
|
||||
* Set the GR bit in PATB so that we know there is no HPT. */
|
||||
|
@ -1393,6 +1435,15 @@ static void ppc_spapr_reset(void)
|
|||
|
||||
qemu_devices_reset();
|
||||
|
||||
/* DRC reset may cause a device to be unplugged. This will cause troubles
|
||||
* if this device is used by another device (eg, a running vhost backend
|
||||
* will crash QEMU if the DIMM holding the vring goes away). To avoid such
|
||||
* situations, we reset DRCs after all devices have been reset.
|
||||
*/
|
||||
object_child_foreach_recursive(object_get_root(), spapr_reset_drcs, NULL);
|
||||
|
||||
spapr_clear_pending_events(spapr);
|
||||
|
||||
/*
|
||||
* We place the device tree and RTAS just below either the top of the RMA,
|
||||
* or just below 2GB, whichever is lowere, so that it can be
|
||||
|
@ -1432,7 +1483,6 @@ static void ppc_spapr_reset(void)
|
|||
g_free(fdt);
|
||||
|
||||
/* Set up the entry state */
|
||||
first_ppc_cpu = POWERPC_CPU(first_cpu);
|
||||
first_ppc_cpu->env.gpr[3] = fdt_addr;
|
||||
first_ppc_cpu->env.gpr[5] = 0;
|
||||
first_cpu->halted = 0;
|
||||
|
|
|
@ -455,12 +455,7 @@ void spapr_drc_reset(sPAPRDRConnector *drc)
|
|||
}
|
||||
}
|
||||
|
||||
static void drc_reset(void *opaque)
|
||||
{
|
||||
spapr_drc_reset(SPAPR_DR_CONNECTOR(opaque));
|
||||
}
|
||||
|
||||
static bool spapr_drc_needed(void *opaque)
|
||||
bool spapr_drc_needed(void *opaque)
|
||||
{
|
||||
sPAPRDRConnector *drc = (sPAPRDRConnector *)opaque;
|
||||
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
|
@ -518,7 +513,6 @@ static void realize(DeviceState *d, Error **errp)
|
|||
}
|
||||
vmstate_register(DEVICE(drc), spapr_drc_index(drc), &vmstate_spapr_drc,
|
||||
drc);
|
||||
qemu_register_reset(drc_reset, drc);
|
||||
trace_spapr_drc_realize_complete(spapr_drc_index(drc));
|
||||
}
|
||||
|
||||
|
@ -529,7 +523,6 @@ static void unrealize(DeviceState *d, Error **errp)
|
|||
char name[256];
|
||||
|
||||
trace_spapr_drc_unrealize(spapr_drc_index(drc));
|
||||
qemu_unregister_reset(drc_reset, drc);
|
||||
vmstate_unregister(DEVICE(drc), &vmstate_spapr_drc, drc);
|
||||
root_container = container_get(object_get_root(), DRC_CONTAINER_PATH);
|
||||
snprintf(name, sizeof(name), "%x", spapr_drc_index(drc));
|
||||
|
|
|
@ -700,6 +700,17 @@ static void event_scan(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
|||
rtas_st(rets, 0, RTAS_OUT_NO_ERRORS_FOUND);
|
||||
}
|
||||
|
||||
void spapr_clear_pending_events(sPAPRMachineState *spapr)
|
||||
{
|
||||
sPAPREventLogEntry *entry = NULL;
|
||||
|
||||
QTAILQ_FOREACH(entry, &spapr->pending_events, next) {
|
||||
QTAILQ_REMOVE(&spapr->pending_events, entry, next);
|
||||
g_free(entry->extended_log);
|
||||
g_free(entry);
|
||||
}
|
||||
}
|
||||
|
||||
void spapr_events_init(sPAPRMachineState *spapr)
|
||||
{
|
||||
QTAILQ_INIT(&spapr->pending_events);
|
||||
|
|
|
@ -442,6 +442,8 @@ static void s390_ipl_class_init(ObjectClass *klass, void *data)
|
|||
dc->reset = s390_ipl_reset;
|
||||
dc->vmsd = &vmstate_ipl;
|
||||
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
|
||||
/* Reason: Loads the ROMs and thus can only be used one time - internally */
|
||||
dc->user_creatable = false;
|
||||
}
|
||||
|
||||
static const TypeInfo s390_ipl_info = {
|
||||
|
|
|
@ -516,8 +516,10 @@ static size_t scsi_sense_len(SCSIRequest *req)
|
|||
static int32_t scsi_target_send_command(SCSIRequest *req, uint8_t *buf)
|
||||
{
|
||||
SCSITargetReq *r = DO_UPCAST(SCSITargetReq, req, req);
|
||||
int fixed_sense = (req->cmd.buf[1] & 1) == 0;
|
||||
|
||||
if (req->lun != 0) {
|
||||
if (req->lun != 0 &&
|
||||
buf[0] != INQUIRY && buf[0] != REQUEST_SENSE) {
|
||||
scsi_req_build_sense(req, SENSE_CODE(LUN_NOT_SUPPORTED));
|
||||
scsi_req_complete(req, CHECK_CONDITION);
|
||||
return 0;
|
||||
|
@ -535,9 +537,28 @@ 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(req));
|
||||
r->len = scsi_device_get_sense(r->req.dev, r->buf,
|
||||
MIN(req->cmd.xfer, r->buf_len),
|
||||
(req->cmd.buf[1] & 1) == 0);
|
||||
if (req->lun != 0) {
|
||||
const struct SCSISense sense = SENSE_CODE(LUN_NOT_SUPPORTED);
|
||||
|
||||
if (fixed_sense) {
|
||||
r->buf[0] = 0x70;
|
||||
r->buf[2] = sense.key;
|
||||
r->buf[10] = 10;
|
||||
r->buf[12] = sense.asc;
|
||||
r->buf[13] = sense.ascq;
|
||||
r->len = MIN(req->cmd.xfer, SCSI_SENSE_LEN);
|
||||
} else {
|
||||
r->buf[0] = 0x72;
|
||||
r->buf[1] = sense.key;
|
||||
r->buf[2] = sense.asc;
|
||||
r->buf[3] = sense.ascq;
|
||||
r->len = 8;
|
||||
}
|
||||
} else {
|
||||
r->len = scsi_device_get_sense(r->req.dev, r->buf,
|
||||
MIN(req->cmd.xfer, r->buf_len),
|
||||
fixed_sense);
|
||||
}
|
||||
if (r->req.dev->sense_is_ua) {
|
||||
scsi_device_unit_attention_reported(req->dev);
|
||||
r->req.dev->sense_len = 0;
|
||||
|
|
12
hw/sd/sd.c
12
hw/sd/sd.c
|
@ -1797,8 +1797,13 @@ uint8_t sd_read_data(SDState *sd)
|
|||
break;
|
||||
|
||||
case 18: /* CMD18: READ_MULTIPLE_BLOCK */
|
||||
if (sd->data_offset == 0)
|
||||
if (sd->data_offset == 0) {
|
||||
if (sd->data_start + io_len > sd->size) {
|
||||
sd->card_status |= ADDRESS_ERROR;
|
||||
return 0x00;
|
||||
}
|
||||
BLK_READ_BLOCK(sd->data_start, io_len);
|
||||
}
|
||||
ret = sd->data[sd->data_offset ++];
|
||||
|
||||
if (sd->data_offset >= io_len) {
|
||||
|
@ -1812,11 +1817,6 @@ uint8_t sd_read_data(SDState *sd)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (sd->data_start + io_len > sd->size) {
|
||||
sd->card_status |= ADDRESS_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -341,9 +341,7 @@ static USBDevice *usb_try_create_simple(USBBus *bus, const char *name,
|
|||
object_property_set_bool(OBJECT(dev), true, "realized", &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
error_prepend(errp, "Failed to initialize USB device '%s': ",
|
||||
name);
|
||||
object_unparent(OBJECT(dev));
|
||||
error_prepend(errp, "Failed to initialize USB device '%s': ", name);
|
||||
return NULL;
|
||||
}
|
||||
return dev;
|
||||
|
|
|
@ -968,6 +968,7 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as,
|
|||
if (!ioctl(group->fd, VFIO_GROUP_SET_CONTAINER, &container->fd)) {
|
||||
group->container = container;
|
||||
QLIST_INSERT_HEAD(&container->group_list, group, container_next);
|
||||
vfio_kvm_device_add_group(group);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -492,21 +492,21 @@ static int vhost_verify_ring_mappings(struct vhost_dev *dev,
|
|||
j = 0;
|
||||
r = vhost_verify_ring_part_mapping(dev, vq->desc, vq->desc_phys,
|
||||
vq->desc_size, start_addr, size);
|
||||
if (!r) {
|
||||
if (r) {
|
||||
break;
|
||||
}
|
||||
|
||||
j++;
|
||||
r = vhost_verify_ring_part_mapping(dev, vq->avail, vq->avail_phys,
|
||||
vq->avail_size, start_addr, size);
|
||||
if (!r) {
|
||||
if (r) {
|
||||
break;
|
||||
}
|
||||
|
||||
j++;
|
||||
r = vhost_verify_ring_part_mapping(dev, vq->used, vq->used_phys,
|
||||
vq->used_size, start_addr, size);
|
||||
if (!r) {
|
||||
if (r) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1137,6 +1137,10 @@ static void vhost_virtqueue_stop(struct vhost_dev *dev,
|
|||
r = dev->vhost_ops->vhost_get_vring_base(dev, &state);
|
||||
if (r < 0) {
|
||||
VHOST_OPS_DEBUG("vhost VQ %d ring restore failed: %d", idx, r);
|
||||
/* Connection to the backend is broken, so let's sync internal
|
||||
* last avail idx to the device used idx.
|
||||
*/
|
||||
virtio_queue_restore_last_avail_idx(vdev, idx);
|
||||
} else {
|
||||
virtio_queue_set_last_avail_idx(vdev, idx, state.num);
|
||||
}
|
||||
|
@ -1356,6 +1360,10 @@ void vhost_dev_cleanup(struct vhost_dev *hdev)
|
|||
if (hdev->mem) {
|
||||
/* those are only safe after successful init */
|
||||
memory_listener_unregister(&hdev->memory_listener);
|
||||
for (i = 0; i < hdev->n_mem_sections; ++i) {
|
||||
MemoryRegionSection *section = &hdev->mem_sections[i];
|
||||
memory_region_unref(section->mr);
|
||||
}
|
||||
QLIST_REMOVE(hdev, entry);
|
||||
}
|
||||
if (hdev->migration_blocker) {
|
||||
|
|
|
@ -2311,6 +2311,16 @@ void virtio_queue_set_last_avail_idx(VirtIODevice *vdev, int n, uint16_t idx)
|
|||
vdev->vq[n].shadow_avail_idx = idx;
|
||||
}
|
||||
|
||||
void virtio_queue_restore_last_avail_idx(VirtIODevice *vdev, int n)
|
||||
{
|
||||
rcu_read_lock();
|
||||
if (vdev->vq[n].vring.desc) {
|
||||
vdev->vq[n].last_avail_idx = vring_used_idx(&vdev->vq[n]);
|
||||
vdev->vq[n].shadow_avail_idx = vdev->vq[n].last_avail_idx;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
void virtio_queue_update_used_idx(VirtIODevice *vdev, int n)
|
||||
{
|
||||
rcu_read_lock();
|
||||
|
|
|
@ -121,6 +121,7 @@ static void wdt_diag288_class_init(ObjectClass *klass, void *data)
|
|||
dc->realize = wdt_diag288_realize;
|
||||
dc->unrealize = wdt_diag288_unrealize;
|
||||
dc->reset = wdt_diag288_reset;
|
||||
dc->hotpluggable = false;
|
||||
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
|
||||
dc->vmsd = &vmstate_diag288;
|
||||
diag288->handle_timer = wdt_diag288_handle_timer;
|
||||
|
|
|
@ -22,14 +22,18 @@
|
|||
#ifndef CONFIG_USER_ONLY
|
||||
typedef struct AddressSpaceDispatch AddressSpaceDispatch;
|
||||
|
||||
void address_space_init_dispatch(AddressSpace *as);
|
||||
void address_space_unregister(AddressSpace *as);
|
||||
void address_space_destroy_dispatch(AddressSpace *as);
|
||||
|
||||
extern const MemoryRegionOps unassigned_mem_ops;
|
||||
|
||||
bool memory_region_access_valid(MemoryRegion *mr, hwaddr addr,
|
||||
unsigned size, bool is_write);
|
||||
|
||||
void flatview_add_to_dispatch(FlatView *fv, MemoryRegionSection *section);
|
||||
AddressSpaceDispatch *address_space_dispatch_new(FlatView *fv);
|
||||
void address_space_dispatch_compact(AddressSpaceDispatch *d);
|
||||
|
||||
AddressSpaceDispatch *address_space_to_dispatch(AddressSpace *as);
|
||||
AddressSpaceDispatch *flatview_to_dispatch(FlatView *fv);
|
||||
void address_space_dispatch_free(AddressSpaceDispatch *d);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -318,21 +318,18 @@ struct AddressSpace {
|
|||
struct rcu_head rcu;
|
||||
char *name;
|
||||
MemoryRegion *root;
|
||||
int ref_count;
|
||||
bool malloced;
|
||||
|
||||
/* Accessed via RCU. */
|
||||
struct FlatView *current_map;
|
||||
|
||||
int ioeventfd_nb;
|
||||
struct MemoryRegionIoeventfd *ioeventfds;
|
||||
struct AddressSpaceDispatch *dispatch;
|
||||
struct AddressSpaceDispatch *next_dispatch;
|
||||
MemoryListener dispatch_listener;
|
||||
QTAILQ_HEAD(memory_listeners_as, MemoryListener) listeners;
|
||||
QTAILQ_ENTRY(AddressSpace) address_spaces_link;
|
||||
};
|
||||
|
||||
FlatView *address_space_to_flatview(AddressSpace *as);
|
||||
|
||||
/**
|
||||
* MemoryRegionSection: describes a fragment of a #MemoryRegion
|
||||
*
|
||||
|
@ -346,7 +343,7 @@ struct AddressSpace {
|
|||
*/
|
||||
struct MemoryRegionSection {
|
||||
MemoryRegion *mr;
|
||||
AddressSpace *address_space;
|
||||
FlatView *fv;
|
||||
hwaddr offset_within_region;
|
||||
Int128 size;
|
||||
hwaddr offset_within_address_space;
|
||||
|
@ -1594,23 +1591,6 @@ MemTxResult memory_region_dispatch_write(MemoryRegion *mr,
|
|||
*/
|
||||
void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name);
|
||||
|
||||
/**
|
||||
* address_space_init_shareable: return an address space for a memory region,
|
||||
* creating it if it does not already exist
|
||||
*
|
||||
* @root: a #MemoryRegion that routes addresses for the address space
|
||||
* @name: an address space name. The name is only used for debugging
|
||||
* output.
|
||||
*
|
||||
* This function will return a pointer to an existing AddressSpace
|
||||
* which was initialized with the specified MemoryRegion, or it will
|
||||
* create and initialize one if it does not already exist. The ASes
|
||||
* are reference-counted, so the memory will be freed automatically
|
||||
* when the AddressSpace is destroyed via address_space_destroy.
|
||||
*/
|
||||
AddressSpace *address_space_init_shareable(MemoryRegion *root,
|
||||
const char *name);
|
||||
|
||||
/**
|
||||
* address_space_destroy: destroy an address space
|
||||
*
|
||||
|
@ -1855,9 +1835,17 @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
|
|||
* @len: pointer to length
|
||||
* @is_write: indicates the transfer direction
|
||||
*/
|
||||
MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
|
||||
hwaddr *xlat, hwaddr *len,
|
||||
bool is_write);
|
||||
MemoryRegion *flatview_translate(FlatView *fv,
|
||||
hwaddr addr, hwaddr *xlat,
|
||||
hwaddr *len, bool is_write);
|
||||
|
||||
static inline MemoryRegion *address_space_translate(AddressSpace *as,
|
||||
hwaddr addr, hwaddr *xlat,
|
||||
hwaddr *len, bool is_write)
|
||||
{
|
||||
return flatview_translate(address_space_to_flatview(as),
|
||||
addr, xlat, len, is_write);
|
||||
}
|
||||
|
||||
/* address_space_access_valid: check for validity of accessing an address
|
||||
* space range
|
||||
|
@ -1908,12 +1896,13 @@ void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len,
|
|||
|
||||
|
||||
/* Internal functions, part of the implementation of address_space_read. */
|
||||
MemTxResult address_space_read_continue(AddressSpace *as, hwaddr addr,
|
||||
MemTxAttrs attrs, uint8_t *buf,
|
||||
int len, hwaddr addr1, hwaddr l,
|
||||
MemoryRegion *mr);
|
||||
MemTxResult address_space_read_full(AddressSpace *as, hwaddr addr,
|
||||
MemTxAttrs attrs, uint8_t *buf, int len);
|
||||
MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr,
|
||||
MemTxAttrs attrs, uint8_t *buf,
|
||||
int len, hwaddr addr1, hwaddr l,
|
||||
MemoryRegion *mr);
|
||||
|
||||
MemTxResult flatview_read_full(FlatView *fv, hwaddr addr,
|
||||
MemTxAttrs attrs, uint8_t *buf, int len);
|
||||
void *qemu_map_ram_ptr(RAMBlock *ram_block, ram_addr_t addr);
|
||||
|
||||
static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
|
||||
|
@ -1940,8 +1929,8 @@ static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
|
|||
* @buf: buffer with the data transferred
|
||||
*/
|
||||
static inline __attribute__((__always_inline__))
|
||||
MemTxResult address_space_read(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
|
||||
uint8_t *buf, int len)
|
||||
MemTxResult flatview_read(FlatView *fv, hwaddr addr, MemTxAttrs attrs,
|
||||
uint8_t *buf, int len)
|
||||
{
|
||||
MemTxResult result = MEMTX_OK;
|
||||
hwaddr l, addr1;
|
||||
|
@ -1952,22 +1941,29 @@ MemTxResult address_space_read(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
|
|||
if (len) {
|
||||
rcu_read_lock();
|
||||
l = len;
|
||||
mr = address_space_translate(as, addr, &addr1, &l, false);
|
||||
mr = flatview_translate(fv, addr, &addr1, &l, false);
|
||||
if (len == l && memory_access_is_direct(mr, false)) {
|
||||
ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
|
||||
memcpy(buf, ptr, len);
|
||||
} else {
|
||||
result = address_space_read_continue(as, addr, attrs, buf, len,
|
||||
addr1, l, mr);
|
||||
result = flatview_read_continue(fv, addr, attrs, buf, len,
|
||||
addr1, l, mr);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
} else {
|
||||
result = address_space_read_full(as, addr, attrs, buf, len);
|
||||
result = flatview_read_full(fv, addr, attrs, buf, len);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline MemTxResult address_space_read(AddressSpace *as, hwaddr addr,
|
||||
MemTxAttrs attrs, uint8_t *buf,
|
||||
int len)
|
||||
{
|
||||
return flatview_read(address_space_to_flatview(as), addr, attrs, buf, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* address_space_read_cached: read from a cached RAM region
|
||||
*
|
||||
|
|
|
@ -21,7 +21,7 @@ typedef struct {
|
|||
SysBusDevice parent_obj;
|
||||
/*< public >*/
|
||||
|
||||
AddressSpace *source_as;
|
||||
AddressSpace source_as;
|
||||
MemoryRegion iomem;
|
||||
uint32_t base;
|
||||
MemoryRegion *source_memory;
|
||||
|
|
|
@ -662,6 +662,7 @@ void spapr_cpu_parse_features(sPAPRMachineState *spapr);
|
|||
int spapr_hpt_shift_for_ramsize(uint64_t ramsize);
|
||||
void spapr_reallocate_hpt(sPAPRMachineState *spapr, int shift,
|
||||
Error **errp);
|
||||
void spapr_clear_pending_events(sPAPRMachineState *spapr);
|
||||
|
||||
/* CPU and LMB DRC release callbacks. */
|
||||
void spapr_core_release(DeviceState *dev);
|
||||
|
|
|
@ -257,6 +257,7 @@ int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object *owner,
|
|||
void spapr_drc_attach(sPAPRDRConnector *drc, DeviceState *d, void *fdt,
|
||||
int fdt_start_offset, Error **errp);
|
||||
void spapr_drc_detach(sPAPRDRConnector *drc);
|
||||
bool spapr_drc_needed(void *opaque);
|
||||
|
||||
static inline bool spapr_drc_unplug_requested(sPAPRDRConnector *drc)
|
||||
{
|
||||
|
|
|
@ -272,6 +272,7 @@ hwaddr virtio_queue_get_avail_size(VirtIODevice *vdev, int n);
|
|||
hwaddr virtio_queue_get_used_size(VirtIODevice *vdev, int n);
|
||||
uint16_t virtio_queue_get_last_avail_idx(VirtIODevice *vdev, int n);
|
||||
void virtio_queue_set_last_avail_idx(VirtIODevice *vdev, int n, uint16_t idx);
|
||||
void virtio_queue_restore_last_avail_idx(VirtIODevice *vdev, int n);
|
||||
void virtio_queue_invalidate_signalled_used(VirtIODevice *vdev, int n);
|
||||
void virtio_queue_update_used_idx(VirtIODevice *vdev, int n);
|
||||
VirtQueue *virtio_get_queue(VirtIODevice *vdev, int n);
|
||||
|
|
|
@ -442,4 +442,12 @@
|
|||
} while(0)
|
||||
#endif
|
||||
|
||||
#define atomic_fetch_inc_nonzero(ptr) ({ \
|
||||
typeof_strip_qual(*ptr) _oldn = atomic_read(ptr); \
|
||||
while (_oldn && atomic_cmpxchg(ptr, _oldn, _oldn + 1) != _oldn) { \
|
||||
_oldn = atomic_read(ptr); \
|
||||
} \
|
||||
_oldn; \
|
||||
})
|
||||
|
||||
#endif /* QEMU_ATOMIC_H */
|
||||
|
|
|
@ -189,13 +189,13 @@ extern int daemon(int, int);
|
|||
|
||||
/* Round number up to multiple. Requires that d be a power of 2 (see
|
||||
* QEMU_ALIGN_UP for a safer but slower version on arbitrary
|
||||
* numbers) */
|
||||
* numbers); works even if d is a smaller type than n. */
|
||||
#ifndef ROUND_UP
|
||||
#define ROUND_UP(n,d) (((n) + (d) - 1) & -(d))
|
||||
#define ROUND_UP(n, d) (((n) + (d) - 1) & -(0 ? (n) : (d)))
|
||||
#endif
|
||||
|
||||
#ifndef DIV_ROUND_UP
|
||||
#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
|
||||
#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
|
@ -30,6 +30,7 @@ typedef struct DisplaySurface DisplaySurface;
|
|||
typedef struct DriveInfo DriveInfo;
|
||||
typedef struct Error Error;
|
||||
typedef struct EventNotifier EventNotifier;
|
||||
typedef struct FlatView FlatView;
|
||||
typedef struct FWCfgEntry FWCfgEntry;
|
||||
typedef struct FWCfgIoState FWCfgIoState;
|
||||
typedef struct FWCfgMemState FWCfgMemState;
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include "trace.h"
|
||||
|
||||
|
||||
/* Max amount to allow in rawinput/rawoutput buffers */
|
||||
/* Max amount to allow in rawinput/encoutput buffers */
|
||||
#define QIO_CHANNEL_WEBSOCK_MAX_BUFFER 8192
|
||||
|
||||
#define QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN 24
|
||||
|
@ -1006,7 +1006,7 @@ qio_channel_websock_source_prepare(GSource *source,
|
|||
if (wsource->wioc->rawinput.offset) {
|
||||
cond |= G_IO_IN;
|
||||
}
|
||||
if (wsource->wioc->rawoutput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER) {
|
||||
if (wsource->wioc->encoutput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER) {
|
||||
cond |= G_IO_OUT;
|
||||
}
|
||||
|
||||
|
@ -1022,7 +1022,7 @@ qio_channel_websock_source_check(GSource *source)
|
|||
if (wsource->wioc->rawinput.offset) {
|
||||
cond |= G_IO_IN;
|
||||
}
|
||||
if (wsource->wioc->rawoutput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER) {
|
||||
if (wsource->wioc->encoutput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER) {
|
||||
cond |= G_IO_OUT;
|
||||
}
|
||||
|
||||
|
@ -1041,7 +1041,7 @@ qio_channel_websock_source_dispatch(GSource *source,
|
|||
if (wsource->wioc->rawinput.offset) {
|
||||
cond |= G_IO_IN;
|
||||
}
|
||||
if (wsource->wioc->rawoutput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER) {
|
||||
if (wsource->wioc->encoutput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER) {
|
||||
cond |= G_IO_OUT;
|
||||
}
|
||||
|
||||
|
|
273
memory.c
273
memory.c
|
@ -47,6 +47,8 @@ static QTAILQ_HEAD(memory_listeners, MemoryListener) memory_listeners
|
|||
static QTAILQ_HEAD(, AddressSpace) address_spaces
|
||||
= QTAILQ_HEAD_INITIALIZER(address_spaces);
|
||||
|
||||
static GHashTable *flat_views;
|
||||
|
||||
typedef struct AddrRange AddrRange;
|
||||
|
||||
/*
|
||||
|
@ -154,7 +156,8 @@ enum ListenerDirection { Forward, Reverse };
|
|||
/* No need to ref/unref .mr, the FlatRange keeps it alive. */
|
||||
#define MEMORY_LISTENER_UPDATE_REGION(fr, as, dir, callback, _args...) \
|
||||
do { \
|
||||
MemoryRegionSection mrs = section_from_flat_range(fr, as); \
|
||||
MemoryRegionSection mrs = section_from_flat_range(fr, \
|
||||
address_space_to_flatview(as)); \
|
||||
MEMORY_LISTENER_CALL(as, callback, dir, &mrs, ##_args); \
|
||||
} while(0)
|
||||
|
||||
|
@ -208,7 +211,6 @@ static bool memory_region_ioeventfd_equal(MemoryRegionIoeventfd a,
|
|||
}
|
||||
|
||||
typedef struct FlatRange FlatRange;
|
||||
typedef struct FlatView FlatView;
|
||||
|
||||
/* Range of memory in the global map. Addresses are absolute. */
|
||||
struct FlatRange {
|
||||
|
@ -229,6 +231,8 @@ struct FlatView {
|
|||
FlatRange *ranges;
|
||||
unsigned nr;
|
||||
unsigned nr_allocated;
|
||||
struct AddressSpaceDispatch *dispatch;
|
||||
MemoryRegion *root;
|
||||
};
|
||||
|
||||
typedef struct AddressSpaceOps AddressSpaceOps;
|
||||
|
@ -237,11 +241,11 @@ typedef struct AddressSpaceOps AddressSpaceOps;
|
|||
for (var = (view)->ranges; var < (view)->ranges + (view)->nr; ++var)
|
||||
|
||||
static inline MemoryRegionSection
|
||||
section_from_flat_range(FlatRange *fr, AddressSpace *as)
|
||||
section_from_flat_range(FlatRange *fr, FlatView *fv)
|
||||
{
|
||||
return (MemoryRegionSection) {
|
||||
.mr = fr->mr,
|
||||
.address_space = as,
|
||||
.fv = fv,
|
||||
.offset_within_region = fr->offset_in_region,
|
||||
.size = fr->addr.size,
|
||||
.offset_within_address_space = int128_get64(fr->addr.start),
|
||||
|
@ -258,12 +262,17 @@ static bool flatrange_equal(FlatRange *a, FlatRange *b)
|
|||
&& a->readonly == b->readonly;
|
||||
}
|
||||
|
||||
static void flatview_init(FlatView *view)
|
||||
static FlatView *flatview_new(MemoryRegion *mr_root)
|
||||
{
|
||||
FlatView *view;
|
||||
|
||||
view = g_new0(FlatView, 1);
|
||||
view->ref = 1;
|
||||
view->ranges = NULL;
|
||||
view->nr = 0;
|
||||
view->nr_allocated = 0;
|
||||
view->root = mr_root;
|
||||
memory_region_ref(mr_root);
|
||||
trace_flatview_new(view, mr_root);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
/* Insert a range into a given position. Caller is responsible for maintaining
|
||||
|
@ -287,25 +296,47 @@ static void flatview_destroy(FlatView *view)
|
|||
{
|
||||
int i;
|
||||
|
||||
trace_flatview_destroy(view, view->root);
|
||||
if (view->dispatch) {
|
||||
address_space_dispatch_free(view->dispatch);
|
||||
}
|
||||
for (i = 0; i < view->nr; i++) {
|
||||
memory_region_unref(view->ranges[i].mr);
|
||||
}
|
||||
g_free(view->ranges);
|
||||
memory_region_unref(view->root);
|
||||
g_free(view);
|
||||
}
|
||||
|
||||
static void flatview_ref(FlatView *view)
|
||||
static bool flatview_ref(FlatView *view)
|
||||
{
|
||||
atomic_inc(&view->ref);
|
||||
return atomic_fetch_inc_nonzero(&view->ref) > 0;
|
||||
}
|
||||
|
||||
static void flatview_unref(FlatView *view)
|
||||
{
|
||||
if (atomic_fetch_dec(&view->ref) == 1) {
|
||||
flatview_destroy(view);
|
||||
trace_flatview_destroy_rcu(view, view->root);
|
||||
assert(view->root);
|
||||
call_rcu(view, flatview_destroy, rcu);
|
||||
}
|
||||
}
|
||||
|
||||
FlatView *address_space_to_flatview(AddressSpace *as)
|
||||
{
|
||||
return atomic_rcu_read(&as->current_map);
|
||||
}
|
||||
|
||||
AddressSpaceDispatch *flatview_to_dispatch(FlatView *fv)
|
||||
{
|
||||
return fv->dispatch;
|
||||
}
|
||||
|
||||
AddressSpaceDispatch *address_space_to_dispatch(AddressSpace *as)
|
||||
{
|
||||
return flatview_to_dispatch(address_space_to_flatview(as));
|
||||
}
|
||||
|
||||
static bool can_merge(FlatRange *r1, FlatRange *r2)
|
||||
{
|
||||
return int128_eq(addrrange_end(r1->addr), r2->addr.start)
|
||||
|
@ -701,13 +732,57 @@ static void render_memory_region(FlatView *view,
|
|||
}
|
||||
}
|
||||
|
||||
static MemoryRegion *memory_region_get_flatview_root(MemoryRegion *mr)
|
||||
{
|
||||
while (mr->enabled) {
|
||||
if (mr->alias) {
|
||||
if (!mr->alias_offset && int128_ge(mr->size, mr->alias->size)) {
|
||||
/* The alias is included in its entirety. Use it as
|
||||
* the "real" root, so that we can share more FlatViews.
|
||||
*/
|
||||
mr = mr->alias;
|
||||
continue;
|
||||
}
|
||||
} else if (!mr->terminates) {
|
||||
unsigned int found = 0;
|
||||
MemoryRegion *child, *next = NULL;
|
||||
QTAILQ_FOREACH(child, &mr->subregions, subregions_link) {
|
||||
if (child->enabled) {
|
||||
if (++found > 1) {
|
||||
next = NULL;
|
||||
break;
|
||||
}
|
||||
if (!child->addr && int128_ge(mr->size, child->size)) {
|
||||
/* A child is included in its entirety. If it's the only
|
||||
* enabled one, use it in the hope of finding an alias down the
|
||||
* way. This will also let us share FlatViews.
|
||||
*/
|
||||
next = child;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found == 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (next) {
|
||||
mr = next;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return mr;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Render a memory topology into a list of disjoint absolute ranges. */
|
||||
static FlatView *generate_memory_topology(MemoryRegion *mr)
|
||||
{
|
||||
int i;
|
||||
FlatView *view;
|
||||
|
||||
view = g_new(FlatView, 1);
|
||||
flatview_init(view);
|
||||
view = flatview_new(mr);
|
||||
|
||||
if (mr) {
|
||||
render_memory_region(view, mr, int128_zero(),
|
||||
|
@ -715,6 +790,15 @@ static FlatView *generate_memory_topology(MemoryRegion *mr)
|
|||
}
|
||||
flatview_simplify(view);
|
||||
|
||||
view->dispatch = address_space_dispatch_new(view);
|
||||
for (i = 0; i < view->nr; i++) {
|
||||
MemoryRegionSection mrs =
|
||||
section_from_flat_range(&view->ranges[i], view);
|
||||
flatview_add_to_dispatch(view, &mrs);
|
||||
}
|
||||
address_space_dispatch_compact(view->dispatch);
|
||||
g_hash_table_replace(flat_views, mr, view);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
|
@ -740,7 +824,7 @@ static void address_space_add_del_ioeventfds(AddressSpace *as,
|
|||
fds_new[inew]))) {
|
||||
fd = &fds_old[iold];
|
||||
section = (MemoryRegionSection) {
|
||||
.address_space = as,
|
||||
.fv = address_space_to_flatview(as),
|
||||
.offset_within_address_space = int128_get64(fd->addr.start),
|
||||
.size = fd->addr.size,
|
||||
};
|
||||
|
@ -753,7 +837,7 @@ static void address_space_add_del_ioeventfds(AddressSpace *as,
|
|||
fds_old[iold]))) {
|
||||
fd = &fds_new[inew];
|
||||
section = (MemoryRegionSection) {
|
||||
.address_space = as,
|
||||
.fv = address_space_to_flatview(as),
|
||||
.offset_within_address_space = int128_get64(fd->addr.start),
|
||||
.size = fd->addr.size,
|
||||
};
|
||||
|
@ -772,8 +856,12 @@ static FlatView *address_space_get_flatview(AddressSpace *as)
|
|||
FlatView *view;
|
||||
|
||||
rcu_read_lock();
|
||||
view = atomic_rcu_read(&as->current_map);
|
||||
flatview_ref(view);
|
||||
do {
|
||||
view = address_space_to_flatview(as);
|
||||
/* If somebody has replaced as->current_map concurrently,
|
||||
* flatview_ref returns false.
|
||||
*/
|
||||
} while (!flatview_ref(view));
|
||||
rcu_read_unlock();
|
||||
return view;
|
||||
}
|
||||
|
@ -879,18 +967,81 @@ static void address_space_update_topology_pass(AddressSpace *as,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static void address_space_update_topology(AddressSpace *as)
|
||||
static void flatviews_init(void)
|
||||
{
|
||||
FlatView *old_view = address_space_get_flatview(as);
|
||||
FlatView *new_view = generate_memory_topology(as->root);
|
||||
static FlatView *empty_view;
|
||||
|
||||
address_space_update_topology_pass(as, old_view, new_view, false);
|
||||
address_space_update_topology_pass(as, old_view, new_view, true);
|
||||
if (flat_views) {
|
||||
return;
|
||||
}
|
||||
|
||||
flat_views = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL,
|
||||
(GDestroyNotify) flatview_unref);
|
||||
if (!empty_view) {
|
||||
empty_view = generate_memory_topology(NULL);
|
||||
/* We keep it alive forever in the global variable. */
|
||||
flatview_ref(empty_view);
|
||||
} else {
|
||||
g_hash_table_replace(flat_views, NULL, empty_view);
|
||||
flatview_ref(empty_view);
|
||||
}
|
||||
}
|
||||
|
||||
static void flatviews_reset(void)
|
||||
{
|
||||
AddressSpace *as;
|
||||
|
||||
if (flat_views) {
|
||||
g_hash_table_unref(flat_views);
|
||||
flat_views = NULL;
|
||||
}
|
||||
flatviews_init();
|
||||
|
||||
/* Render unique FVs */
|
||||
QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
|
||||
MemoryRegion *physmr = memory_region_get_flatview_root(as->root);
|
||||
|
||||
if (g_hash_table_lookup(flat_views, physmr)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
generate_memory_topology(physmr);
|
||||
}
|
||||
}
|
||||
|
||||
static void address_space_set_flatview(AddressSpace *as)
|
||||
{
|
||||
FlatView *old_view = address_space_to_flatview(as);
|
||||
MemoryRegion *physmr = memory_region_get_flatview_root(as->root);
|
||||
FlatView *new_view = g_hash_table_lookup(flat_views, physmr);
|
||||
|
||||
assert(new_view);
|
||||
|
||||
if (old_view == new_view) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (old_view) {
|
||||
flatview_ref(old_view);
|
||||
}
|
||||
|
||||
flatview_ref(new_view);
|
||||
|
||||
if (!QTAILQ_EMPTY(&as->listeners)) {
|
||||
FlatView tmpview = { .nr = 0 }, *old_view2 = old_view;
|
||||
|
||||
if (!old_view2) {
|
||||
old_view2 = &tmpview;
|
||||
}
|
||||
address_space_update_topology_pass(as, old_view2, new_view, false);
|
||||
address_space_update_topology_pass(as, old_view2, new_view, true);
|
||||
}
|
||||
|
||||
/* Writes are protected by the BQL. */
|
||||
atomic_rcu_set(&as->current_map, new_view);
|
||||
call_rcu(old_view, flatview_unref, rcu);
|
||||
if (old_view) {
|
||||
flatview_unref(old_view);
|
||||
}
|
||||
|
||||
/* Note that all the old MemoryRegions are still alive up to this
|
||||
* point. This relieves most MemoryListeners from the need to
|
||||
|
@ -898,9 +1049,20 @@ static void address_space_update_topology(AddressSpace *as)
|
|||
* outside the iothread mutex, in which case precise reference
|
||||
* counting is necessary.
|
||||
*/
|
||||
flatview_unref(old_view);
|
||||
if (old_view) {
|
||||
flatview_unref(old_view);
|
||||
}
|
||||
}
|
||||
|
||||
address_space_update_ioeventfds(as);
|
||||
static void address_space_update_topology(AddressSpace *as)
|
||||
{
|
||||
MemoryRegion *physmr = memory_region_get_flatview_root(as->root);
|
||||
|
||||
flatviews_init();
|
||||
if (!g_hash_table_lookup(flat_views, physmr)) {
|
||||
generate_memory_topology(physmr);
|
||||
}
|
||||
address_space_set_flatview(as);
|
||||
}
|
||||
|
||||
void memory_region_transaction_begin(void)
|
||||
|
@ -919,10 +1081,13 @@ void memory_region_transaction_commit(void)
|
|||
--memory_region_transaction_depth;
|
||||
if (!memory_region_transaction_depth) {
|
||||
if (memory_region_update_pending) {
|
||||
flatviews_reset();
|
||||
|
||||
MEMORY_LISTENER_CALL_GLOBAL(begin, Forward);
|
||||
|
||||
QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
|
||||
address_space_update_topology(as);
|
||||
address_space_set_flatview(as);
|
||||
address_space_update_ioeventfds(as);
|
||||
}
|
||||
memory_region_update_pending = false;
|
||||
MEMORY_LISTENER_CALL_GLOBAL(commit, Forward);
|
||||
|
@ -1726,7 +1891,7 @@ void memory_region_notify_one(IOMMUNotifier *notifier,
|
|||
* Skip the notification if the notification does not overlap
|
||||
* with registered range.
|
||||
*/
|
||||
if (notifier->start > entry->iova + entry->addr_mask + 1 ||
|
||||
if (notifier->start > entry->iova + entry->addr_mask ||
|
||||
notifier->end < entry->iova) {
|
||||
return;
|
||||
}
|
||||
|
@ -1835,7 +2000,7 @@ void memory_region_sync_dirty_bitmap(MemoryRegion *mr)
|
|||
view = address_space_get_flatview(as);
|
||||
FOR_EACH_FLAT_RANGE(fr, view) {
|
||||
if (fr->mr == mr) {
|
||||
MemoryRegionSection mrs = section_from_flat_range(fr, as);
|
||||
MemoryRegionSection mrs = section_from_flat_range(fr, view);
|
||||
listener->log_sync(listener, &mrs);
|
||||
}
|
||||
}
|
||||
|
@ -1938,7 +2103,7 @@ static void memory_region_update_coalesced_range_as(MemoryRegion *mr, AddressSpa
|
|||
FOR_EACH_FLAT_RANGE(fr, view) {
|
||||
if (fr->mr == mr) {
|
||||
section = (MemoryRegionSection) {
|
||||
.address_space = as,
|
||||
.fv = view,
|
||||
.offset_within_address_space = int128_get64(fr->addr.start),
|
||||
.size = fr->addr.size,
|
||||
};
|
||||
|
@ -2289,7 +2454,7 @@ static MemoryRegionSection memory_region_find_rcu(MemoryRegion *mr,
|
|||
}
|
||||
range = addrrange_make(int128_make64(addr), int128_make64(size));
|
||||
|
||||
view = atomic_rcu_read(&as->current_map);
|
||||
view = address_space_to_flatview(as);
|
||||
fr = flatview_lookup(view, range);
|
||||
if (!fr) {
|
||||
return ret;
|
||||
|
@ -2300,7 +2465,7 @@ static MemoryRegionSection memory_region_find_rcu(MemoryRegion *mr,
|
|||
}
|
||||
|
||||
ret.mr = fr->mr;
|
||||
ret.address_space = as;
|
||||
ret.fv = view;
|
||||
range = addrrange_intersection(range, fr->addr);
|
||||
ret.offset_within_region = fr->offset_in_region;
|
||||
ret.offset_within_region += int128_get64(int128_sub(range.start,
|
||||
|
@ -2349,7 +2514,8 @@ void memory_global_dirty_log_sync(void)
|
|||
view = address_space_get_flatview(as);
|
||||
FOR_EACH_FLAT_RANGE(fr, view) {
|
||||
if (fr->dirty_log_mask) {
|
||||
MemoryRegionSection mrs = section_from_flat_range(fr, as);
|
||||
MemoryRegionSection mrs = section_from_flat_range(fr, view);
|
||||
|
||||
listener->log_sync(listener, &mrs);
|
||||
}
|
||||
}
|
||||
|
@ -2434,7 +2600,7 @@ static void listener_add_address_space(MemoryListener *listener,
|
|||
FOR_EACH_FLAT_RANGE(fr, view) {
|
||||
MemoryRegionSection section = {
|
||||
.mr = fr->mr,
|
||||
.address_space = as,
|
||||
.fv = view,
|
||||
.offset_within_region = fr->offset_in_region,
|
||||
.size = fr->addr.size,
|
||||
.offset_within_address_space = int128_get64(fr->addr.start),
|
||||
|
@ -2610,69 +2776,36 @@ void memory_region_invalidate_mmio_ptr(MemoryRegion *mr, hwaddr offset,
|
|||
void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name)
|
||||
{
|
||||
memory_region_ref(root);
|
||||
memory_region_transaction_begin();
|
||||
as->ref_count = 1;
|
||||
as->root = root;
|
||||
as->malloced = false;
|
||||
as->current_map = g_new(FlatView, 1);
|
||||
flatview_init(as->current_map);
|
||||
as->current_map = NULL;
|
||||
as->ioeventfd_nb = 0;
|
||||
as->ioeventfds = NULL;
|
||||
QTAILQ_INIT(&as->listeners);
|
||||
QTAILQ_INSERT_TAIL(&address_spaces, as, address_spaces_link);
|
||||
as->name = g_strdup(name ? name : "anonymous");
|
||||
address_space_init_dispatch(as);
|
||||
memory_region_update_pending |= root->enabled;
|
||||
memory_region_transaction_commit();
|
||||
address_space_update_topology(as);
|
||||
address_space_update_ioeventfds(as);
|
||||
}
|
||||
|
||||
static void do_address_space_destroy(AddressSpace *as)
|
||||
{
|
||||
bool do_free = as->malloced;
|
||||
|
||||
address_space_destroy_dispatch(as);
|
||||
assert(QTAILQ_EMPTY(&as->listeners));
|
||||
|
||||
flatview_unref(as->current_map);
|
||||
g_free(as->name);
|
||||
g_free(as->ioeventfds);
|
||||
memory_region_unref(as->root);
|
||||
if (do_free) {
|
||||
g_free(as);
|
||||
}
|
||||
}
|
||||
|
||||
AddressSpace *address_space_init_shareable(MemoryRegion *root, const char *name)
|
||||
{
|
||||
AddressSpace *as;
|
||||
|
||||
QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
|
||||
if (root == as->root && as->malloced) {
|
||||
as->ref_count++;
|
||||
return as;
|
||||
}
|
||||
}
|
||||
|
||||
as = g_malloc0(sizeof *as);
|
||||
address_space_init(as, root, name);
|
||||
as->malloced = true;
|
||||
return as;
|
||||
}
|
||||
|
||||
void address_space_destroy(AddressSpace *as)
|
||||
{
|
||||
MemoryRegion *root = as->root;
|
||||
|
||||
as->ref_count--;
|
||||
if (as->ref_count) {
|
||||
return;
|
||||
}
|
||||
/* Flush out anything from MemoryListeners listening in on this */
|
||||
memory_region_transaction_begin();
|
||||
as->root = NULL;
|
||||
memory_region_transaction_commit();
|
||||
QTAILQ_REMOVE(&address_spaces, as, address_spaces_link);
|
||||
address_space_unregister(as);
|
||||
|
||||
/* At this point, as->dispatch and as->current_map are dummy
|
||||
* entries that the guest should never use. Wait for the old
|
||||
|
|
|
@ -161,6 +161,11 @@ int blk_mig_active(void)
|
|||
return !QSIMPLEQ_EMPTY(&block_mig_state.bmds_list);
|
||||
}
|
||||
|
||||
int blk_mig_bulk_active(void)
|
||||
{
|
||||
return blk_mig_active() && !block_mig_state.bulk_completed;
|
||||
}
|
||||
|
||||
uint64_t blk_mig_bytes_transferred(void)
|
||||
{
|
||||
BlkMigDevState *bmds;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#ifdef CONFIG_LIVE_BLOCK_MIGRATION
|
||||
int blk_mig_active(void);
|
||||
int blk_mig_bulk_active(void);
|
||||
uint64_t blk_mig_bytes_transferred(void);
|
||||
uint64_t blk_mig_bytes_remaining(void);
|
||||
uint64_t blk_mig_bytes_total(void);
|
||||
|
@ -25,6 +26,12 @@ static inline int blk_mig_active(void)
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline int blk_mig_bulk_active(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline uint64_t blk_mig_bytes_transferred(void)
|
||||
{
|
||||
return 0;
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include "exec/ram_addr.h"
|
||||
#include "qemu/rcu_queue.h"
|
||||
#include "migration/colo.h"
|
||||
#include "migration/block.h"
|
||||
|
||||
/***********************************************************/
|
||||
/* ram save/restore */
|
||||
|
@ -623,7 +624,10 @@ static void migration_bitmap_sync(RAMState *rs)
|
|||
/ (end_time - rs->time_last_bitmap_sync);
|
||||
bytes_xfer_now = ram_counters.transferred;
|
||||
|
||||
if (migrate_auto_converge()) {
|
||||
/* During block migration the auto-converge logic incorrectly detects
|
||||
* that ram migration makes no progress. Avoid this by disabling the
|
||||
* throttling logic during the bulk phase of block migration. */
|
||||
if (migrate_auto_converge() && !blk_mig_bulk_active()) {
|
||||
/* The following detection logic can be refined later. For now:
|
||||
Check to see if the dirtied bytes is 50% more than the approx.
|
||||
amount of bytes that just got transferred since the last time we
|
||||
|
|
56
nbd/client.c
56
nbd/client.c
|
@ -111,12 +111,12 @@ static int nbd_send_option_request(QIOChannel *ioc, uint32_t opt,
|
|||
stl_be_p(&req.length, len);
|
||||
|
||||
if (nbd_write(ioc, &req, sizeof(req), errp) < 0) {
|
||||
error_prepend(errp, "Failed to send option request header");
|
||||
error_prepend(errp, "Failed to send option request header: ");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (len && nbd_write(ioc, (char *) data, len, errp) < 0) {
|
||||
error_prepend(errp, "Failed to send option request data");
|
||||
error_prepend(errp, "Failed to send option request data: ");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -145,7 +145,7 @@ static int nbd_receive_option_reply(QIOChannel *ioc, uint32_t opt,
|
|||
{
|
||||
QEMU_BUILD_BUG_ON(sizeof(*reply) != 20);
|
||||
if (nbd_read(ioc, reply, sizeof(*reply), errp) < 0) {
|
||||
error_prepend(errp, "failed to read option reply");
|
||||
error_prepend(errp, "failed to read option reply: ");
|
||||
nbd_send_opt_abort(ioc);
|
||||
return -1;
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ static int nbd_handle_reply_err(QIOChannel *ioc, nbd_opt_reply *reply,
|
|||
msg = g_malloc(reply->length + 1);
|
||||
if (nbd_read(ioc, msg, reply->length, errp) < 0) {
|
||||
error_prepend(errp, "failed to read option error 0x%" PRIx32
|
||||
" (%s) message",
|
||||
" (%s) message: ",
|
||||
reply->type, nbd_rep_lookup(reply->type));
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -309,7 +309,7 @@ static int nbd_receive_list(QIOChannel *ioc, const char *want, bool *match,
|
|||
return -1;
|
||||
}
|
||||
if (nbd_read(ioc, &namelen, sizeof(namelen), errp) < 0) {
|
||||
error_prepend(errp, "failed to read option name length");
|
||||
error_prepend(errp, "failed to read option name length: ");
|
||||
nbd_send_opt_abort(ioc);
|
||||
return -1;
|
||||
}
|
||||
|
@ -322,7 +322,8 @@ static int nbd_receive_list(QIOChannel *ioc, const char *want, bool *match,
|
|||
}
|
||||
if (namelen != strlen(want)) {
|
||||
if (nbd_drop(ioc, len, errp) < 0) {
|
||||
error_prepend(errp, "failed to skip export name with wrong length");
|
||||
error_prepend(errp,
|
||||
"failed to skip export name with wrong length: ");
|
||||
nbd_send_opt_abort(ioc);
|
||||
return -1;
|
||||
}
|
||||
|
@ -331,14 +332,14 @@ static int nbd_receive_list(QIOChannel *ioc, const char *want, bool *match,
|
|||
|
||||
assert(namelen < sizeof(name));
|
||||
if (nbd_read(ioc, name, namelen, errp) < 0) {
|
||||
error_prepend(errp, "failed to read export name");
|
||||
error_prepend(errp, "failed to read export name: ");
|
||||
nbd_send_opt_abort(ioc);
|
||||
return -1;
|
||||
}
|
||||
name[namelen] = '\0';
|
||||
len -= namelen;
|
||||
if (nbd_drop(ioc, len, errp) < 0) {
|
||||
error_prepend(errp, "failed to read export description");
|
||||
error_prepend(errp, "failed to read export description: ");
|
||||
nbd_send_opt_abort(ioc);
|
||||
return -1;
|
||||
}
|
||||
|
@ -424,7 +425,7 @@ static int nbd_opt_go(QIOChannel *ioc, const char *wantname,
|
|||
return -1;
|
||||
}
|
||||
if (nbd_read(ioc, &type, sizeof(type), errp) < 0) {
|
||||
error_prepend(errp, "failed to read info type");
|
||||
error_prepend(errp, "failed to read info type: ");
|
||||
nbd_send_opt_abort(ioc);
|
||||
return -1;
|
||||
}
|
||||
|
@ -439,13 +440,13 @@ static int nbd_opt_go(QIOChannel *ioc, const char *wantname,
|
|||
return -1;
|
||||
}
|
||||
if (nbd_read(ioc, &info->size, sizeof(info->size), errp) < 0) {
|
||||
error_prepend(errp, "failed to read info size");
|
||||
error_prepend(errp, "failed to read info size: ");
|
||||
nbd_send_opt_abort(ioc);
|
||||
return -1;
|
||||
}
|
||||
be64_to_cpus(&info->size);
|
||||
if (nbd_read(ioc, &info->flags, sizeof(info->flags), errp) < 0) {
|
||||
error_prepend(errp, "failed to read info flags");
|
||||
error_prepend(errp, "failed to read info flags: ");
|
||||
nbd_send_opt_abort(ioc);
|
||||
return -1;
|
||||
}
|
||||
|
@ -462,7 +463,7 @@ static int nbd_opt_go(QIOChannel *ioc, const char *wantname,
|
|||
}
|
||||
if (nbd_read(ioc, &info->min_block, sizeof(info->min_block),
|
||||
errp) < 0) {
|
||||
error_prepend(errp, "failed to read info minimum block size");
|
||||
error_prepend(errp, "failed to read info minimum block size: ");
|
||||
nbd_send_opt_abort(ioc);
|
||||
return -1;
|
||||
}
|
||||
|
@ -475,7 +476,8 @@ static int nbd_opt_go(QIOChannel *ioc, const char *wantname,
|
|||
}
|
||||
if (nbd_read(ioc, &info->opt_block, sizeof(info->opt_block),
|
||||
errp) < 0) {
|
||||
error_prepend(errp, "failed to read info preferred block size");
|
||||
error_prepend(errp,
|
||||
"failed to read info preferred block size: ");
|
||||
nbd_send_opt_abort(ioc);
|
||||
return -1;
|
||||
}
|
||||
|
@ -489,7 +491,7 @@ static int nbd_opt_go(QIOChannel *ioc, const char *wantname,
|
|||
}
|
||||
if (nbd_read(ioc, &info->max_block, sizeof(info->max_block),
|
||||
errp) < 0) {
|
||||
error_prepend(errp, "failed to read info maximum block size");
|
||||
error_prepend(errp, "failed to read info maximum block size: ");
|
||||
nbd_send_opt_abort(ioc);
|
||||
return -1;
|
||||
}
|
||||
|
@ -501,7 +503,7 @@ static int nbd_opt_go(QIOChannel *ioc, const char *wantname,
|
|||
default:
|
||||
trace_nbd_opt_go_info_unknown(type, nbd_info_lookup(type));
|
||||
if (nbd_drop(ioc, len, errp) < 0) {
|
||||
error_prepend(errp, "Failed to read info payload");
|
||||
error_prepend(errp, "Failed to read info payload: ");
|
||||
nbd_send_opt_abort(ioc);
|
||||
return -1;
|
||||
}
|
||||
|
@ -624,7 +626,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name,
|
|||
}
|
||||
|
||||
if (nbd_read(ioc, buf, 8, errp) < 0) {
|
||||
error_prepend(errp, "Failed to read data");
|
||||
error_prepend(errp, "Failed to read data: ");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -643,7 +645,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name,
|
|||
}
|
||||
|
||||
if (nbd_read(ioc, &magic, sizeof(magic), errp) < 0) {
|
||||
error_prepend(errp, "Failed to read magic");
|
||||
error_prepend(errp, "Failed to read magic: ");
|
||||
goto fail;
|
||||
}
|
||||
magic = be64_to_cpu(magic);
|
||||
|
@ -655,7 +657,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name,
|
|||
bool fixedNewStyle = false;
|
||||
|
||||
if (nbd_read(ioc, &globalflags, sizeof(globalflags), errp) < 0) {
|
||||
error_prepend(errp, "Failed to read server flags");
|
||||
error_prepend(errp, "Failed to read server flags: ");
|
||||
goto fail;
|
||||
}
|
||||
globalflags = be16_to_cpu(globalflags);
|
||||
|
@ -671,7 +673,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name,
|
|||
/* client requested flags */
|
||||
clientflags = cpu_to_be32(clientflags);
|
||||
if (nbd_write(ioc, &clientflags, sizeof(clientflags), errp) < 0) {
|
||||
error_prepend(errp, "Failed to send clientflags field");
|
||||
error_prepend(errp, "Failed to send clientflags field: ");
|
||||
goto fail;
|
||||
}
|
||||
if (tlscreds) {
|
||||
|
@ -723,13 +725,13 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name,
|
|||
|
||||
/* Read the response */
|
||||
if (nbd_read(ioc, &info->size, sizeof(info->size), errp) < 0) {
|
||||
error_prepend(errp, "Failed to read export length");
|
||||
error_prepend(errp, "Failed to read export length: ");
|
||||
goto fail;
|
||||
}
|
||||
be64_to_cpus(&info->size);
|
||||
|
||||
if (nbd_read(ioc, &info->flags, sizeof(info->flags), errp) < 0) {
|
||||
error_prepend(errp, "Failed to read export flags");
|
||||
error_prepend(errp, "Failed to read export flags: ");
|
||||
goto fail;
|
||||
}
|
||||
be16_to_cpus(&info->flags);
|
||||
|
@ -746,13 +748,13 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name,
|
|||
}
|
||||
|
||||
if (nbd_read(ioc, &info->size, sizeof(info->size), errp) < 0) {
|
||||
error_prepend(errp, "Failed to read export length");
|
||||
error_prepend(errp, "Failed to read export length: ");
|
||||
goto fail;
|
||||
}
|
||||
be64_to_cpus(&info->size);
|
||||
|
||||
if (nbd_read(ioc, &oldflags, sizeof(oldflags), errp) < 0) {
|
||||
error_prepend(errp, "Failed to read export flags");
|
||||
error_prepend(errp, "Failed to read export flags: ");
|
||||
goto fail;
|
||||
}
|
||||
be32_to_cpus(&oldflags);
|
||||
|
@ -768,7 +770,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name,
|
|||
|
||||
trace_nbd_receive_negotiate_size_flags(info->size, info->flags);
|
||||
if (zeroes && nbd_drop(ioc, 124, errp) < 0) {
|
||||
error_prepend(errp, "Failed to read reserved block");
|
||||
error_prepend(errp, "Failed to read reserved block: ");
|
||||
goto fail;
|
||||
}
|
||||
rc = 0;
|
||||
|
@ -943,12 +945,6 @@ ssize_t nbd_receive_reply(QIOChannel *ioc, NBDReply *reply, Error **errp)
|
|||
reply->handle = ldq_be_p(buf + 8);
|
||||
|
||||
reply->error = nbd_errno_to_system_errno(reply->error);
|
||||
|
||||
if (reply->error == ESHUTDOWN) {
|
||||
/* This works even on mingw which lacks a native ESHUTDOWN */
|
||||
error_setg(errp, "server shutting down");
|
||||
return -EINVAL;
|
||||
}
|
||||
trace_nbd_receive_reply(magic, reply->error, reply->handle);
|
||||
|
||||
if (magic != NBD_REPLY_MAGIC) {
|
||||
|
|
13
nbd/server.c
13
nbd/server.c
|
@ -393,6 +393,10 @@ static int nbd_negotiate_handle_info(NBDClient *client, uint32_t length,
|
|||
msg = "name length is incorrect";
|
||||
goto invalid;
|
||||
}
|
||||
if (namelen >= sizeof(name)) {
|
||||
msg = "name too long for qemu";
|
||||
goto invalid;
|
||||
}
|
||||
if (nbd_read(client->ioc, name, namelen, errp) < 0) {
|
||||
return -EIO;
|
||||
}
|
||||
|
@ -430,6 +434,7 @@ static int nbd_negotiate_handle_info(NBDClient *client, uint32_t length,
|
|||
break;
|
||||
}
|
||||
}
|
||||
assert(length == 0);
|
||||
|
||||
exp = nbd_export_find(name);
|
||||
if (!exp) {
|
||||
|
@ -440,7 +445,7 @@ static int nbd_negotiate_handle_info(NBDClient *client, uint32_t length,
|
|||
|
||||
/* Don't bother sending NBD_INFO_NAME unless client requested it */
|
||||
if (sendname) {
|
||||
rc = nbd_negotiate_send_info(client, opt, NBD_INFO_NAME, length, name,
|
||||
rc = nbd_negotiate_send_info(client, opt, NBD_INFO_NAME, namelen, name,
|
||||
errp);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
|
@ -661,6 +666,12 @@ static int nbd_negotiate_options(NBDClient *client, uint16_t myflags,
|
|||
}
|
||||
length = be32_to_cpu(length);
|
||||
|
||||
if (length > NBD_MAX_BUFFER_SIZE) {
|
||||
error_setg(errp, "len (%" PRIu32" ) is larger than max len (%u)",
|
||||
length, NBD_MAX_BUFFER_SIZE);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
trace_nbd_negotiate_options_check_option(option,
|
||||
nbd_opt_lookup(option));
|
||||
if (client->tlscreds &&
|
||||
|
|
|
@ -369,7 +369,7 @@ static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer,
|
|||
net_socket_read_poll(s, true);
|
||||
|
||||
/* mcast: save bound address as dst */
|
||||
if (is_connected) {
|
||||
if (is_connected && mcast != NULL) {
|
||||
s->dgram_dst = saddr;
|
||||
snprintf(nc->info_str, sizeof(nc->info_str),
|
||||
"socket: fd=%d (cloned mcast=%s:%d)",
|
||||
|
@ -674,8 +674,8 @@ int net_init_socket(const Netdev *netdev, const char *name,
|
|||
assert(netdev->type == NET_CLIENT_DRIVER_SOCKET);
|
||||
sock = &netdev->u.socket;
|
||||
|
||||
if (sock->has_listen + sock->has_connect + sock->has_mcast +
|
||||
sock->has_udp > 1) {
|
||||
if (sock->has_fd + sock->has_listen + sock->has_connect + sock->has_mcast +
|
||||
sock->has_udp != 1) {
|
||||
error_report("exactly one of listen=, connect=, mcast= or udp="
|
||||
" is required");
|
||||
return -1;
|
||||
|
|
|
@ -133,7 +133,7 @@ struct ccw1 {
|
|||
__u8 flags;
|
||||
__u16 count;
|
||||
__u32 cda;
|
||||
} __attribute__ ((packed));
|
||||
} __attribute__ ((packed, aligned(8)));
|
||||
|
||||
#define CCW_FLAG_DC 0x80
|
||||
#define CCW_FLAG_CC 0x40
|
||||
|
|
|
@ -187,7 +187,6 @@ ERROR_WHITELIST = [
|
|||
{'log':r"Device [\w.,-]+ can not be dynamically instantiated"},
|
||||
{'log':r"Platform Bus: Can not fit MMIO region of size "},
|
||||
# other more specific errors we will ignore:
|
||||
{'device':'allwinner-a10', 'log':"Unsupported NIC model:"},
|
||||
{'device':'.*-spapr-cpu-core', 'log':r"CPU core type should be"},
|
||||
{'log':r"MSI(-X)? is not supported by interrupt controller"},
|
||||
{'log':r"pxb-pcie? devices cannot reside on a PCIe? bus"},
|
||||
|
|
|
@ -20,6 +20,10 @@ git checkout "v${version}"
|
|||
git submodule update --init
|
||||
(cd roms/seabios && git describe --tags --long --dirty > .version)
|
||||
rm -rf .git roms/*/.git dtc/.git pixman/.git
|
||||
# FIXME: The following line is a workaround for avoiding filename collisions
|
||||
# when unpacking u-boot sources on case-insensitive filesystems. Once we
|
||||
# update to something with u-boot commit 610eec7f0 we can drop this line.
|
||||
tar cfj roms/u-boot.tar.bz2 -C roms u-boot && rm -rf roms/u-boot
|
||||
popd
|
||||
tar cfj ${destination}.tar.bz2 ${destination}
|
||||
rm -rf ${destination}
|
||||
|
|
|
@ -59,6 +59,27 @@ socreate(Slirp *slirp)
|
|||
return(so);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove references to so from the given message queue.
|
||||
*/
|
||||
static void
|
||||
soqfree(struct socket *so, struct quehead *qh)
|
||||
{
|
||||
struct mbuf *ifq;
|
||||
|
||||
for (ifq = (struct mbuf *) qh->qh_link;
|
||||
(struct quehead *) ifq != qh;
|
||||
ifq = ifq->ifq_next) {
|
||||
if (ifq->ifq_so == so) {
|
||||
struct mbuf *ifm;
|
||||
ifq->ifq_so = NULL;
|
||||
for (ifm = ifq->ifs_next; ifm != ifq; ifm = ifm->ifs_next) {
|
||||
ifm->ifq_so = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* remque and free a socket, clobber cache
|
||||
*/
|
||||
|
@ -66,23 +87,9 @@ void
|
|||
sofree(struct socket *so)
|
||||
{
|
||||
Slirp *slirp = so->slirp;
|
||||
struct mbuf *ifm;
|
||||
|
||||
for (ifm = (struct mbuf *) slirp->if_fastq.qh_link;
|
||||
(struct quehead *) ifm != &slirp->if_fastq;
|
||||
ifm = ifm->ifq_next) {
|
||||
if (ifm->ifq_so == so) {
|
||||
ifm->ifq_so = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for (ifm = (struct mbuf *) slirp->if_batchq.qh_link;
|
||||
(struct quehead *) ifm != &slirp->if_batchq;
|
||||
ifm = ifm->ifq_next) {
|
||||
if (ifm->ifq_so == so) {
|
||||
ifm->ifq_so = NULL;
|
||||
}
|
||||
}
|
||||
soqfree(so, &slirp->if_fastq);
|
||||
soqfree(so, &slirp->if_batchq);
|
||||
|
||||
if (so->so_emu==EMU_RSH && so->extra) {
|
||||
sofree(so->extra);
|
||||
|
|
|
@ -40,3 +40,4 @@ stub-obj-y += pc_madt_cpu_entry.o
|
|||
stub-obj-y += vmgenid.o
|
||||
stub-obj-y += xen-common.o
|
||||
stub-obj-y += xen-hvm.o
|
||||
stub-obj-y += pci-host-piix.o
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
#include "qemu/osdep.h"
|
||||
#include "hw/i386/pc.h"
|
||||
PCIBus *find_i440fx(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
|
@ -650,6 +650,9 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
|
|||
CPUARMState *env = &cpu->env;
|
||||
int pagebits;
|
||||
Error *local_err = NULL;
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
AddressSpace *as;
|
||||
#endif
|
||||
|
||||
cpu_exec_realizefn(cs, &local_err);
|
||||
if (local_err != NULL) {
|
||||
|
@ -835,19 +838,17 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
|
|||
}
|
||||
|
||||
if (cpu->has_el3) {
|
||||
AddressSpace *as;
|
||||
as = g_new0(AddressSpace, 1);
|
||||
|
||||
if (!cpu->secure_memory) {
|
||||
cpu->secure_memory = cs->memory;
|
||||
}
|
||||
as = address_space_init_shareable(cpu->secure_memory,
|
||||
"cpu-secure-memory");
|
||||
address_space_init(as, cpu->secure_memory, "cpu-secure-memory");
|
||||
cpu_address_space_init(cs, as, ARMASIdx_S);
|
||||
}
|
||||
cpu_address_space_init(cs,
|
||||
address_space_init_shareable(cs->memory,
|
||||
"cpu-memory"),
|
||||
ARMASIdx_NS);
|
||||
as = g_new0(AddressSpace, 1);
|
||||
address_space_init(as, cs->memory, "cpu-memory");
|
||||
cpu_address_space_init(cs, as, ARMASIdx_NS);
|
||||
#endif
|
||||
|
||||
qemu_init_vcpu(cs);
|
||||
|
|
|
@ -2217,29 +2217,34 @@ static void disas_ldst_pair(DisasContext *s, uint32_t insn)
|
|||
} else {
|
||||
do_fp_st(s, rt, tcg_addr, size);
|
||||
}
|
||||
} else {
|
||||
TCGv_i64 tcg_rt = cpu_reg(s, rt);
|
||||
if (is_load) {
|
||||
do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, false,
|
||||
false, 0, false, false);
|
||||
} else {
|
||||
do_gpr_st(s, tcg_rt, tcg_addr, size,
|
||||
false, 0, false, false);
|
||||
}
|
||||
}
|
||||
tcg_gen_addi_i64(tcg_addr, tcg_addr, 1 << size);
|
||||
if (is_vector) {
|
||||
tcg_gen_addi_i64(tcg_addr, tcg_addr, 1 << size);
|
||||
if (is_load) {
|
||||
do_fp_ld(s, rt2, tcg_addr, size);
|
||||
} else {
|
||||
do_fp_st(s, rt2, tcg_addr, size);
|
||||
}
|
||||
} else {
|
||||
TCGv_i64 tcg_rt = cpu_reg(s, rt);
|
||||
TCGv_i64 tcg_rt2 = cpu_reg(s, rt2);
|
||||
|
||||
if (is_load) {
|
||||
TCGv_i64 tmp = tcg_temp_new_i64();
|
||||
|
||||
/* Do not modify tcg_rt before recognizing any exception
|
||||
* from the second load.
|
||||
*/
|
||||
do_gpr_ld(s, tmp, tcg_addr, size, is_signed, false,
|
||||
false, 0, false, false);
|
||||
tcg_gen_addi_i64(tcg_addr, tcg_addr, 1 << size);
|
||||
do_gpr_ld(s, tcg_rt2, tcg_addr, size, is_signed, false,
|
||||
false, 0, false, false);
|
||||
|
||||
tcg_gen_mov_i64(tcg_rt, tmp);
|
||||
tcg_temp_free_i64(tmp);
|
||||
} else {
|
||||
do_gpr_st(s, tcg_rt, tcg_addr, size,
|
||||
false, 0, false, false);
|
||||
tcg_gen_addi_i64(tcg_addr, tcg_addr, 1 << size);
|
||||
do_gpr_st(s, tcg_rt2, tcg_addr, size,
|
||||
false, 0, false, false);
|
||||
}
|
||||
|
|
|
@ -7858,9 +7858,27 @@ static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
|
|||
TCGv_i32 tmp2 = tcg_temp_new_i32();
|
||||
TCGv_i64 t64 = tcg_temp_new_i64();
|
||||
|
||||
gen_aa32_ld_i64(s, t64, addr, get_mem_index(s), opc);
|
||||
/* For AArch32, architecturally the 32-bit word at the lowest
|
||||
* address is always Rt and the one at addr+4 is Rt2, even if
|
||||
* the CPU is big-endian. That means we don't want to do a
|
||||
* gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
|
||||
* for an architecturally 64-bit access, but instead do a
|
||||
* 64-bit access using MO_BE if appropriate and then split
|
||||
* the two halves.
|
||||
* This only makes a difference for BE32 user-mode, where
|
||||
* frob64() must not flip the two halves of the 64-bit data
|
||||
* but this code must treat BE32 user-mode like BE32 system.
|
||||
*/
|
||||
TCGv taddr = gen_aa32_addr(s, addr, opc);
|
||||
|
||||
tcg_gen_qemu_ld_i64(t64, taddr, get_mem_index(s), opc);
|
||||
tcg_temp_free(taddr);
|
||||
tcg_gen_mov_i64(cpu_exclusive_val, t64);
|
||||
tcg_gen_extr_i64_i32(tmp, tmp2, t64);
|
||||
if (s->be_data == MO_BE) {
|
||||
tcg_gen_extr_i64_i32(tmp2, tmp, t64);
|
||||
} else {
|
||||
tcg_gen_extr_i64_i32(tmp, tmp2, t64);
|
||||
}
|
||||
tcg_temp_free_i64(t64);
|
||||
|
||||
store_reg(s, rt2, tmp2);
|
||||
|
@ -7909,15 +7927,26 @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
|
|||
TCGv_i64 n64 = tcg_temp_new_i64();
|
||||
|
||||
t2 = load_reg(s, rt2);
|
||||
tcg_gen_concat_i32_i64(n64, t1, t2);
|
||||
/* For AArch32, architecturally the 32-bit word at the lowest
|
||||
* address is always Rt and the one at addr+4 is Rt2, even if
|
||||
* the CPU is big-endian. Since we're going to treat this as a
|
||||
* single 64-bit BE store, we need to put the two halves in the
|
||||
* opposite order for BE to LE, so that they end up in the right
|
||||
* places.
|
||||
* We don't want gen_aa32_frob64() because that does the wrong
|
||||
* thing for BE32 usermode.
|
||||
*/
|
||||
if (s->be_data == MO_BE) {
|
||||
tcg_gen_concat_i32_i64(n64, t2, t1);
|
||||
} else {
|
||||
tcg_gen_concat_i32_i64(n64, t1, t2);
|
||||
}
|
||||
tcg_temp_free_i32(t2);
|
||||
gen_aa32_frob64(s, n64);
|
||||
|
||||
tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
|
||||
get_mem_index(s), opc);
|
||||
tcg_temp_free_i64(n64);
|
||||
|
||||
gen_aa32_frob64(s, o64);
|
||||
tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
|
||||
tcg_gen_extrl_i64_i32(t0, o64);
|
||||
|
||||
|
|
|
@ -3702,10 +3702,11 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
|
|||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
if (tcg_enabled()) {
|
||||
AddressSpace *as_normal = address_space_init_shareable(cs->memory,
|
||||
"cpu-memory");
|
||||
AddressSpace *as_normal = g_new0(AddressSpace, 1);
|
||||
AddressSpace *as_smm = g_new(AddressSpace, 1);
|
||||
|
||||
address_space_init(as_normal, cs->memory, "cpu-memory");
|
||||
|
||||
cpu->cpu_as_mem = g_new(MemoryRegion, 1);
|
||||
cpu->cpu_as_root = g_new(MemoryRegion, 1);
|
||||
|
||||
|
|
|
@ -942,6 +942,7 @@ void nios2_tcg_init(void)
|
|||
int i;
|
||||
|
||||
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
|
||||
tcg_ctx.tcg_env = cpu_env;
|
||||
|
||||
for (i = 0; i < NUM_CORE_REGS; i++) {
|
||||
cpu_R[i] = tcg_global_mem_new(cpu_env,
|
||||
|
|
|
@ -141,7 +141,7 @@ void ppc_set_compat(PowerPCCPU *cpu, uint32_t compat_pvr, Error **errp)
|
|||
cpu_synchronize_state(CPU(cpu));
|
||||
|
||||
if (kvm_enabled() && cpu->compat_pvr != compat_pvr) {
|
||||
int ret = kvmppc_set_compat(cpu, cpu->compat_pvr);
|
||||
int ret = kvmppc_set_compat(cpu, compat_pvr);
|
||||
if (ret < 0) {
|
||||
error_setg_errno(errp, -ret,
|
||||
"Unable to set CPU compatibility mode in KVM");
|
||||
|
|
|
@ -527,7 +527,6 @@ static uint16_t default_GEN13_GA1[] = {
|
|||
#define default_GEN13_GA2 EmptyFeat
|
||||
|
||||
static uint16_t default_GEN14_GA1[] = {
|
||||
S390_FEAT_ADAPTER_INT_SUPPRESSION,
|
||||
S390_FEAT_INSTRUCTION_EXEC_PROT,
|
||||
S390_FEAT_GUARDED_STORAGE,
|
||||
S390_FEAT_VECTOR_PACKED_DECIMAL,
|
||||
|
|
|
@ -308,8 +308,13 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
|
|||
}
|
||||
}
|
||||
|
||||
/* Try to enable AIS facility */
|
||||
kvm_vm_enable_cap(s, KVM_CAP_S390_AIS, 0);
|
||||
/*
|
||||
* The migration interface for ais was introduced with kernel 4.13
|
||||
* but the capability itself had been active since 4.12. As migration
|
||||
* support is considered necessary let's disable ais in the 2.10
|
||||
* machine.
|
||||
*/
|
||||
/* kvm_vm_enable_cap(s, KVM_CAP_S390_AIS, 0); */
|
||||
|
||||
qemu_mutex_init(&qemu_sigp_mutex);
|
||||
|
||||
|
|
|
@ -117,15 +117,15 @@ _export_nbd_snapshot sn1
|
|||
|
||||
echo
|
||||
echo "== verifying the exported snapshot with patterns, method 1 =="
|
||||
$QEMU_IO_NBD -c 'read -P 0xa 0x1000 0x1000' "$nbd_snapshot_img" | _filter_qemu_io
|
||||
$QEMU_IO_NBD -c 'read -P 0xb 0x2000 0x1000' "$nbd_snapshot_img" | _filter_qemu_io
|
||||
$QEMU_IO_NBD -r -c 'read -P 0xa 0x1000 0x1000' "$nbd_snapshot_img" | _filter_qemu_io
|
||||
$QEMU_IO_NBD -r -c 'read -P 0xb 0x2000 0x1000' "$nbd_snapshot_img" | _filter_qemu_io
|
||||
|
||||
_export_nbd_snapshot1 sn1
|
||||
|
||||
echo
|
||||
echo "== verifying the exported snapshot with patterns, method 2 =="
|
||||
$QEMU_IO_NBD -c 'read -P 0xa 0x1000 0x1000' "$nbd_snapshot_img" | _filter_qemu_io
|
||||
$QEMU_IO_NBD -c 'read -P 0xb 0x2000 0x1000' "$nbd_snapshot_img" | _filter_qemu_io
|
||||
$QEMU_IO_NBD -r -c 'read -P 0xa 0x1000 0x1000' "$nbd_snapshot_img" | _filter_qemu_io
|
||||
$QEMU_IO_NBD -r -c 'read -P 0xb 0x2000 0x1000' "$nbd_snapshot_img" | _filter_qemu_io
|
||||
|
||||
$QEMU_IMG convert "$TEST_IMG" -l sn1 -O qcow2 "$converted_image"
|
||||
|
||||
|
|
|
@ -69,13 +69,15 @@ fi
|
|||
# in B
|
||||
CREATION_SIZE=$((2 * 1024 * 1024 - 48 * 1024))
|
||||
|
||||
# 512 is the actual test -- but it's good to test 64k as well, just to be sure.
|
||||
for cluster_size in 512 64k; do
|
||||
# in kB
|
||||
for GROWTH_SIZE in 16 48 80; do
|
||||
for create_mode in off metadata falloc full; do
|
||||
for growth_mode in off metadata falloc full; do
|
||||
echo "--- growth_size=$GROWTH_SIZE create_mode=$create_mode growth_mode=$growth_mode ---"
|
||||
echo "--- cluster_size=$cluster_size growth_size=$GROWTH_SIZE create_mode=$create_mode growth_mode=$growth_mode ---"
|
||||
|
||||
IMGOPTS="preallocation=$create_mode,cluster_size=512" _make_test_img ${CREATION_SIZE}
|
||||
IMGOPTS="preallocation=$create_mode,cluster_size=$cluster_size" _make_test_img ${CREATION_SIZE}
|
||||
$QEMU_IMG resize -f "$IMGFMT" --preallocation=$growth_mode "$TEST_IMG" +${GROWTH_SIZE}K
|
||||
|
||||
host_size_0=$(get_image_size_on_host)
|
||||
|
@ -123,6 +125,7 @@ for GROWTH_SIZE in 16 48 80; do
|
|||
done
|
||||
done
|
||||
done
|
||||
done
|
||||
|
||||
# success, all done
|
||||
echo '*** done'
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
QA output created by 125
|
||||
--- growth_size=16 create_mode=off growth_mode=off ---
|
||||
--- cluster_size=512 growth_size=16 create_mode=off growth_mode=off ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -7,7 +7,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 16384/16384 bytes at offset 2048000
|
||||
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=16 create_mode=off growth_mode=metadata ---
|
||||
--- cluster_size=512 growth_size=16 create_mode=off growth_mode=metadata ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -15,7 +15,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 16384/16384 bytes at offset 2048000
|
||||
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=16 create_mode=off growth_mode=falloc ---
|
||||
--- cluster_size=512 growth_size=16 create_mode=off growth_mode=falloc ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -23,7 +23,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 16384/16384 bytes at offset 2048000
|
||||
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=16 create_mode=off growth_mode=full ---
|
||||
--- cluster_size=512 growth_size=16 create_mode=off growth_mode=full ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -31,7 +31,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 16384/16384 bytes at offset 2048000
|
||||
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=16 create_mode=metadata growth_mode=off ---
|
||||
--- cluster_size=512 growth_size=16 create_mode=metadata growth_mode=off ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -39,7 +39,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 16384/16384 bytes at offset 2048000
|
||||
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=16 create_mode=metadata growth_mode=metadata ---
|
||||
--- cluster_size=512 growth_size=16 create_mode=metadata growth_mode=metadata ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -47,7 +47,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 16384/16384 bytes at offset 2048000
|
||||
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=16 create_mode=metadata growth_mode=falloc ---
|
||||
--- cluster_size=512 growth_size=16 create_mode=metadata growth_mode=falloc ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -55,7 +55,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 16384/16384 bytes at offset 2048000
|
||||
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=16 create_mode=metadata growth_mode=full ---
|
||||
--- cluster_size=512 growth_size=16 create_mode=metadata growth_mode=full ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -63,7 +63,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 16384/16384 bytes at offset 2048000
|
||||
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=16 create_mode=falloc growth_mode=off ---
|
||||
--- cluster_size=512 growth_size=16 create_mode=falloc growth_mode=off ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -71,7 +71,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 16384/16384 bytes at offset 2048000
|
||||
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=16 create_mode=falloc growth_mode=metadata ---
|
||||
--- cluster_size=512 growth_size=16 create_mode=falloc growth_mode=metadata ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -79,7 +79,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 16384/16384 bytes at offset 2048000
|
||||
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=16 create_mode=falloc growth_mode=falloc ---
|
||||
--- cluster_size=512 growth_size=16 create_mode=falloc growth_mode=falloc ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -87,7 +87,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 16384/16384 bytes at offset 2048000
|
||||
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=16 create_mode=falloc growth_mode=full ---
|
||||
--- cluster_size=512 growth_size=16 create_mode=falloc growth_mode=full ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -95,7 +95,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 16384/16384 bytes at offset 2048000
|
||||
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=16 create_mode=full growth_mode=off ---
|
||||
--- cluster_size=512 growth_size=16 create_mode=full growth_mode=off ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -103,7 +103,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 16384/16384 bytes at offset 2048000
|
||||
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=16 create_mode=full growth_mode=metadata ---
|
||||
--- cluster_size=512 growth_size=16 create_mode=full growth_mode=metadata ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -111,7 +111,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 16384/16384 bytes at offset 2048000
|
||||
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=16 create_mode=full growth_mode=falloc ---
|
||||
--- cluster_size=512 growth_size=16 create_mode=full growth_mode=falloc ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -119,7 +119,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 16384/16384 bytes at offset 2048000
|
||||
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=16 create_mode=full growth_mode=full ---
|
||||
--- cluster_size=512 growth_size=16 create_mode=full growth_mode=full ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -127,7 +127,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 16384/16384 bytes at offset 2048000
|
||||
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=48 create_mode=off growth_mode=off ---
|
||||
--- cluster_size=512 growth_size=48 create_mode=off growth_mode=off ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -135,7 +135,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 49152/49152 bytes at offset 2048000
|
||||
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=48 create_mode=off growth_mode=metadata ---
|
||||
--- cluster_size=512 growth_size=48 create_mode=off growth_mode=metadata ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -143,7 +143,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 49152/49152 bytes at offset 2048000
|
||||
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=48 create_mode=off growth_mode=falloc ---
|
||||
--- cluster_size=512 growth_size=48 create_mode=off growth_mode=falloc ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -151,7 +151,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 49152/49152 bytes at offset 2048000
|
||||
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=48 create_mode=off growth_mode=full ---
|
||||
--- cluster_size=512 growth_size=48 create_mode=off growth_mode=full ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -159,7 +159,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 49152/49152 bytes at offset 2048000
|
||||
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=48 create_mode=metadata growth_mode=off ---
|
||||
--- cluster_size=512 growth_size=48 create_mode=metadata growth_mode=off ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -167,7 +167,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 49152/49152 bytes at offset 2048000
|
||||
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=48 create_mode=metadata growth_mode=metadata ---
|
||||
--- cluster_size=512 growth_size=48 create_mode=metadata growth_mode=metadata ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -175,7 +175,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 49152/49152 bytes at offset 2048000
|
||||
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=48 create_mode=metadata growth_mode=falloc ---
|
||||
--- cluster_size=512 growth_size=48 create_mode=metadata growth_mode=falloc ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -183,7 +183,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 49152/49152 bytes at offset 2048000
|
||||
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=48 create_mode=metadata growth_mode=full ---
|
||||
--- cluster_size=512 growth_size=48 create_mode=metadata growth_mode=full ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -191,7 +191,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 49152/49152 bytes at offset 2048000
|
||||
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=48 create_mode=falloc growth_mode=off ---
|
||||
--- cluster_size=512 growth_size=48 create_mode=falloc growth_mode=off ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -199,7 +199,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 49152/49152 bytes at offset 2048000
|
||||
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=48 create_mode=falloc growth_mode=metadata ---
|
||||
--- cluster_size=512 growth_size=48 create_mode=falloc growth_mode=metadata ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -207,7 +207,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 49152/49152 bytes at offset 2048000
|
||||
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=48 create_mode=falloc growth_mode=falloc ---
|
||||
--- cluster_size=512 growth_size=48 create_mode=falloc growth_mode=falloc ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -215,7 +215,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 49152/49152 bytes at offset 2048000
|
||||
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=48 create_mode=falloc growth_mode=full ---
|
||||
--- cluster_size=512 growth_size=48 create_mode=falloc growth_mode=full ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -223,7 +223,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 49152/49152 bytes at offset 2048000
|
||||
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=48 create_mode=full growth_mode=off ---
|
||||
--- cluster_size=512 growth_size=48 create_mode=full growth_mode=off ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -231,7 +231,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 49152/49152 bytes at offset 2048000
|
||||
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=48 create_mode=full growth_mode=metadata ---
|
||||
--- cluster_size=512 growth_size=48 create_mode=full growth_mode=metadata ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -239,7 +239,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 49152/49152 bytes at offset 2048000
|
||||
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=48 create_mode=full growth_mode=falloc ---
|
||||
--- cluster_size=512 growth_size=48 create_mode=full growth_mode=falloc ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -247,7 +247,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 49152/49152 bytes at offset 2048000
|
||||
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=48 create_mode=full growth_mode=full ---
|
||||
--- cluster_size=512 growth_size=48 create_mode=full growth_mode=full ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -255,7 +255,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 49152/49152 bytes at offset 2048000
|
||||
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=80 create_mode=off growth_mode=off ---
|
||||
--- cluster_size=512 growth_size=80 create_mode=off growth_mode=off ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -263,7 +263,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 81920/81920 bytes at offset 2048000
|
||||
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=80 create_mode=off growth_mode=metadata ---
|
||||
--- cluster_size=512 growth_size=80 create_mode=off growth_mode=metadata ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -271,7 +271,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 81920/81920 bytes at offset 2048000
|
||||
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=80 create_mode=off growth_mode=falloc ---
|
||||
--- cluster_size=512 growth_size=80 create_mode=off growth_mode=falloc ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -279,7 +279,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 81920/81920 bytes at offset 2048000
|
||||
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=80 create_mode=off growth_mode=full ---
|
||||
--- cluster_size=512 growth_size=80 create_mode=off growth_mode=full ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -287,7 +287,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 81920/81920 bytes at offset 2048000
|
||||
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=80 create_mode=metadata growth_mode=off ---
|
||||
--- cluster_size=512 growth_size=80 create_mode=metadata growth_mode=off ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -295,7 +295,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 81920/81920 bytes at offset 2048000
|
||||
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=80 create_mode=metadata growth_mode=metadata ---
|
||||
--- cluster_size=512 growth_size=80 create_mode=metadata growth_mode=metadata ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -303,7 +303,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 81920/81920 bytes at offset 2048000
|
||||
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=80 create_mode=metadata growth_mode=falloc ---
|
||||
--- cluster_size=512 growth_size=80 create_mode=metadata growth_mode=falloc ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -311,7 +311,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 81920/81920 bytes at offset 2048000
|
||||
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=80 create_mode=metadata growth_mode=full ---
|
||||
--- cluster_size=512 growth_size=80 create_mode=metadata growth_mode=full ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -319,7 +319,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 81920/81920 bytes at offset 2048000
|
||||
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=80 create_mode=falloc growth_mode=off ---
|
||||
--- cluster_size=512 growth_size=80 create_mode=falloc growth_mode=off ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -327,7 +327,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 81920/81920 bytes at offset 2048000
|
||||
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=80 create_mode=falloc growth_mode=metadata ---
|
||||
--- cluster_size=512 growth_size=80 create_mode=falloc growth_mode=metadata ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -335,7 +335,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 81920/81920 bytes at offset 2048000
|
||||
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=80 create_mode=falloc growth_mode=falloc ---
|
||||
--- cluster_size=512 growth_size=80 create_mode=falloc growth_mode=falloc ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -343,7 +343,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 81920/81920 bytes at offset 2048000
|
||||
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=80 create_mode=falloc growth_mode=full ---
|
||||
--- cluster_size=512 growth_size=80 create_mode=falloc growth_mode=full ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -351,7 +351,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 81920/81920 bytes at offset 2048000
|
||||
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=80 create_mode=full growth_mode=off ---
|
||||
--- cluster_size=512 growth_size=80 create_mode=full growth_mode=off ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -359,7 +359,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 81920/81920 bytes at offset 2048000
|
||||
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=80 create_mode=full growth_mode=metadata ---
|
||||
--- cluster_size=512 growth_size=80 create_mode=full growth_mode=metadata ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -367,7 +367,7 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 81920/81920 bytes at offset 2048000
|
||||
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=80 create_mode=full growth_mode=falloc ---
|
||||
--- cluster_size=512 growth_size=80 create_mode=full growth_mode=falloc ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
@ -375,7 +375,391 @@ wrote 2048000/2048000 bytes at offset 0
|
|||
wrote 81920/81920 bytes at offset 2048000
|
||||
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- growth_size=80 create_mode=full growth_mode=full ---
|
||||
--- cluster_size=512 growth_size=80 create_mode=full growth_mode=full ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 81920/81920 bytes at offset 2048000
|
||||
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=16 create_mode=off growth_mode=off ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 16384/16384 bytes at offset 2048000
|
||||
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=16 create_mode=off growth_mode=metadata ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 16384/16384 bytes at offset 2048000
|
||||
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=16 create_mode=off growth_mode=falloc ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 16384/16384 bytes at offset 2048000
|
||||
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=16 create_mode=off growth_mode=full ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 16384/16384 bytes at offset 2048000
|
||||
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=16 create_mode=metadata growth_mode=off ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 16384/16384 bytes at offset 2048000
|
||||
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=16 create_mode=metadata growth_mode=metadata ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 16384/16384 bytes at offset 2048000
|
||||
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=16 create_mode=metadata growth_mode=falloc ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 16384/16384 bytes at offset 2048000
|
||||
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=16 create_mode=metadata growth_mode=full ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 16384/16384 bytes at offset 2048000
|
||||
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=16 create_mode=falloc growth_mode=off ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 16384/16384 bytes at offset 2048000
|
||||
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=16 create_mode=falloc growth_mode=metadata ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 16384/16384 bytes at offset 2048000
|
||||
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=16 create_mode=falloc growth_mode=falloc ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 16384/16384 bytes at offset 2048000
|
||||
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=16 create_mode=falloc growth_mode=full ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 16384/16384 bytes at offset 2048000
|
||||
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=16 create_mode=full growth_mode=off ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 16384/16384 bytes at offset 2048000
|
||||
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=16 create_mode=full growth_mode=metadata ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 16384/16384 bytes at offset 2048000
|
||||
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=16 create_mode=full growth_mode=falloc ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 16384/16384 bytes at offset 2048000
|
||||
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=16 create_mode=full growth_mode=full ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 16384/16384 bytes at offset 2048000
|
||||
16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=48 create_mode=off growth_mode=off ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 49152/49152 bytes at offset 2048000
|
||||
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=48 create_mode=off growth_mode=metadata ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 49152/49152 bytes at offset 2048000
|
||||
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=48 create_mode=off growth_mode=falloc ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 49152/49152 bytes at offset 2048000
|
||||
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=48 create_mode=off growth_mode=full ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 49152/49152 bytes at offset 2048000
|
||||
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=48 create_mode=metadata growth_mode=off ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 49152/49152 bytes at offset 2048000
|
||||
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=48 create_mode=metadata growth_mode=metadata ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 49152/49152 bytes at offset 2048000
|
||||
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=48 create_mode=metadata growth_mode=falloc ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 49152/49152 bytes at offset 2048000
|
||||
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=48 create_mode=metadata growth_mode=full ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 49152/49152 bytes at offset 2048000
|
||||
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=48 create_mode=falloc growth_mode=off ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 49152/49152 bytes at offset 2048000
|
||||
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=48 create_mode=falloc growth_mode=metadata ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 49152/49152 bytes at offset 2048000
|
||||
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=48 create_mode=falloc growth_mode=falloc ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 49152/49152 bytes at offset 2048000
|
||||
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=48 create_mode=falloc growth_mode=full ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 49152/49152 bytes at offset 2048000
|
||||
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=48 create_mode=full growth_mode=off ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 49152/49152 bytes at offset 2048000
|
||||
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=48 create_mode=full growth_mode=metadata ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 49152/49152 bytes at offset 2048000
|
||||
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=48 create_mode=full growth_mode=falloc ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 49152/49152 bytes at offset 2048000
|
||||
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=48 create_mode=full growth_mode=full ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 49152/49152 bytes at offset 2048000
|
||||
48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=80 create_mode=off growth_mode=off ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 81920/81920 bytes at offset 2048000
|
||||
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=80 create_mode=off growth_mode=metadata ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 81920/81920 bytes at offset 2048000
|
||||
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=80 create_mode=off growth_mode=falloc ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 81920/81920 bytes at offset 2048000
|
||||
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=80 create_mode=off growth_mode=full ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 81920/81920 bytes at offset 2048000
|
||||
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=80 create_mode=metadata growth_mode=off ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 81920/81920 bytes at offset 2048000
|
||||
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=80 create_mode=metadata growth_mode=metadata ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 81920/81920 bytes at offset 2048000
|
||||
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=80 create_mode=metadata growth_mode=falloc ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 81920/81920 bytes at offset 2048000
|
||||
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=80 create_mode=metadata growth_mode=full ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 81920/81920 bytes at offset 2048000
|
||||
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=80 create_mode=falloc growth_mode=off ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 81920/81920 bytes at offset 2048000
|
||||
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=80 create_mode=falloc growth_mode=metadata ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 81920/81920 bytes at offset 2048000
|
||||
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=80 create_mode=falloc growth_mode=falloc ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 81920/81920 bytes at offset 2048000
|
||||
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=80 create_mode=falloc growth_mode=full ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 81920/81920 bytes at offset 2048000
|
||||
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=80 create_mode=full growth_mode=off ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 81920/81920 bytes at offset 2048000
|
||||
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=80 create_mode=full growth_mode=metadata ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 81920/81920 bytes at offset 2048000
|
||||
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=80 create_mode=full growth_mode=falloc ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 81920/81920 bytes at offset 2048000
|
||||
80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
--- cluster_size=64k growth_size=80 create_mode=full growth_mode=full ---
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
|
||||
Image resized.
|
||||
wrote 2048000/2048000 bytes at offset 0
|
||||
|
|
|
@ -78,7 +78,7 @@ _send_qemu_cmd $QEMU_HANDLE \
|
|||
'arguments': { 'device': 'drv' }}" \
|
||||
'return'
|
||||
|
||||
$QEMU_IO_PROG -f raw -c 'read -P 42 0 64k' \
|
||||
$QEMU_IO_PROG -f raw -r -c 'read -P 42 0 64k' \
|
||||
"nbd+unix:///drv?socket=$TEST_DIR/nbd" 2>&1 \
|
||||
| _filter_qemu_io | _filter_nbd
|
||||
|
||||
|
@ -87,7 +87,7 @@ _send_qemu_cmd $QEMU_HANDLE \
|
|||
'arguments': { 'device': 'drv' }}" \
|
||||
'return'
|
||||
|
||||
$QEMU_IO_PROG -f raw -c close \
|
||||
$QEMU_IO_PROG -f raw -r -c close \
|
||||
"nbd+unix:///drv?socket=$TEST_DIR/nbd" 2>&1 \
|
||||
| _filter_qemu_io | _filter_nbd
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ class NBDBlockdevAddBase(iotests.QMPTestCase):
|
|||
'driver': 'raw',
|
||||
'file': {
|
||||
'driver': 'nbd',
|
||||
'read-only': True,
|
||||
'server': address
|
||||
} }
|
||||
if export is not None:
|
||||
|
|
|
@ -466,11 +466,18 @@ vubr_panic(VuDev *dev, const char *msg)
|
|||
vubr->quit = 1;
|
||||
}
|
||||
|
||||
static bool
|
||||
vubr_queue_is_processed_in_order(VuDev *dev, int qidx)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static const VuDevIface vuiface = {
|
||||
.get_features = vubr_get_features,
|
||||
.set_features = vubr_set_features,
|
||||
.process_msg = vubr_process_msg,
|
||||
.queue_set_started = vubr_queue_set_started,
|
||||
.queue_is_processed_in_order = vubr_queue_is_processed_in_order,
|
||||
};
|
||||
|
||||
static void
|
||||
|
|
|
@ -64,6 +64,9 @@ memory_region_tb_read(int cpu_index, uint64_t addr, uint64_t value, unsigned siz
|
|||
memory_region_tb_write(int cpu_index, uint64_t addr, uint64_t value, unsigned size) "cpu %d addr 0x%"PRIx64" value 0x%"PRIx64" size %u"
|
||||
memory_region_ram_device_read(int cpu_index, void *mr, uint64_t addr, uint64_t value, unsigned size) "cpu %d mr %p addr 0x%"PRIx64" value 0x%"PRIx64" size %u"
|
||||
memory_region_ram_device_write(int cpu_index, void *mr, uint64_t addr, uint64_t value, unsigned size) "cpu %d mr %p addr 0x%"PRIx64" value 0x%"PRIx64" size %u"
|
||||
flatview_new(FlatView *view, MemoryRegion *root) "%p (root %p)"
|
||||
flatview_destroy(FlatView *view, MemoryRegion *root) "%p (root %p)"
|
||||
flatview_destroy_rcu(FlatView *view, MemoryRegion *root) "%p (root %p)"
|
||||
|
||||
### Guest events, keep at bottom
|
||||
|
||||
|
|
|
@ -1540,7 +1540,7 @@ void dpy_gfx_replace_surface(QemuConsole *con,
|
|||
DisplaySurface *old_surface = con->surface;
|
||||
DisplayChangeListener *dcl;
|
||||
|
||||
assert(old_surface != surface);
|
||||
assert(old_surface != surface || surface == NULL);
|
||||
|
||||
con->surface = surface;
|
||||
QLIST_FOREACH(dcl, &s->listeners, next) {
|
||||
|
|
|
@ -91,7 +91,7 @@ bool stat64_min_slow(Stat64 *s, uint64_t value)
|
|||
low = atomic_read(&s->low);
|
||||
|
||||
orig = ((uint64_t)high << 32) | low;
|
||||
if (orig < value) {
|
||||
if (value < orig) {
|
||||
/* We have to set low before high, just like stat64_min reads
|
||||
* high before low. The value may become higher temporarily, but
|
||||
* stat64_get does not notice (it takes the lock) and the only ill
|
||||
|
@ -120,7 +120,7 @@ bool stat64_max_slow(Stat64 *s, uint64_t value)
|
|||
low = atomic_read(&s->low);
|
||||
|
||||
orig = ((uint64_t)high << 32) | low;
|
||||
if (orig > value) {
|
||||
if (value > orig) {
|
||||
/* We have to set low before high, just like stat64_max reads
|
||||
* high before low. The value may become lower temporarily, but
|
||||
* stat64_get does not notice (it takes the lock) and the only ill
|
||||
|
|
16
vl.c
16
vl.c
|
@ -3557,7 +3557,7 @@ int main(int argc, char **argv, char **envp)
|
|||
case QEMU_OPTION_virtfs: {
|
||||
QemuOpts *fsdev;
|
||||
QemuOpts *device;
|
||||
const char *writeout, *sock_fd, *socket;
|
||||
const char *writeout, *sock_fd, *socket, *path, *security_model;
|
||||
|
||||
olist = qemu_find_opts("virtfs");
|
||||
if (!olist) {
|
||||
|
@ -3596,11 +3596,15 @@ int main(int argc, char **argv, char **envp)
|
|||
}
|
||||
qemu_opt_set(fsdev, "fsdriver",
|
||||
qemu_opt_get(opts, "fsdriver"), &error_abort);
|
||||
qemu_opt_set(fsdev, "path", qemu_opt_get(opts, "path"),
|
||||
&error_abort);
|
||||
qemu_opt_set(fsdev, "security_model",
|
||||
qemu_opt_get(opts, "security_model"),
|
||||
&error_abort);
|
||||
path = qemu_opt_get(opts, "path");
|
||||
if (path) {
|
||||
qemu_opt_set(fsdev, "path", path, &error_abort);
|
||||
}
|
||||
security_model = qemu_opt_get(opts, "security_model");
|
||||
if (security_model) {
|
||||
qemu_opt_set(fsdev, "security_model", security_model,
|
||||
&error_abort);
|
||||
}
|
||||
socket = qemu_opt_get(opts, "socket");
|
||||
if (socket) {
|
||||
qemu_opt_set(fsdev, "socket", socket, &error_abort);
|
||||
|
|
Loading…
Reference in New Issue