Compare commits
105
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0d83fccb4f | ||
|
|
4dde694191 | ||
|
|
7d17d68971 | ||
|
|
345f1cd9f6 | ||
|
|
8d5f2a7570 | ||
|
|
5f20161cf3 | ||
|
|
05838b4688 | ||
|
|
223d1a2da1 | ||
|
|
7f7ac2141e | ||
|
|
db1604cd60 | ||
|
|
cc1fd25295 | ||
|
|
ee99e42be4 | ||
|
|
0ef167c907 | ||
|
|
248a780fd3 | ||
|
|
80f630be21 | ||
|
|
353801cde4 | ||
|
|
c8a3159df4 | ||
|
|
48fdfebab6 | ||
|
|
6eb194ddd7 | ||
|
|
7e278ef797 | ||
|
|
6a5ea68e9e | ||
|
|
31454ebde5 | ||
|
|
5e4eb851dd | ||
|
|
dd11d33deb | ||
|
|
c4bf37e0b0 | ||
|
|
e9dbd28e2a | ||
|
|
92230a5963 | ||
|
|
48b3aa20ae | ||
|
|
f1372d6e14 | ||
|
|
63087cd74b | ||
|
|
9df69dcd14 | ||
|
|
95a0638043 | ||
|
|
1790a9d77d | ||
|
|
1b16ded6a5 | ||
|
|
ca83f87a66 | ||
|
|
2817466c55 | ||
|
|
e389e44a35 | ||
|
|
b1fdc94193 | ||
|
|
61781984db | ||
|
|
857efecf91 | ||
|
|
99837b0d36 | ||
|
|
b34c7bd463 | ||
|
|
f3467f56c1 | ||
|
|
5be5335661 | ||
|
|
af29bd3193 | ||
|
|
f72ca1ac6f | ||
|
|
4d45fe11d1 | ||
|
|
4a25ab2a04 | ||
|
|
95200ebb50 | ||
|
|
8e94512568 | ||
|
|
d40d148feb | ||
|
|
f9856029d5 | ||
|
|
a3a254550b | ||
|
|
533dedf059 | ||
|
|
54c26b7340 | ||
|
|
f5436d1dab | ||
|
|
3550eeafcd | ||
|
|
316c2c9448 | ||
|
|
98b4465f7d | ||
|
|
8342e1240b | ||
|
|
0b6ab25367 | ||
|
|
742886578d | ||
|
|
2f8e8c7396 | ||
|
|
069e885d83 | ||
|
|
bfb15f77bb | ||
|
|
c6a7b922f8 | ||
|
|
d06c61f310 | ||
|
|
91a2f46297 | ||
|
|
520d4b288f | ||
|
|
4b6542dd17 | ||
|
|
c1a77fd6fa | ||
|
|
2e68f28854 | ||
|
|
45a4f18e2e | ||
|
|
5c17966605 | ||
|
|
6ff3ab0d6b | ||
|
|
1dc33ed90b | ||
|
|
12d2c4184c | ||
|
|
56f101ecce | ||
|
|
805b5d98c6 | ||
|
|
fff39a7ad0 | ||
|
|
2b294f6b65 | ||
|
|
336d5881a9 | ||
|
|
616018352c | ||
|
|
135a972b45 | ||
|
|
b69a553b4a | ||
|
|
e00da552a0 | ||
|
|
8c1c230a6e | ||
|
|
58a83c6149 | ||
|
|
bccdef6b1a | ||
|
|
d75aa4372f | ||
|
|
62680fad7f | ||
|
|
e0af5a0e8b | ||
|
|
67f3280c06 | ||
|
|
5f9f818ea8 | ||
|
|
5045570009 | ||
|
|
60c6b790fc | ||
|
|
aee5f8f98e | ||
|
|
02b1ad881c | ||
|
|
156af3ac98 | ||
|
|
ce83ee57f6 | ||
|
|
5844365fe8 | ||
|
|
4b887ae658 | ||
|
|
e9e0a5854b | ||
|
|
47882fa497 | ||
|
|
92b6a16087 |
No files matched your search
+3
-1
@@ -139,7 +139,6 @@ static void msmouse_chr_close (struct CharDriverState *chr)
|
||||
|
||||
qemu_input_handler_unregister(mouse->hs);
|
||||
g_free(mouse);
|
||||
g_free(chr);
|
||||
}
|
||||
|
||||
static QemuInputHandler msmouse_handler = {
|
||||
@@ -159,6 +158,9 @@ static CharDriverState *qemu_chr_open_msmouse(const char *id,
|
||||
CharDriverState *chr;
|
||||
|
||||
chr = qemu_chr_alloc(common, errp);
|
||||
if (!chr) {
|
||||
return NULL;
|
||||
}
|
||||
chr->chr_write = msmouse_chr_write;
|
||||
chr->chr_close = msmouse_chr_close;
|
||||
chr->chr_accept_input = msmouse_chr_accept_input;
|
||||
|
||||
+5
-22
@@ -1296,6 +1296,11 @@ void blk_eject(BlockBackend *blk, bool eject_flag)
|
||||
if (bs) {
|
||||
bdrv_eject(bs, eject_flag);
|
||||
}
|
||||
|
||||
/* Whether or not we ejected on the backend,
|
||||
* the frontend experienced a tray event. */
|
||||
qapi_event_send_device_tray_moved(blk_name(blk),
|
||||
eject_flag, &error_abort);
|
||||
}
|
||||
|
||||
int blk_get_flags(BlockBackend *blk)
|
||||
@@ -1624,28 +1629,6 @@ int blk_commit_all(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int blk_flush_all(void)
|
||||
{
|
||||
BlockBackend *blk = NULL;
|
||||
int result = 0;
|
||||
|
||||
while ((blk = blk_all_next(blk)) != NULL) {
|
||||
AioContext *aio_context = blk_get_aio_context(blk);
|
||||
int ret;
|
||||
|
||||
aio_context_acquire(aio_context);
|
||||
if (blk_is_inserted(blk)) {
|
||||
ret = blk_flush(blk);
|
||||
if (ret < 0 && !result) {
|
||||
result = ret;
|
||||
}
|
||||
}
|
||||
aio_context_release(aio_context);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* throttling disk I/O limits */
|
||||
void blk_set_io_limits(BlockBackend *blk, ThrottleConfig *cfg)
|
||||
|
||||
+76
-25
@@ -73,7 +73,6 @@ static CURLMcode __curl_multi_socket_action(CURLM *multi_handle,
|
||||
|
||||
#define CURL_NUM_STATES 8
|
||||
#define CURL_NUM_ACB 8
|
||||
#define SECTOR_SIZE 512
|
||||
#define READ_AHEAD_DEFAULT (256 * 1024)
|
||||
#define CURL_TIMEOUT_DEFAULT 5
|
||||
#define CURL_TIMEOUT_MAX 10000
|
||||
@@ -106,12 +105,17 @@ typedef struct CURLAIOCB {
|
||||
size_t end;
|
||||
} CURLAIOCB;
|
||||
|
||||
typedef struct CURLSocket {
|
||||
int fd;
|
||||
QLIST_ENTRY(CURLSocket) next;
|
||||
} CURLSocket;
|
||||
|
||||
typedef struct CURLState
|
||||
{
|
||||
struct BDRVCURLState *s;
|
||||
CURLAIOCB *acb[CURL_NUM_ACB];
|
||||
CURL *curl;
|
||||
curl_socket_t sock_fd;
|
||||
QLIST_HEAD(, CURLSocket) sockets;
|
||||
char *orig_buf;
|
||||
size_t buf_start;
|
||||
size_t buf_off;
|
||||
@@ -165,11 +169,28 @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
|
||||
{
|
||||
BDRVCURLState *s;
|
||||
CURLState *state = NULL;
|
||||
CURLSocket *socket;
|
||||
|
||||
curl_easy_getinfo(curl, CURLINFO_PRIVATE, (char **)&state);
|
||||
state->sock_fd = fd;
|
||||
s = state->s;
|
||||
|
||||
DPRINTF("CURL (AIO): Sock action %d on fd %d\n", action, fd);
|
||||
QLIST_FOREACH(socket, &state->sockets, next) {
|
||||
if (socket->fd == fd) {
|
||||
if (action == CURL_POLL_REMOVE) {
|
||||
QLIST_REMOVE(socket, next);
|
||||
g_free(socket);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!socket) {
|
||||
socket = g_new0(CURLSocket, 1);
|
||||
socket->fd = fd;
|
||||
QLIST_INSERT_HEAD(&state->sockets, socket, next);
|
||||
}
|
||||
socket = NULL;
|
||||
|
||||
DPRINTF("CURL (AIO): Sock action %d on fd %d\n", action, (int)fd);
|
||||
switch (action) {
|
||||
case CURL_POLL_IN:
|
||||
aio_set_fd_handler(s->aio_context, fd, false,
|
||||
@@ -214,12 +235,13 @@ static size_t curl_read_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
|
||||
|
||||
DPRINTF("CURL: Just reading %zd bytes\n", realsize);
|
||||
|
||||
if (!s || !s->orig_buf)
|
||||
return 0;
|
||||
if (!s || !s->orig_buf) {
|
||||
goto read_end;
|
||||
}
|
||||
|
||||
if (s->buf_off >= s->buf_len) {
|
||||
/* buffer full, read nothing */
|
||||
return 0;
|
||||
goto read_end;
|
||||
}
|
||||
realsize = MIN(realsize, s->buf_len - s->buf_off);
|
||||
memcpy(s->orig_buf + s->buf_off, ptr, realsize);
|
||||
@@ -232,15 +254,26 @@ static size_t curl_read_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
|
||||
continue;
|
||||
|
||||
if ((s->buf_off >= acb->end)) {
|
||||
size_t request_length = acb->nb_sectors * BDRV_SECTOR_SIZE;
|
||||
|
||||
qemu_iovec_from_buf(acb->qiov, 0, s->orig_buf + acb->start,
|
||||
acb->end - acb->start);
|
||||
|
||||
if (acb->end - acb->start < request_length) {
|
||||
size_t offset = acb->end - acb->start;
|
||||
qemu_iovec_memset(acb->qiov, offset, 0,
|
||||
request_length - offset);
|
||||
}
|
||||
|
||||
acb->common.cb(acb->common.opaque, 0);
|
||||
qemu_aio_unref(acb);
|
||||
s->acb[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return realsize;
|
||||
read_end:
|
||||
/* curl will error out if we do not return this value */
|
||||
return size * nmemb;
|
||||
}
|
||||
|
||||
static int curl_find_buf(BDRVCURLState *s, size_t start, size_t len,
|
||||
@@ -248,6 +281,8 @@ static int curl_find_buf(BDRVCURLState *s, size_t start, size_t len,
|
||||
{
|
||||
int i;
|
||||
size_t end = start + len;
|
||||
size_t clamped_end = MIN(end, s->len);
|
||||
size_t clamped_len = clamped_end - start;
|
||||
|
||||
for (i=0; i<CURL_NUM_STATES; i++) {
|
||||
CURLState *state = &s->states[i];
|
||||
@@ -262,12 +297,15 @@ static int curl_find_buf(BDRVCURLState *s, size_t start, size_t len,
|
||||
// Does the existing buffer cover our section?
|
||||
if ((start >= state->buf_start) &&
|
||||
(start <= buf_end) &&
|
||||
(end >= state->buf_start) &&
|
||||
(end <= buf_end))
|
||||
(clamped_end >= state->buf_start) &&
|
||||
(clamped_end <= buf_end))
|
||||
{
|
||||
char *buf = state->orig_buf + (start - state->buf_start);
|
||||
|
||||
qemu_iovec_from_buf(acb->qiov, 0, buf, len);
|
||||
qemu_iovec_from_buf(acb->qiov, 0, buf, clamped_len);
|
||||
if (clamped_len < len) {
|
||||
qemu_iovec_memset(acb->qiov, clamped_len, 0, len - clamped_len);
|
||||
}
|
||||
acb->common.cb(acb->common.opaque, 0);
|
||||
|
||||
return FIND_RET_OK;
|
||||
@@ -277,13 +315,13 @@ static int curl_find_buf(BDRVCURLState *s, size_t start, size_t len,
|
||||
if (state->in_use &&
|
||||
(start >= state->buf_start) &&
|
||||
(start <= buf_fend) &&
|
||||
(end >= state->buf_start) &&
|
||||
(end <= buf_fend))
|
||||
(clamped_end >= state->buf_start) &&
|
||||
(clamped_end <= buf_fend))
|
||||
{
|
||||
int j;
|
||||
|
||||
acb->start = start - state->buf_start;
|
||||
acb->end = acb->start + len;
|
||||
acb->end = acb->start + clamped_len;
|
||||
|
||||
for (j=0; j<CURL_NUM_ACB; j++) {
|
||||
if (!state->acb[j]) {
|
||||
@@ -353,6 +391,7 @@ static void curl_multi_check_completion(BDRVCURLState *s)
|
||||
static void curl_multi_do(void *arg)
|
||||
{
|
||||
CURLState *s = (CURLState *)arg;
|
||||
CURLSocket *socket, *next_socket;
|
||||
int running;
|
||||
int r;
|
||||
|
||||
@@ -360,10 +399,13 @@ static void curl_multi_do(void *arg)
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
r = curl_multi_socket_action(s->s->multi, s->sock_fd, 0, &running);
|
||||
} while(r == CURLM_CALL_MULTI_PERFORM);
|
||||
|
||||
/* Need to use _SAFE because curl_multi_socket_action() may trigger
|
||||
* curl_sock_cb() which might modify this list */
|
||||
QLIST_FOREACH_SAFE(socket, &s->sockets, next, next_socket) {
|
||||
do {
|
||||
r = curl_multi_socket_action(s->s->multi, socket->fd, 0, &running);
|
||||
} while (r == CURLM_CALL_MULTI_PERFORM);
|
||||
}
|
||||
}
|
||||
|
||||
static void curl_multi_read(void *arg)
|
||||
@@ -467,6 +509,7 @@ static CURLState *curl_init_state(BlockDriverState *bs, BDRVCURLState *s)
|
||||
#endif
|
||||
}
|
||||
|
||||
QLIST_INIT(&state->sockets);
|
||||
state->s = s;
|
||||
|
||||
return state;
|
||||
@@ -476,6 +519,14 @@ static void curl_clean_state(CURLState *s)
|
||||
{
|
||||
if (s->s->multi)
|
||||
curl_multi_remove_handle(s->s->multi, s->curl);
|
||||
|
||||
while (!QLIST_EMPTY(&s->sockets)) {
|
||||
CURLSocket *socket = QLIST_FIRST(&s->sockets);
|
||||
|
||||
QLIST_REMOVE(socket, next);
|
||||
g_free(socket);
|
||||
}
|
||||
|
||||
s->in_use = 0;
|
||||
}
|
||||
|
||||
@@ -725,12 +776,12 @@ static void curl_readv_bh_cb(void *p)
|
||||
qemu_bh_delete(acb->bh);
|
||||
acb->bh = NULL;
|
||||
|
||||
size_t start = acb->sector_num * SECTOR_SIZE;
|
||||
size_t start = acb->sector_num * BDRV_SECTOR_SIZE;
|
||||
size_t end;
|
||||
|
||||
// In case we have the requested data already (e.g. read-ahead),
|
||||
// we can just call the callback and be done.
|
||||
switch (curl_find_buf(s, start, acb->nb_sectors * SECTOR_SIZE, acb)) {
|
||||
switch (curl_find_buf(s, start, acb->nb_sectors * BDRV_SECTOR_SIZE, acb)) {
|
||||
case FIND_RET_OK:
|
||||
qemu_aio_unref(acb);
|
||||
// fall through
|
||||
@@ -749,13 +800,13 @@ static void curl_readv_bh_cb(void *p)
|
||||
}
|
||||
|
||||
acb->start = 0;
|
||||
acb->end = (acb->nb_sectors * SECTOR_SIZE);
|
||||
acb->end = MIN(acb->nb_sectors * BDRV_SECTOR_SIZE, s->len - start);
|
||||
|
||||
state->buf_off = 0;
|
||||
g_free(state->orig_buf);
|
||||
state->buf_start = start;
|
||||
state->buf_len = acb->end + s->readahead_size;
|
||||
end = MIN(start + state->buf_len, s->len) - 1;
|
||||
state->buf_len = MIN(acb->end + s->readahead_size, s->len - start);
|
||||
end = start + state->buf_len - 1;
|
||||
state->orig_buf = g_try_malloc(state->buf_len);
|
||||
if (state->buf_len && state->orig_buf == NULL) {
|
||||
curl_clean_state(state);
|
||||
@@ -766,8 +817,8 @@ static void curl_readv_bh_cb(void *p)
|
||||
state->acb[0] = acb;
|
||||
|
||||
snprintf(state->range, 127, "%zd-%zd", start, end);
|
||||
DPRINTF("CURL (AIO): Reading %d at %zd (%s)\n",
|
||||
(acb->nb_sectors * SECTOR_SIZE), start, state->range);
|
||||
DPRINTF("CURL (AIO): Reading %llu at %zd (%s)\n",
|
||||
(acb->nb_sectors * BDRV_SECTOR_SIZE), start, state->range);
|
||||
curl_easy_setopt(state->curl, CURLOPT_RANGE, state->range);
|
||||
|
||||
curl_multi_add_handle(s->multi, state->curl);
|
||||
|
||||
+73
-22
@@ -1179,6 +1179,8 @@ 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);
|
||||
|
||||
assert(alignment % bs->bl.request_alignment == 0);
|
||||
head = offset % alignment;
|
||||
@@ -1194,9 +1196,12 @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
|
||||
* boundaries.
|
||||
*/
|
||||
if (head) {
|
||||
/* Make a small request up to the first aligned sector. */
|
||||
num = MIN(count, alignment - head);
|
||||
head = 0;
|
||||
/* Make a small request up to the first aligned sector. For
|
||||
* convenience, limit this request to max_transfer even if
|
||||
* we don't need to fall back to writes. */
|
||||
num = MIN(MIN(count, max_transfer), alignment - head);
|
||||
head = (head + num) % alignment;
|
||||
assert(num < max_write_zeroes);
|
||||
} else if (tail && num > alignment) {
|
||||
/* Shorten the request to the last aligned sector. */
|
||||
num -= tail;
|
||||
@@ -1222,8 +1227,6 @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
|
||||
|
||||
if (ret == -ENOTSUP) {
|
||||
/* Fall back to bounce buffer if write zeroes is unsupported */
|
||||
int max_transfer = MIN_NON_ZERO(bs->bl.max_transfer,
|
||||
MAX_WRITE_ZEROES_BOUNCE_BUFFER);
|
||||
BdrvRequestFlags write_flags = flags & ~BDRV_REQ_ZERO_WRITE;
|
||||
|
||||
if ((flags & BDRV_REQ_FUA) &&
|
||||
@@ -1615,6 +1618,31 @@ int coroutine_fn bdrv_co_pwrite_zeroes(BdrvChild *child, int64_t offset,
|
||||
BDRV_REQ_ZERO_WRITE | flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* Flush ALL BDSes regardless of if they are reachable via a BlkBackend or not.
|
||||
*/
|
||||
int bdrv_flush_all(void)
|
||||
{
|
||||
BdrvNextIterator it;
|
||||
BlockDriverState *bs = NULL;
|
||||
int result = 0;
|
||||
|
||||
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
|
||||
AioContext *aio_context = bdrv_get_aio_context(bs);
|
||||
int ret;
|
||||
|
||||
aio_context_acquire(aio_context);
|
||||
ret = bdrv_flush(bs);
|
||||
if (ret < 0 && !result) {
|
||||
result = ret;
|
||||
}
|
||||
aio_context_release(aio_context);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
typedef struct BdrvCoGetBlockStatusData {
|
||||
BlockDriverState *bs;
|
||||
BlockDriverState *base;
|
||||
@@ -2283,11 +2311,11 @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
|
||||
int current_gen = bs->write_gen;
|
||||
|
||||
/* Wait until any previous flushes are completed */
|
||||
while (bs->flush_started_gen != bs->flushed_gen) {
|
||||
while (bs->active_flush_req != NULL) {
|
||||
qemu_co_queue_wait(&bs->flush_queue);
|
||||
}
|
||||
|
||||
bs->flush_started_gen = current_gen;
|
||||
bs->active_flush_req = &req;
|
||||
|
||||
/* Write back all layers by calling one driver function */
|
||||
if (bs->drv->bdrv_co_flush) {
|
||||
@@ -2356,8 +2384,12 @@ flush_parent:
|
||||
ret = bs->file ? bdrv_co_flush(bs->file->bs) : 0;
|
||||
out:
|
||||
/* Notify any pending flushes that we have completed */
|
||||
bs->flushed_gen = current_gen;
|
||||
qemu_co_queue_restart_all(&bs->flush_queue);
|
||||
if (ret == 0) {
|
||||
bs->flushed_gen = current_gen;
|
||||
}
|
||||
bs->active_flush_req = NULL;
|
||||
/* Return value is ignored - it's ok if wait queue is empty */
|
||||
qemu_co_queue_next(&bs->flush_queue);
|
||||
|
||||
tracked_request_end(&req);
|
||||
return ret;
|
||||
@@ -2405,7 +2437,7 @@ int coroutine_fn bdrv_co_pdiscard(BlockDriverState *bs, int64_t offset,
|
||||
{
|
||||
BdrvTrackedRequest req;
|
||||
int max_pdiscard, ret;
|
||||
int head, align;
|
||||
int head, tail, align;
|
||||
|
||||
if (!bs->drv) {
|
||||
return -ENOMEDIUM;
|
||||
@@ -2428,19 +2460,15 @@ int coroutine_fn bdrv_co_pdiscard(BlockDriverState *bs, int64_t offset,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Discard is advisory, so ignore any unaligned head or tail */
|
||||
/* Discard is advisory, but some devices track and coalesce
|
||||
* unaligned requests, so we must pass everything down rather than
|
||||
* round here. Still, most devices will just silently ignore
|
||||
* unaligned requests (by returning -ENOTSUP), so we must fragment
|
||||
* the request accordingly. */
|
||||
align = MAX(bs->bl.pdiscard_alignment, bs->bl.request_alignment);
|
||||
assert(align % bs->bl.request_alignment == 0);
|
||||
head = offset % align;
|
||||
if (head) {
|
||||
head = MIN(count, align - head);
|
||||
count -= head;
|
||||
offset += head;
|
||||
}
|
||||
count = QEMU_ALIGN_DOWN(count, align);
|
||||
if (!count) {
|
||||
return 0;
|
||||
}
|
||||
tail = (offset + count) % align;
|
||||
|
||||
tracked_request_begin(&req, bs, offset, count, BDRV_TRACKED_DISCARD);
|
||||
|
||||
@@ -2451,11 +2479,34 @@ int coroutine_fn bdrv_co_pdiscard(BlockDriverState *bs, int64_t offset,
|
||||
|
||||
max_pdiscard = QEMU_ALIGN_DOWN(MIN_NON_ZERO(bs->bl.max_pdiscard, INT_MAX),
|
||||
align);
|
||||
assert(max_pdiscard);
|
||||
assert(max_pdiscard >= bs->bl.request_alignment);
|
||||
|
||||
while (count > 0) {
|
||||
int ret;
|
||||
int num = MIN(count, max_pdiscard);
|
||||
int num = count;
|
||||
|
||||
if (head) {
|
||||
/* Make small requests to get to alignment boundaries. */
|
||||
num = MIN(count, align - head);
|
||||
if (!QEMU_IS_ALIGNED(num, bs->bl.request_alignment)) {
|
||||
num %= bs->bl.request_alignment;
|
||||
}
|
||||
head = (head + num) % align;
|
||||
assert(num < max_pdiscard);
|
||||
} else if (tail) {
|
||||
if (num > align) {
|
||||
/* Shorten the request to the last aligned cluster. */
|
||||
num -= tail;
|
||||
} else if (!QEMU_IS_ALIGNED(tail, bs->bl.request_alignment) &&
|
||||
tail > bs->bl.request_alignment) {
|
||||
tail %= bs->bl.request_alignment;
|
||||
num -= tail;
|
||||
}
|
||||
}
|
||||
/* limit request size */
|
||||
if (num > max_pdiscard) {
|
||||
num = max_pdiscard;
|
||||
}
|
||||
|
||||
if (bs->drv->bdrv_co_pdiscard) {
|
||||
ret = bs->drv->bdrv_co_pdiscard(bs, offset, num);
|
||||
|
||||
+11
-6
@@ -1048,7 +1048,9 @@ coroutine_fn iscsi_co_pdiscard(BlockDriverState *bs, int64_t offset, int count)
|
||||
struct IscsiTask iTask;
|
||||
struct unmap_list list;
|
||||
|
||||
assert(is_byte_request_lun_aligned(offset, count, iscsilun));
|
||||
if (!is_byte_request_lun_aligned(offset, count, iscsilun)) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (!iscsilun->lbp.lbpu) {
|
||||
/* UNMAP is not supported by the target */
|
||||
@@ -1813,19 +1815,22 @@ static void iscsi_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||
|
||||
IscsiLun *iscsilun = bs->opaque;
|
||||
uint64_t max_xfer_len = iscsilun->use_16_for_rw ? 0xffffffff : 0xffff;
|
||||
unsigned int block_size = MAX(BDRV_SECTOR_SIZE, iscsilun->block_size);
|
||||
|
||||
bs->bl.request_alignment = iscsilun->block_size;
|
||||
assert(iscsilun->block_size >= BDRV_SECTOR_SIZE || bs->sg);
|
||||
|
||||
bs->bl.request_alignment = block_size;
|
||||
|
||||
if (iscsilun->bl.max_xfer_len) {
|
||||
max_xfer_len = MIN(max_xfer_len, iscsilun->bl.max_xfer_len);
|
||||
}
|
||||
|
||||
if (max_xfer_len * iscsilun->block_size < INT_MAX) {
|
||||
if (max_xfer_len * block_size < INT_MAX) {
|
||||
bs->bl.max_transfer = max_xfer_len * iscsilun->block_size;
|
||||
}
|
||||
|
||||
if (iscsilun->lbp.lbpu) {
|
||||
if (iscsilun->bl.max_unmap < 0xffffffff / iscsilun->block_size) {
|
||||
if (iscsilun->bl.max_unmap < 0xffffffff / block_size) {
|
||||
bs->bl.max_pdiscard =
|
||||
iscsilun->bl.max_unmap * iscsilun->block_size;
|
||||
}
|
||||
@@ -1835,7 +1840,7 @@ static void iscsi_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||
bs->bl.pdiscard_alignment = iscsilun->block_size;
|
||||
}
|
||||
|
||||
if (iscsilun->bl.max_ws_len < 0xffffffff / iscsilun->block_size) {
|
||||
if (iscsilun->bl.max_ws_len < 0xffffffff / block_size) {
|
||||
bs->bl.max_pwrite_zeroes =
|
||||
iscsilun->bl.max_ws_len * iscsilun->block_size;
|
||||
}
|
||||
@@ -1846,7 +1851,7 @@ static void iscsi_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||
bs->bl.pwrite_zeroes_alignment = iscsilun->block_size;
|
||||
}
|
||||
if (iscsilun->bl.opt_xfer_len &&
|
||||
iscsilun->bl.opt_xfer_len < INT_MAX / iscsilun->block_size) {
|
||||
iscsilun->bl.opt_xfer_len < INT_MAX / block_size) {
|
||||
bs->bl.opt_transfer = pow2floor(iscsilun->bl.opt_xfer_len *
|
||||
iscsilun->block_size);
|
||||
}
|
||||
|
||||
@@ -427,7 +427,7 @@ static int coroutine_fn do_perform_cow(BlockDriverState *bs,
|
||||
|
||||
if (bs->encrypted) {
|
||||
Error *err = NULL;
|
||||
int64_t sector = (cluster_offset + offset_in_cluster)
|
||||
int64_t sector = (src_cluster_offset + offset_in_cluster)
|
||||
>> BDRV_SECTOR_BITS;
|
||||
assert(s->cipher);
|
||||
assert((offset_in_cluster & ~BDRV_SECTOR_MASK) == 0);
|
||||
|
||||
@@ -1204,6 +1204,7 @@ static void qcow2_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||
bs->bl.request_alignment = BDRV_SECTOR_SIZE;
|
||||
}
|
||||
bs->bl.pwrite_zeroes_alignment = s->cluster_size;
|
||||
bs->bl.pdiscard_alignment = s->cluster_size;
|
||||
}
|
||||
|
||||
static int qcow2_set_key(BlockDriverState *bs, const char *key)
|
||||
@@ -2485,6 +2486,11 @@ static coroutine_fn int qcow2_co_pdiscard(BlockDriverState *bs,
|
||||
int ret;
|
||||
BDRVQcow2State *s = bs->opaque;
|
||||
|
||||
if (!QEMU_IS_ALIGNED(offset | count, s->cluster_size)) {
|
||||
assert(count < s->cluster_size);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
qemu_co_mutex_lock(&s->lock);
|
||||
ret = qcow2_discard_clusters(bs, offset, count >> BDRV_SECTOR_BITS,
|
||||
QCOW2_DISCARD_REQUEST, false);
|
||||
|
||||
+2
-2
@@ -737,7 +737,7 @@ static BlockAIOCB *qemu_rbd_aio_readv(BlockDriverState *bs,
|
||||
void *opaque)
|
||||
{
|
||||
return rbd_start_aio(bs, sector_num << BDRV_SECTOR_BITS, qiov,
|
||||
nb_sectors << BDRV_SECTOR_BITS, cb, opaque,
|
||||
(int64_t) nb_sectors << BDRV_SECTOR_BITS, cb, opaque,
|
||||
RBD_AIO_READ);
|
||||
}
|
||||
|
||||
@@ -749,7 +749,7 @@ static BlockAIOCB *qemu_rbd_aio_writev(BlockDriverState *bs,
|
||||
void *opaque)
|
||||
{
|
||||
return rbd_start_aio(bs, sector_num << BDRV_SECTOR_BITS, qiov,
|
||||
nb_sectors << BDRV_SECTOR_BITS, cb, opaque,
|
||||
(int64_t) nb_sectors << BDRV_SECTOR_BITS, cb, opaque,
|
||||
RBD_AIO_WRITE);
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -2820,8 +2820,9 @@ static coroutine_fn int sd_co_pdiscard(BlockDriverState *bs, int64_t offset,
|
||||
iov.iov_len = sizeof(zero);
|
||||
discard_iov.iov = &iov;
|
||||
discard_iov.niov = 1;
|
||||
assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0);
|
||||
assert((count & (BDRV_SECTOR_SIZE - 1)) == 0);
|
||||
if (!QEMU_IS_ALIGNED(offset | count, BDRV_SECTOR_SIZE)) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
acb = sd_aio_setup(bs, &discard_iov, offset >> BDRV_SECTOR_BITS,
|
||||
count >> BDRV_SECTOR_BITS);
|
||||
acb->aiocb_type = AIOCB_DISCARD_OBJ;
|
||||
|
||||
+23
-4
@@ -168,6 +168,22 @@ static BlockBackend *throttle_group_next_blk(BlockBackend *blk)
|
||||
return blk_by_public(next);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return whether a BlockBackend has pending requests.
|
||||
*
|
||||
* This assumes that tg->lock is held.
|
||||
*
|
||||
* @blk: the BlockBackend
|
||||
* @is_write: the type of operation (read/write)
|
||||
* @ret: whether the BlockBackend has pending requests.
|
||||
*/
|
||||
static inline bool blk_has_pending_reqs(BlockBackend *blk,
|
||||
bool is_write)
|
||||
{
|
||||
const BlockBackendPublic *blkp = blk_get_public(blk);
|
||||
return blkp->pending_reqs[is_write];
|
||||
}
|
||||
|
||||
/* Return the next BlockBackend in the round-robin sequence with pending I/O
|
||||
* requests.
|
||||
*
|
||||
@@ -188,7 +204,7 @@ static BlockBackend *next_throttle_token(BlockBackend *blk, bool is_write)
|
||||
|
||||
/* get next bs round in round robin style */
|
||||
token = throttle_group_next_blk(token);
|
||||
while (token != start && !blkp->pending_reqs[is_write]) {
|
||||
while (token != start && !blk_has_pending_reqs(token, is_write)) {
|
||||
token = throttle_group_next_blk(token);
|
||||
}
|
||||
|
||||
@@ -196,10 +212,13 @@ static BlockBackend *next_throttle_token(BlockBackend *blk, bool is_write)
|
||||
* then decide the token is the current bs because chances are
|
||||
* the current bs get the current request queued.
|
||||
*/
|
||||
if (token == start && !blkp->pending_reqs[is_write]) {
|
||||
if (token == start && !blk_has_pending_reqs(token, is_write)) {
|
||||
token = blk;
|
||||
}
|
||||
|
||||
/* Either we return the original BB, or one with pending requests */
|
||||
assert(token == blk || blk_has_pending_reqs(token, is_write));
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
@@ -257,7 +276,7 @@ static void schedule_next_request(BlockBackend *blk, bool is_write)
|
||||
|
||||
/* Check if there's any pending request to schedule next */
|
||||
token = next_throttle_token(blk, is_write);
|
||||
if (!blkp->pending_reqs[is_write]) {
|
||||
if (!blk_has_pending_reqs(token, is_write)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -271,7 +290,7 @@ static void schedule_next_request(BlockBackend *blk, bool is_write)
|
||||
qemu_co_queue_next(&blkp->throttled_reqs[is_write])) {
|
||||
token = blk;
|
||||
} else {
|
||||
ThrottleTimers *tt = &blkp->throttle_timers;
|
||||
ThrottleTimers *tt = &blk_get_public(token)->throttle_timers;
|
||||
int64_t now = qemu_clock_get_ns(tt->clock_type);
|
||||
timer_mod(tt->timers[is_write], now + 1);
|
||||
tg->any_timer_armed[is_write] = true;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-version.h"
|
||||
#include <machine/trap.h>
|
||||
|
||||
#include "qapi/error.h"
|
||||
|
||||
@@ -745,7 +745,7 @@ static int do_vm_stop(RunState state)
|
||||
}
|
||||
|
||||
bdrv_drain_all();
|
||||
ret = blk_flush_all();
|
||||
ret = bdrv_flush_all();
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1488,7 +1488,7 @@ int vm_stop_force_state(RunState state)
|
||||
bdrv_drain_all();
|
||||
/* Make sure to return an error if the flush in a previous vm_stop()
|
||||
* failed. */
|
||||
return blk_flush_all();
|
||||
return bdrv_flush_all();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -192,6 +192,12 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
|
||||
}
|
||||
|
||||
if (cipher->mode == QCRYPTO_CIPHER_MODE_XTS) {
|
||||
if (ctx->blocksize != XTS_BLOCK_SIZE) {
|
||||
error_setg(errp,
|
||||
"Cipher block size %zu must equal XTS block size %d",
|
||||
ctx->blocksize, XTS_BLOCK_SIZE);
|
||||
goto error;
|
||||
}
|
||||
ctx->iv = g_new0(uint8_t, ctx->blocksize);
|
||||
}
|
||||
|
||||
|
||||
@@ -361,6 +361,13 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (mode == QCRYPTO_CIPHER_MODE_XTS &&
|
||||
ctx->blocksize != XTS_BLOCK_SIZE) {
|
||||
error_setg(errp, "Cipher block size %zu must equal XTS block size %d",
|
||||
ctx->blocksize, XTS_BLOCK_SIZE);
|
||||
goto error;
|
||||
}
|
||||
|
||||
ctx->iv = g_new0(uint8_t, ctx->blocksize);
|
||||
cipher->opaque = ctx;
|
||||
|
||||
@@ -456,11 +463,6 @@ int qcrypto_cipher_decrypt(QCryptoCipher *cipher,
|
||||
break;
|
||||
|
||||
case QCRYPTO_CIPHER_MODE_XTS:
|
||||
if (ctx->blocksize != XTS_BLOCK_SIZE) {
|
||||
error_setg(errp, "Block size must be %d not %zu",
|
||||
XTS_BLOCK_SIZE, ctx->blocksize);
|
||||
return -1;
|
||||
}
|
||||
xts_decrypt(ctx->ctx, ctx->ctx_tweak,
|
||||
ctx->alg_encrypt_wrapper, ctx->alg_decrypt_wrapper,
|
||||
ctx->iv, len, out, in);
|
||||
|
||||
+12
-9
@@ -73,6 +73,7 @@ typedef struct {
|
||||
AioContext *ctx;
|
||||
BlockAIOCB *acb;
|
||||
QEMUSGList *sg;
|
||||
uint32_t align;
|
||||
uint64_t offset;
|
||||
DMADirection dir;
|
||||
int sg_cur_index;
|
||||
@@ -160,8 +161,9 @@ static void dma_blk_cb(void *opaque, int ret)
|
||||
return;
|
||||
}
|
||||
|
||||
if (dbs->iov.size & ~BDRV_SECTOR_MASK) {
|
||||
qemu_iovec_discard_back(&dbs->iov, dbs->iov.size & ~BDRV_SECTOR_MASK);
|
||||
if (!QEMU_IS_ALIGNED(dbs->iov.size, dbs->align)) {
|
||||
qemu_iovec_discard_back(&dbs->iov,
|
||||
QEMU_ALIGN_DOWN(dbs->iov.size, dbs->align));
|
||||
}
|
||||
|
||||
dbs->acb = dbs->io_func(dbs->offset, &dbs->iov,
|
||||
@@ -199,7 +201,7 @@ static const AIOCBInfo dma_aiocb_info = {
|
||||
};
|
||||
|
||||
BlockAIOCB *dma_blk_io(AioContext *ctx,
|
||||
QEMUSGList *sg, uint64_t offset,
|
||||
QEMUSGList *sg, uint64_t offset, uint32_t align,
|
||||
DMAIOFunc *io_func, void *io_func_opaque,
|
||||
BlockCompletionFunc *cb,
|
||||
void *opaque, DMADirection dir)
|
||||
@@ -212,6 +214,7 @@ BlockAIOCB *dma_blk_io(AioContext *ctx,
|
||||
dbs->sg = sg;
|
||||
dbs->ctx = ctx;
|
||||
dbs->offset = offset;
|
||||
dbs->align = align;
|
||||
dbs->sg_cur_index = 0;
|
||||
dbs->sg_cur_byte = 0;
|
||||
dbs->dir = dir;
|
||||
@@ -234,11 +237,11 @@ BlockAIOCB *dma_blk_read_io_func(int64_t offset, QEMUIOVector *iov,
|
||||
}
|
||||
|
||||
BlockAIOCB *dma_blk_read(BlockBackend *blk,
|
||||
QEMUSGList *sg, uint64_t offset,
|
||||
QEMUSGList *sg, uint64_t offset, uint32_t align,
|
||||
void (*cb)(void *opaque, int ret), void *opaque)
|
||||
{
|
||||
return dma_blk_io(blk_get_aio_context(blk),
|
||||
sg, offset, dma_blk_read_io_func, blk, cb, opaque,
|
||||
return dma_blk_io(blk_get_aio_context(blk), sg, offset, align,
|
||||
dma_blk_read_io_func, blk, cb, opaque,
|
||||
DMA_DIRECTION_FROM_DEVICE);
|
||||
}
|
||||
|
||||
@@ -252,11 +255,11 @@ BlockAIOCB *dma_blk_write_io_func(int64_t offset, QEMUIOVector *iov,
|
||||
}
|
||||
|
||||
BlockAIOCB *dma_blk_write(BlockBackend *blk,
|
||||
QEMUSGList *sg, uint64_t offset,
|
||||
QEMUSGList *sg, uint64_t offset, uint32_t align,
|
||||
void (*cb)(void *opaque, int ret), void *opaque)
|
||||
{
|
||||
return dma_blk_io(blk_get_aio_context(blk),
|
||||
sg, offset, dma_blk_write_io_func, blk, cb, opaque,
|
||||
return dma_blk_io(blk_get_aio_context(blk), sg, offset, align,
|
||||
dma_blk_write_io_func, blk, cb, opaque,
|
||||
DMA_DIRECTION_TO_DEVICE);
|
||||
}
|
||||
|
||||
|
||||
@@ -1284,6 +1284,7 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
|
||||
break;
|
||||
case MIGRATION_PARAMETER_CPU_THROTTLE_INCREMENT:
|
||||
has_cpu_throttle_increment = true;
|
||||
use_int_value = true;
|
||||
break;
|
||||
case MIGRATION_PARAMETER_TLS_CREDS:
|
||||
has_tls_creds = true;
|
||||
|
||||
+139
-9
@@ -1010,6 +1010,7 @@ static void v9fs_attach(void *opaque)
|
||||
goto out;
|
||||
}
|
||||
err += offset;
|
||||
memcpy(&s->root_qid, &qid, sizeof(qid));
|
||||
trace_v9fs_attach_return(pdu->tag, pdu->id,
|
||||
qid.type, qid.version, qid.path);
|
||||
/*
|
||||
@@ -1256,6 +1257,19 @@ static int v9fs_walk_marshal(V9fsPDU *pdu, uint16_t nwnames, V9fsQID *qids)
|
||||
return offset;
|
||||
}
|
||||
|
||||
static bool name_is_illegal(const char *name)
|
||||
{
|
||||
return !*name || strchr(name, '/') != NULL;
|
||||
}
|
||||
|
||||
static bool not_same_qid(const V9fsQID *qid1, const V9fsQID *qid2)
|
||||
{
|
||||
return
|
||||
qid1->type != qid2->type ||
|
||||
qid1->version != qid2->version ||
|
||||
qid1->path != qid2->path;
|
||||
}
|
||||
|
||||
static void v9fs_walk(void *opaque)
|
||||
{
|
||||
int name_idx;
|
||||
@@ -1271,6 +1285,7 @@ static void v9fs_walk(void *opaque)
|
||||
V9fsFidState *newfidp = NULL;
|
||||
V9fsPDU *pdu = opaque;
|
||||
V9fsState *s = pdu->s;
|
||||
V9fsQID qid;
|
||||
|
||||
err = pdu_unmarshal(pdu, offset, "ddw", &fid, &newfid, &nwnames);
|
||||
if (err < 0) {
|
||||
@@ -1289,6 +1304,10 @@ static void v9fs_walk(void *opaque)
|
||||
if (err < 0) {
|
||||
goto out_nofid;
|
||||
}
|
||||
if (name_is_illegal(wnames[i].data)) {
|
||||
err = -ENOENT;
|
||||
goto out_nofid;
|
||||
}
|
||||
offset += err;
|
||||
}
|
||||
} else if (nwnames > P9_MAXWELEM) {
|
||||
@@ -1300,8 +1319,15 @@ static void v9fs_walk(void *opaque)
|
||||
err = -ENOENT;
|
||||
goto out_nofid;
|
||||
}
|
||||
|
||||
v9fs_path_init(&dpath);
|
||||
v9fs_path_init(&path);
|
||||
|
||||
err = fid_to_qid(pdu, fidp, &qid);
|
||||
if (err < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Both dpath and path initially poin to fidp.
|
||||
* Needed to handle request with nwnames == 0
|
||||
@@ -1309,16 +1335,22 @@ static void v9fs_walk(void *opaque)
|
||||
v9fs_path_copy(&dpath, &fidp->path);
|
||||
v9fs_path_copy(&path, &fidp->path);
|
||||
for (name_idx = 0; name_idx < nwnames; name_idx++) {
|
||||
err = v9fs_co_name_to_path(pdu, &dpath, wnames[name_idx].data, &path);
|
||||
if (err < 0) {
|
||||
goto out;
|
||||
if (not_same_qid(&pdu->s->root_qid, &qid) ||
|
||||
strcmp("..", wnames[name_idx].data)) {
|
||||
err = v9fs_co_name_to_path(pdu, &dpath, wnames[name_idx].data,
|
||||
&path);
|
||||
if (err < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = v9fs_co_lstat(pdu, &path, &stbuf);
|
||||
if (err < 0) {
|
||||
goto out;
|
||||
}
|
||||
stat_to_qid(&stbuf, &qid);
|
||||
v9fs_path_copy(&dpath, &path);
|
||||
}
|
||||
err = v9fs_co_lstat(pdu, &path, &stbuf);
|
||||
if (err < 0) {
|
||||
goto out;
|
||||
}
|
||||
stat_to_qid(&stbuf, &qids[name_idx]);
|
||||
v9fs_path_copy(&dpath, &path);
|
||||
memcpy(&qids[name_idx], &qid, sizeof(qid));
|
||||
}
|
||||
if (fid == newfid) {
|
||||
BUG_ON(fidp->fid_type != P9_FID_NONE);
|
||||
@@ -1483,6 +1515,16 @@ static void v9fs_lcreate(void *opaque)
|
||||
}
|
||||
trace_v9fs_lcreate(pdu->tag, pdu->id, dfid, flags, mode, gid);
|
||||
|
||||
if (name_is_illegal(name.data)) {
|
||||
err = -ENOENT;
|
||||
goto out_nofid;
|
||||
}
|
||||
|
||||
if (!strcmp(".", name.data) || !strcmp("..", name.data)) {
|
||||
err = -EEXIST;
|
||||
goto out_nofid;
|
||||
}
|
||||
|
||||
fidp = get_fid(pdu, dfid);
|
||||
if (fidp == NULL) {
|
||||
err = -ENOENT;
|
||||
@@ -2077,6 +2119,16 @@ static void v9fs_create(void *opaque)
|
||||
}
|
||||
trace_v9fs_create(pdu->tag, pdu->id, fid, name.data, perm, mode);
|
||||
|
||||
if (name_is_illegal(name.data)) {
|
||||
err = -ENOENT;
|
||||
goto out_nofid;
|
||||
}
|
||||
|
||||
if (!strcmp(".", name.data) || !strcmp("..", name.data)) {
|
||||
err = -EEXIST;
|
||||
goto out_nofid;
|
||||
}
|
||||
|
||||
fidp = get_fid(pdu, fid);
|
||||
if (fidp == NULL) {
|
||||
err = -EINVAL;
|
||||
@@ -2242,6 +2294,16 @@ static void v9fs_symlink(void *opaque)
|
||||
}
|
||||
trace_v9fs_symlink(pdu->tag, pdu->id, dfid, name.data, symname.data, gid);
|
||||
|
||||
if (name_is_illegal(name.data)) {
|
||||
err = -ENOENT;
|
||||
goto out_nofid;
|
||||
}
|
||||
|
||||
if (!strcmp(".", name.data) || !strcmp("..", name.data)) {
|
||||
err = -EEXIST;
|
||||
goto out_nofid;
|
||||
}
|
||||
|
||||
dfidp = get_fid(pdu, dfid);
|
||||
if (dfidp == NULL) {
|
||||
err = -EINVAL;
|
||||
@@ -2316,6 +2378,16 @@ static void v9fs_link(void *opaque)
|
||||
}
|
||||
trace_v9fs_link(pdu->tag, pdu->id, dfid, oldfid, name.data);
|
||||
|
||||
if (name_is_illegal(name.data)) {
|
||||
err = -ENOENT;
|
||||
goto out_nofid;
|
||||
}
|
||||
|
||||
if (!strcmp(".", name.data) || !strcmp("..", name.data)) {
|
||||
err = -EEXIST;
|
||||
goto out_nofid;
|
||||
}
|
||||
|
||||
dfidp = get_fid(pdu, dfid);
|
||||
if (dfidp == NULL) {
|
||||
err = -ENOENT;
|
||||
@@ -2398,6 +2470,22 @@ static void v9fs_unlinkat(void *opaque)
|
||||
if (err < 0) {
|
||||
goto out_nofid;
|
||||
}
|
||||
|
||||
if (name_is_illegal(name.data)) {
|
||||
err = -ENOENT;
|
||||
goto out_nofid;
|
||||
}
|
||||
|
||||
if (!strcmp(".", name.data)) {
|
||||
err = -EINVAL;
|
||||
goto out_nofid;
|
||||
}
|
||||
|
||||
if (!strcmp("..", name.data)) {
|
||||
err = -ENOTEMPTY;
|
||||
goto out_nofid;
|
||||
}
|
||||
|
||||
dfidp = get_fid(pdu, dfid);
|
||||
if (dfidp == NULL) {
|
||||
err = -EINVAL;
|
||||
@@ -2504,6 +2592,17 @@ static void v9fs_rename(void *opaque)
|
||||
if (err < 0) {
|
||||
goto out_nofid;
|
||||
}
|
||||
|
||||
if (name_is_illegal(name.data)) {
|
||||
err = -ENOENT;
|
||||
goto out_nofid;
|
||||
}
|
||||
|
||||
if (!strcmp(".", name.data) || !strcmp("..", name.data)) {
|
||||
err = -EISDIR;
|
||||
goto out_nofid;
|
||||
}
|
||||
|
||||
fidp = get_fid(pdu, fid);
|
||||
if (fidp == NULL) {
|
||||
err = -ENOENT;
|
||||
@@ -2616,6 +2715,17 @@ static void v9fs_renameat(void *opaque)
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
if (name_is_illegal(old_name.data) || name_is_illegal(new_name.data)) {
|
||||
err = -ENOENT;
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
if (!strcmp(".", old_name.data) || !strcmp("..", old_name.data) ||
|
||||
!strcmp(".", new_name.data) || !strcmp("..", new_name.data)) {
|
||||
err = -EISDIR;
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
v9fs_path_write_lock(s);
|
||||
err = v9fs_complete_renameat(pdu, olddirfid,
|
||||
&old_name, newdirfid, &new_name);
|
||||
@@ -2826,6 +2936,16 @@ static void v9fs_mknod(void *opaque)
|
||||
}
|
||||
trace_v9fs_mknod(pdu->tag, pdu->id, fid, mode, major, minor);
|
||||
|
||||
if (name_is_illegal(name.data)) {
|
||||
err = -ENOENT;
|
||||
goto out_nofid;
|
||||
}
|
||||
|
||||
if (!strcmp(".", name.data) || !strcmp("..", name.data)) {
|
||||
err = -EEXIST;
|
||||
goto out_nofid;
|
||||
}
|
||||
|
||||
fidp = get_fid(pdu, fid);
|
||||
if (fidp == NULL) {
|
||||
err = -ENOENT;
|
||||
@@ -2977,6 +3097,16 @@ static void v9fs_mkdir(void *opaque)
|
||||
}
|
||||
trace_v9fs_mkdir(pdu->tag, pdu->id, fid, name.data, mode, gid);
|
||||
|
||||
if (name_is_illegal(name.data)) {
|
||||
err = -ENOENT;
|
||||
goto out_nofid;
|
||||
}
|
||||
|
||||
if (!strcmp(".", name.data) || !strcmp("..", name.data)) {
|
||||
err = -EEXIST;
|
||||
goto out_nofid;
|
||||
}
|
||||
|
||||
fidp = get_fid(pdu, fid);
|
||||
if (fidp == NULL) {
|
||||
err = -ENOENT;
|
||||
|
||||
@@ -236,6 +236,7 @@ typedef struct V9fsState
|
||||
int32_t root_fid;
|
||||
Error *migration_blocker;
|
||||
V9fsConf fsconf;
|
||||
V9fsQID root_qid;
|
||||
} V9fsState;
|
||||
|
||||
/* 9p2000.L open flags */
|
||||
|
||||
@@ -99,6 +99,7 @@ void build_acpi_ipmi_devices(Aml *scope, BusState *bus)
|
||||
|
||||
ii = IPMI_INTERFACE(obj);
|
||||
iic = IPMI_INTERFACE_GET_CLASS(obj);
|
||||
memset(&info, 0, sizeof(info));
|
||||
iic->get_fwinfo(ii, &info);
|
||||
aml_append(scope, aml_ipmi_device(&info));
|
||||
}
|
||||
|
||||
+6
-3
@@ -60,6 +60,8 @@ typedef struct GUSState {
|
||||
int64_t last_ticks;
|
||||
qemu_irq pic;
|
||||
IsaDma *isa_dma;
|
||||
PortioList portio_list1;
|
||||
PortioList portio_list2;
|
||||
} GUSState;
|
||||
|
||||
static uint32_t gus_readb(void *opaque, uint32_t nport)
|
||||
@@ -265,9 +267,10 @@ static void gus_realizefn (DeviceState *dev, Error **errp)
|
||||
s->samples = AUD_get_buffer_size_out (s->voice) >> s->shift;
|
||||
s->mixbuf = g_malloc0 (s->samples << s->shift);
|
||||
|
||||
isa_register_portio_list (d, s->port, gus_portio_list1, s, "gus");
|
||||
isa_register_portio_list (d, (s->port + 0x100) & 0xf00,
|
||||
gus_portio_list2, s, "gus");
|
||||
isa_register_portio_list(d, &s->portio_list1, s->port,
|
||||
gus_portio_list1, s, "gus");
|
||||
isa_register_portio_list(d, &s->portio_list2, (s->port + 0x100) & 0xf00,
|
||||
gus_portio_list2, s, "gus");
|
||||
|
||||
s->isa_dma = isa_get_dma(isa_bus_from_device(d), s->emu.gusdma);
|
||||
k = ISADMA_GET_CLASS(s->isa_dma);
|
||||
|
||||
+3
-1
@@ -106,6 +106,7 @@ typedef struct SB16State {
|
||||
/* mixer state */
|
||||
int mixer_nreg;
|
||||
uint8_t mixer_regs[256];
|
||||
PortioList portio_list;
|
||||
} SB16State;
|
||||
|
||||
static void SB_audio_callback (void *opaque, int free);
|
||||
@@ -1378,7 +1379,8 @@ static void sb16_realizefn (DeviceState *dev, Error **errp)
|
||||
dolog ("warning: Could not create auxiliary timer\n");
|
||||
}
|
||||
|
||||
isa_register_portio_list (isadev, s->port, sb16_ioport_list, s, "sb16");
|
||||
isa_register_portio_list(isadev, &s->portio_list, s->port,
|
||||
sb16_ioport_list, s, "sb16");
|
||||
|
||||
s->isa_hdma = isa_get_dma(isa_bus_from_device(isadev), s->hdma);
|
||||
k = ISADMA_GET_CLASS(s->isa_hdma);
|
||||
|
||||
+3
-1
@@ -692,6 +692,7 @@ struct FDCtrl {
|
||||
/* Timers state */
|
||||
uint8_t timer0;
|
||||
uint8_t timer1;
|
||||
PortioList portio_list;
|
||||
};
|
||||
|
||||
static FloppyDriveType get_fallback_drive_type(FDrive *drv)
|
||||
@@ -2495,7 +2496,8 @@ static void isabus_fdc_realize(DeviceState *dev, Error **errp)
|
||||
FDCtrl *fdctrl = &isa->state;
|
||||
Error *err = NULL;
|
||||
|
||||
isa_register_portio_list(isadev, isa->iobase, fdc_portio_list, fdctrl,
|
||||
isa_register_portio_list(isadev, &fdctrl->portio_list,
|
||||
isa->iobase, fdc_portio_list, fdctrl,
|
||||
"fdc");
|
||||
|
||||
isa_init_irq(isadev, &fdctrl->irq, isa->irq);
|
||||
|
||||
+4
-2
@@ -258,8 +258,10 @@ static uint16_t nvme_rw(NvmeCtrl *n, NvmeNamespace *ns, NvmeCmd *cmd,
|
||||
req->has_sg = true;
|
||||
dma_acct_start(n->conf.blk, &req->acct, &req->qsg, acct);
|
||||
req->aiocb = is_write ?
|
||||
dma_blk_write(n->conf.blk, &req->qsg, data_offset, nvme_rw_cb, req) :
|
||||
dma_blk_read(n->conf.blk, &req->qsg, data_offset, nvme_rw_cb, req);
|
||||
dma_blk_write(n->conf.blk, &req->qsg, data_offset, BDRV_SECTOR_SIZE,
|
||||
nvme_rw_cb, req) :
|
||||
dma_blk_read(n->conf.blk, &req->qsg, data_offset, BDRV_SECTOR_SIZE,
|
||||
nvme_rw_cb, req);
|
||||
|
||||
return NVME_NO_COMPLETE;
|
||||
}
|
||||
|
||||
+2
-1
@@ -80,6 +80,7 @@ typedef struct ParallelState {
|
||||
uint32_t last_read_offset; /* For debugging */
|
||||
/* Memory-mapped interface */
|
||||
int it_shift;
|
||||
PortioList portio_list;
|
||||
} ParallelState;
|
||||
|
||||
#define TYPE_ISA_PARALLEL "isa-parallel"
|
||||
@@ -532,7 +533,7 @@ static void parallel_isa_realizefn(DeviceState *dev, Error **errp)
|
||||
s->status = dummy;
|
||||
}
|
||||
|
||||
isa_register_portio_list(isadev, base,
|
||||
isa_register_portio_list(isadev, &s->portio_list, base,
|
||||
(s->hw_driver
|
||||
? &isa_parallel_portio_hw_list[0]
|
||||
: &isa_parallel_portio_sw_list[0]),
|
||||
|
||||
@@ -39,6 +39,8 @@ typedef struct ISAVGAState {
|
||||
ISADevice parent_obj;
|
||||
|
||||
struct VGACommonState state;
|
||||
PortioList portio_vga;
|
||||
PortioList portio_vbe;
|
||||
} ISAVGAState;
|
||||
|
||||
static void vga_isa_reset(DeviceState *dev)
|
||||
@@ -60,9 +62,11 @@ static void vga_isa_realizefn(DeviceState *dev, Error **errp)
|
||||
vga_common_init(s, OBJECT(dev), true);
|
||||
s->legacy_address_space = isa_address_space(isadev);
|
||||
vga_io_memory = vga_init_io(s, OBJECT(dev), &vga_ports, &vbe_ports);
|
||||
isa_register_portio_list(isadev, 0x3b0, vga_ports, s, "vga");
|
||||
isa_register_portio_list(isadev, &d->portio_vga,
|
||||
0x3b0, vga_ports, s, "vga");
|
||||
if (vbe_ports) {
|
||||
isa_register_portio_list(isadev, 0x1ce, vbe_ports, s, "vbe");
|
||||
isa_register_portio_list(isadev, &d->portio_vbe,
|
||||
0x1ce, vbe_ports, s, "vbe");
|
||||
}
|
||||
memory_region_add_subregion_overlap(isa_address_space(isadev),
|
||||
0x000a0000,
|
||||
|
||||
+4
-2
@@ -553,10 +553,12 @@ static void i8257_realize(DeviceState *dev, Error **errp)
|
||||
memory_region_add_subregion(isa_address_space_io(isa),
|
||||
d->base, &d->channel_io);
|
||||
|
||||
isa_register_portio_list(isa, d->page_base, page_portio_list, d,
|
||||
isa_register_portio_list(isa, &d->portio_page,
|
||||
d->page_base, page_portio_list, d,
|
||||
"dma-page");
|
||||
if (d->pageh_base >= 0) {
|
||||
isa_register_portio_list(isa, d->pageh_base, pageh_portio_list, d,
|
||||
isa_register_portio_list(isa, &d->portio_pageh,
|
||||
d->pageh_base, pageh_portio_list, d,
|
||||
"dma-pageh");
|
||||
}
|
||||
|
||||
|
||||
@@ -985,6 +985,7 @@ static void vtd_context_device_invalidate(IntelIOMMUState *s,
|
||||
mask = 7; /* Mask bit 2:0 in the SID field */
|
||||
break;
|
||||
}
|
||||
mask = ~mask;
|
||||
VTD_DPRINTF(INV, "device-selective invalidation source 0x%"PRIx16
|
||||
" mask %"PRIu16, source_id, mask);
|
||||
vtd_bus = vtd_find_as_from_bus_num(s, VTD_SID_TO_BUS(source_id));
|
||||
|
||||
@@ -1251,6 +1251,7 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev, Error **errp)
|
||||
error_propagate(errp, local_err);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
dev->dev.cap_present |= QEMU_PCI_CAP_MSI;
|
||||
dev->cap.available |= ASSIGNED_DEVICE_CAP_MSI;
|
||||
/* Only 32-bit/no-mask currently supported */
|
||||
ret = pci_add_capability2(pci_dev, PCI_CAP_ID_MSI, pos, 10,
|
||||
@@ -1285,6 +1286,7 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev, Error **errp)
|
||||
error_propagate(errp, local_err);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
dev->dev.cap_present |= QEMU_PCI_CAP_MSIX;
|
||||
dev->cap.available |= ASSIGNED_DEVICE_CAP_MSIX;
|
||||
ret = pci_add_capability2(pci_dev, PCI_CAP_ID_MSIX, pos, 12,
|
||||
&local_err);
|
||||
@@ -1648,6 +1650,7 @@ static void assigned_dev_register_msix_mmio(AssignedDevice *dev, Error **errp)
|
||||
dev->msix_table = NULL;
|
||||
return;
|
||||
}
|
||||
dev->dev.msix_table = (uint8_t *)dev->msix_table;
|
||||
|
||||
assigned_dev_msix_reset(dev);
|
||||
|
||||
@@ -1665,6 +1668,7 @@ static void assigned_dev_unregister_msix_mmio(AssignedDevice *dev)
|
||||
error_report("error unmapping msix_table! %s", strerror(errno));
|
||||
}
|
||||
dev->msix_table = NULL;
|
||||
dev->dev.msix_table = NULL;
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_assigned_device = {
|
||||
|
||||
@@ -134,8 +134,6 @@ static void platform_fixed_ioport_writew(void *opaque, uint32_t addr, uint32_t v
|
||||
devices, and bit 2 the non-primary-master IDE devices. */
|
||||
if (val & UNPLUG_ALL_IDE_DISKS) {
|
||||
DPRINTF("unplug disks\n");
|
||||
blk_drain_all();
|
||||
blk_flush_all();
|
||||
pci_unplug_disks(pci_dev->bus);
|
||||
}
|
||||
if (val & UNPLUG_ALL_NICS) {
|
||||
|
||||
@@ -948,6 +948,7 @@ static void ncq_cb(void *opaque, int ret)
|
||||
NCQTransferState *ncq_tfs = (NCQTransferState *)opaque;
|
||||
IDEState *ide_state = &ncq_tfs->drive->port.ifs[0];
|
||||
|
||||
ncq_tfs->aiocb = NULL;
|
||||
if (ret == -ECANCELED) {
|
||||
return;
|
||||
}
|
||||
@@ -1008,6 +1009,7 @@ static void execute_ncq_command(NCQTransferState *ncq_tfs)
|
||||
&ncq_tfs->sglist, BLOCK_ACCT_READ);
|
||||
ncq_tfs->aiocb = dma_blk_read(ide_state->blk, &ncq_tfs->sglist,
|
||||
ncq_tfs->lba << BDRV_SECTOR_BITS,
|
||||
BDRV_SECTOR_SIZE,
|
||||
ncq_cb, ncq_tfs);
|
||||
break;
|
||||
case WRITE_FPDMA_QUEUED:
|
||||
@@ -1021,6 +1023,7 @@ static void execute_ncq_command(NCQTransferState *ncq_tfs)
|
||||
&ncq_tfs->sglist, BLOCK_ACCT_WRITE);
|
||||
ncq_tfs->aiocb = dma_blk_write(ide_state->blk, &ncq_tfs->sglist,
|
||||
ncq_tfs->lba << BDRV_SECTOR_BITS,
|
||||
BDRV_SECTOR_SIZE,
|
||||
ncq_cb, ncq_tfs);
|
||||
break;
|
||||
default:
|
||||
|
||||
+40
-11
@@ -637,6 +637,23 @@ static unsigned int event_status_media(IDEState *s,
|
||||
return 8; /* We wrote to 4 extra bytes from the header */
|
||||
}
|
||||
|
||||
/*
|
||||
* Before transferring data or otherwise signalling acceptance of a command
|
||||
* marked CONDDATA, we must check the validity of the byte_count_limit.
|
||||
*/
|
||||
static bool validate_bcl(IDEState *s)
|
||||
{
|
||||
/* TODO: Check IDENTIFY data word 125 for defacult BCL (currently 0) */
|
||||
if (s->atapi_dma || atapi_byte_count_limit(s)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* TODO: Move abort back into core.c and introduce proper error flow between
|
||||
* ATAPI layer and IDE core layer */
|
||||
ide_abort_command(s);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void cmd_get_event_status_notification(IDEState *s,
|
||||
uint8_t *buf)
|
||||
{
|
||||
@@ -1028,12 +1045,19 @@ static void cmd_read_cd(IDEState *s, uint8_t* buf)
|
||||
return;
|
||||
}
|
||||
|
||||
transfer_request = buf[9];
|
||||
switch(transfer_request & 0xf8) {
|
||||
case 0x00:
|
||||
transfer_request = buf[9] & 0xf8;
|
||||
if (transfer_request == 0x00) {
|
||||
/* nothing */
|
||||
ide_atapi_cmd_ok(s);
|
||||
break;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check validity of BCL before transferring data */
|
||||
if (!validate_bcl(s)) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (transfer_request) {
|
||||
case 0x10:
|
||||
/* normal read */
|
||||
ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
|
||||
@@ -1266,6 +1290,14 @@ enum {
|
||||
* See ATA8-ACS3 "7.21.5 Byte Count Limit"
|
||||
*/
|
||||
NONDATA = 0x04,
|
||||
|
||||
/*
|
||||
* CONDDATA implies a command that transfers data only conditionally based
|
||||
* on the presence of suboptions. It should be exempt from the BCL check at
|
||||
* command validation time, but it needs to be checked at the command
|
||||
* handler level instead.
|
||||
*/
|
||||
CONDDATA = 0x08,
|
||||
};
|
||||
|
||||
static const struct AtapiCmd {
|
||||
@@ -1289,7 +1321,7 @@ static const struct AtapiCmd {
|
||||
[ 0xad ] = { cmd_read_dvd_structure, CHECK_READY },
|
||||
[ 0xbb ] = { cmd_set_speed, NONDATA },
|
||||
[ 0xbd ] = { cmd_mechanism_status, 0 },
|
||||
[ 0xbe ] = { cmd_read_cd, CHECK_READY },
|
||||
[ 0xbe ] = { cmd_read_cd, CHECK_READY | CONDDATA },
|
||||
/* [1] handler detects and reports not ready condition itself */
|
||||
};
|
||||
|
||||
@@ -1348,15 +1380,12 @@ void ide_atapi_cmd(IDEState *s)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Nondata commands permit the byte_count_limit to be 0.
|
||||
/* Commands that don't transfer DATA permit the byte_count_limit to be 0.
|
||||
* If this is a data-transferring PIO command and BCL is 0,
|
||||
* we abort at the /ATA/ level, not the ATAPI level.
|
||||
* See ATA8 ACS3 section 7.17.6.49 and 7.21.5 */
|
||||
if (cmd->handler && !(cmd->flags & NONDATA)) {
|
||||
/* TODO: Check IDENTIFY data word 125 for default BCL (currently 0) */
|
||||
if (!(atapi_byte_count_limit(s) || s->atapi_dma)) {
|
||||
/* TODO: Move abort back into core.c and make static inline again */
|
||||
ide_abort_command(s);
|
||||
if (cmd->handler && !(cmd->flags & (NONDATA | CONDDATA))) {
|
||||
if (!validate_bcl(s)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
+8
-6
@@ -882,15 +882,15 @@ static void ide_dma_cb(void *opaque, int ret)
|
||||
switch (s->dma_cmd) {
|
||||
case IDE_DMA_READ:
|
||||
s->bus->dma->aiocb = dma_blk_read(s->blk, &s->sg, offset,
|
||||
ide_dma_cb, s);
|
||||
BDRV_SECTOR_SIZE, ide_dma_cb, s);
|
||||
break;
|
||||
case IDE_DMA_WRITE:
|
||||
s->bus->dma->aiocb = dma_blk_write(s->blk, &s->sg, offset,
|
||||
ide_dma_cb, s);
|
||||
BDRV_SECTOR_SIZE, ide_dma_cb, s);
|
||||
break;
|
||||
case IDE_DMA_TRIM:
|
||||
s->bus->dma->aiocb = dma_blk_io(blk_get_aio_context(s->blk),
|
||||
&s->sg, offset,
|
||||
&s->sg, offset, BDRV_SECTOR_SIZE,
|
||||
ide_issue_trim, s->blk, ide_dma_cb, s,
|
||||
DMA_DIRECTION_TO_DEVICE);
|
||||
break;
|
||||
@@ -2582,7 +2582,7 @@ static void ide_restart_cb(void *opaque, int running, RunState state)
|
||||
void ide_register_restart_cb(IDEBus *bus)
|
||||
{
|
||||
if (bus->dma->ops->restart_dma) {
|
||||
qemu_add_vm_change_state_handler(ide_restart_cb, bus);
|
||||
bus->vmstate = qemu_add_vm_change_state_handler(ide_restart_cb, bus);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2619,10 +2619,12 @@ void ide_init_ioport(IDEBus *bus, ISADevice *dev, int iobase, int iobase2)
|
||||
{
|
||||
/* ??? Assume only ISA and PCI configurations, and that the PCI-ISA
|
||||
bridge has been setup properly to always register with ISA. */
|
||||
isa_register_portio_list(dev, iobase, ide_portio_list, bus, "ide");
|
||||
isa_register_portio_list(dev, &bus->portio_list,
|
||||
iobase, ide_portio_list, bus, "ide");
|
||||
|
||||
if (iobase2) {
|
||||
isa_register_portio_list(dev, iobase2, ide_portio2_list, bus, "ide");
|
||||
isa_register_portio_list(dev, &bus->portio2_list,
|
||||
iobase2, ide_portio2_list, bus, "ide");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -179,6 +179,10 @@ int pci_piix3_xen_ide_unplug(DeviceState *dev)
|
||||
if (di != NULL && !di->media_cd) {
|
||||
BlockBackend *blk = blk_by_legacy_dinfo(di);
|
||||
DeviceState *ds = blk_get_attached_dev(blk);
|
||||
|
||||
blk_drain(blk);
|
||||
blk_flush(blk);
|
||||
|
||||
if (ds) {
|
||||
blk_detach_dev(blk, ds);
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
/* --------------------------------- */
|
||||
|
||||
static char *idebus_get_fw_dev_path(DeviceState *dev);
|
||||
static void idebus_unrealize(DeviceState *qdev, Error **errp);
|
||||
|
||||
static Property ide_props[] = {
|
||||
DEFINE_PROP_UINT32("unit", IDEDevice, unit, -1),
|
||||
@@ -44,6 +45,15 @@ static void ide_bus_class_init(ObjectClass *klass, void *data)
|
||||
k->get_fw_dev_path = idebus_get_fw_dev_path;
|
||||
}
|
||||
|
||||
static void idebus_unrealize(DeviceState *qdev, Error **errp)
|
||||
{
|
||||
IDEBus *bus = DO_UPCAST(IDEBus, qbus, qdev->parent_bus);
|
||||
|
||||
if (bus->vmstate) {
|
||||
qemu_del_vm_change_state_handler(bus->vmstate);
|
||||
}
|
||||
}
|
||||
|
||||
static const TypeInfo ide_bus_info = {
|
||||
.name = TYPE_IDE_BUS,
|
||||
.parent = TYPE_BUS,
|
||||
@@ -345,6 +355,7 @@ static void ide_device_class_init(ObjectClass *klass, void *data)
|
||||
k->init = ide_qdev_init;
|
||||
set_bit(DEVICE_CATEGORY_STORAGE, k->categories);
|
||||
k->bus_type = TYPE_IDE_BUS;
|
||||
k->unrealize = idebus_unrealize;
|
||||
k->props = ide_props;
|
||||
}
|
||||
|
||||
|
||||
+5
-9
@@ -131,24 +131,20 @@ void isa_register_ioport(ISADevice *dev, MemoryRegion *io, uint16_t start)
|
||||
isa_init_ioport(dev, start);
|
||||
}
|
||||
|
||||
void isa_register_portio_list(ISADevice *dev, uint16_t start,
|
||||
void isa_register_portio_list(ISADevice *dev,
|
||||
PortioList *piolist, uint16_t start,
|
||||
const MemoryRegionPortio *pio_start,
|
||||
void *opaque, const char *name)
|
||||
{
|
||||
PortioList piolist;
|
||||
assert(piolist && !piolist->owner);
|
||||
|
||||
/* START is how we should treat DEV, regardless of the actual
|
||||
contents of the portio array. This is how the old code
|
||||
actually handled e.g. the FDC device. */
|
||||
isa_init_ioport(dev, start);
|
||||
|
||||
/* FIXME: the device should store created PortioList in its state. Note
|
||||
that DEV can be NULL here and that single device can register several
|
||||
portio lists. Current implementation is leaking memory allocated
|
||||
in portio_list_init. The leak is not critical because it happens only
|
||||
at initialization time. */
|
||||
portio_list_init(&piolist, OBJECT(dev), pio_start, opaque, name);
|
||||
portio_list_add(&piolist, isabus->address_space_io, start);
|
||||
portio_list_init(piolist, OBJECT(dev), pio_start, opaque, name);
|
||||
portio_list_add(piolist, isabus->address_space_io, start);
|
||||
}
|
||||
|
||||
static void isa_device_init(Object *obj)
|
||||
|
||||
+3
-1
@@ -859,7 +859,7 @@ static void ivshmem_common_realize(PCIDevice *dev, Error **errp)
|
||||
pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY,
|
||||
&s->ivshmem_mmio);
|
||||
|
||||
if (!s->not_legacy_32bit) {
|
||||
if (s->not_legacy_32bit) {
|
||||
attr |= PCI_BASE_ADDRESS_MEM_TYPE_64;
|
||||
}
|
||||
|
||||
@@ -1045,6 +1045,7 @@ static void ivshmem_plain_init(Object *obj)
|
||||
ivshmem_check_memdev_is_busy,
|
||||
OBJ_PROP_LINK_UNREF_ON_RELEASE,
|
||||
&error_abort);
|
||||
s->not_legacy_32bit = 1;
|
||||
}
|
||||
|
||||
static void ivshmem_plain_realize(PCIDevice *dev, Error **errp)
|
||||
@@ -1116,6 +1117,7 @@ static void ivshmem_doorbell_init(Object *obj)
|
||||
|
||||
s->features |= (1 << IVSHMEM_MSI);
|
||||
s->legacy_size = SIZE_MAX; /* whatever the server sends */
|
||||
s->not_legacy_32bit = 1;
|
||||
}
|
||||
|
||||
static void ivshmem_doorbell_realize(PCIDevice *dev, Error **errp)
|
||||
|
||||
+1
-7
@@ -69,7 +69,6 @@ typedef struct E1000EState {
|
||||
uint16_t subsys_ven_used;
|
||||
uint16_t subsys_used;
|
||||
|
||||
uint32_t intr_state;
|
||||
bool disable_vnet;
|
||||
|
||||
E1000ECore core;
|
||||
@@ -89,8 +88,6 @@ typedef struct E1000EState {
|
||||
#define E1000E_MSIX_TABLE (0x0000)
|
||||
#define E1000E_MSIX_PBA (0x2000)
|
||||
|
||||
#define E1000E_USE_MSIX BIT(0)
|
||||
|
||||
static uint64_t
|
||||
e1000e_mmio_read(void *opaque, hwaddr addr, unsigned size)
|
||||
{
|
||||
@@ -302,8 +299,6 @@ e1000e_init_msix(E1000EState *s)
|
||||
} else {
|
||||
if (!e1000e_use_msix_vectors(s, E1000E_MSIX_VEC_NUM)) {
|
||||
msix_uninit(d, &s->msix, &s->msix);
|
||||
} else {
|
||||
s->intr_state |= E1000E_USE_MSIX;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -311,7 +306,7 @@ e1000e_init_msix(E1000EState *s)
|
||||
static void
|
||||
e1000e_cleanup_msix(E1000EState *s)
|
||||
{
|
||||
if (s->intr_state & E1000E_USE_MSIX) {
|
||||
if (msix_enabled(PCI_DEVICE(s))) {
|
||||
e1000e_unuse_msix_vectors(s, E1000E_MSIX_VEC_NUM);
|
||||
msix_uninit(PCI_DEVICE(s), &s->msix, &s->msix);
|
||||
}
|
||||
@@ -601,7 +596,6 @@ static const VMStateDescription e1000e_vmstate = {
|
||||
VMSTATE_MSIX(parent_obj, E1000EState),
|
||||
|
||||
VMSTATE_UINT32(ioaddr, E1000EState),
|
||||
VMSTATE_UINT32(intr_state, E1000EState),
|
||||
VMSTATE_UINT32(core.rxbuf_min_shift, E1000EState),
|
||||
VMSTATE_UINT8(core.rx_desc_len, E1000EState),
|
||||
VMSTATE_UINT32_ARRAY(core.rxbuf_sizes, E1000EState,
|
||||
|
||||
+2
-3
@@ -65,10 +65,9 @@ void net_tx_pkt_init(struct NetTxPkt **pkt, PCIDevice *pci_dev,
|
||||
|
||||
p->pci_dev = pci_dev;
|
||||
|
||||
p->vec = g_malloc((sizeof *p->vec) *
|
||||
(max_frags + NET_TX_PKT_PL_START_FRAG));
|
||||
p->vec = g_new(struct iovec, max_frags + NET_TX_PKT_PL_START_FRAG);
|
||||
|
||||
p->raw = g_malloc((sizeof *p->raw) * max_frags);
|
||||
p->raw = g_new(struct iovec, max_frags);
|
||||
|
||||
p->max_payload_frags = max_frags;
|
||||
p->max_raw_frags = max_frags;
|
||||
|
||||
+1
-1
@@ -2350,7 +2350,7 @@ static void rtl8139_cplus_transmit(RTL8139State *s)
|
||||
{
|
||||
int txcount = 0;
|
||||
|
||||
while (rtl8139_cplus_transmit_one(s))
|
||||
while (txcount < 64 && rtl8139_cplus_transmit_one(s))
|
||||
{
|
||||
++txcount;
|
||||
}
|
||||
|
||||
@@ -1904,6 +1904,7 @@ static void virtio_net_class_init(ObjectClass *klass, void *data)
|
||||
vdc->guest_notifier_pending = virtio_net_guest_notifier_pending;
|
||||
vdc->load = virtio_net_load_device;
|
||||
vdc->save = virtio_net_save_device;
|
||||
vdc->legacy_features |= (0x1 << VIRTIO_NET_F_GSO);
|
||||
}
|
||||
|
||||
static const TypeInfo virtio_net_info = {
|
||||
|
||||
+46
-30
@@ -594,6 +594,51 @@ static int spapr_populate_memory(sPAPRMachineState *spapr, void *fdt)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Populate the "ibm,pa-features" property */
|
||||
static void spapr_populate_pa_features(CPUPPCState *env, void *fdt, int offset)
|
||||
{
|
||||
uint8_t pa_features_206[] = { 6, 0,
|
||||
0xf6, 0x1f, 0xc7, 0x00, 0x80, 0xc0 };
|
||||
uint8_t pa_features_207[] = { 24, 0,
|
||||
0xf6, 0x1f, 0xc7, 0xc0, 0x80, 0xf0,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
|
||||
0x80, 0x00, 0x80, 0x00, 0x00, 0x00 };
|
||||
uint8_t *pa_features;
|
||||
size_t pa_size;
|
||||
|
||||
switch (env->mmu_model) {
|
||||
case POWERPC_MMU_2_06:
|
||||
case POWERPC_MMU_2_06a:
|
||||
pa_features = pa_features_206;
|
||||
pa_size = sizeof(pa_features_206);
|
||||
break;
|
||||
case POWERPC_MMU_2_07:
|
||||
case POWERPC_MMU_2_07a:
|
||||
pa_features = pa_features_207;
|
||||
pa_size = sizeof(pa_features_207);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (env->ci_large_pages) {
|
||||
/*
|
||||
* Note: we keep CI large pages off by default because a 64K capable
|
||||
* guest provisioned with large pages might otherwise try to map a qemu
|
||||
* framebuffer (or other kind of memory mapped PCI BAR) using 64K pages
|
||||
* even if that qemu runs on a 4k host.
|
||||
* We dd this bit back here if we are confident this is not an issue
|
||||
*/
|
||||
pa_features[3] |= 0x20;
|
||||
}
|
||||
if (kvmppc_has_cap_htm() && pa_size > 24) {
|
||||
pa_features[24] |= 0x80; /* Transactional memory support */
|
||||
}
|
||||
|
||||
_FDT((fdt_setprop(fdt, offset, "ibm,pa-features", pa_features, pa_size)));
|
||||
}
|
||||
|
||||
static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
|
||||
sPAPRMachineState *spapr)
|
||||
{
|
||||
@@ -621,24 +666,6 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
|
||||
_FDT((fdt_setprop_cell(fdt, offset, "ibm,my-drc-index", drc_index)));
|
||||
}
|
||||
|
||||
/* Note: we keep CI large pages off for now because a 64K capable guest
|
||||
* provisioned with large pages might otherwise try to map a qemu
|
||||
* framebuffer (or other kind of memory mapped PCI BAR) using 64K pages
|
||||
* even if that qemu runs on a 4k host.
|
||||
*
|
||||
* We can later add this bit back when we are confident this is not
|
||||
* an issue (!HV KVM or 64K host)
|
||||
*/
|
||||
uint8_t pa_features_206[] = { 6, 0,
|
||||
0xf6, 0x1f, 0xc7, 0x00, 0x80, 0xc0 };
|
||||
uint8_t pa_features_207[] = { 24, 0,
|
||||
0xf6, 0x1f, 0xc7, 0xc0, 0x80, 0xf0,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
|
||||
0x80, 0x00, 0x80, 0x00, 0x80, 0x00 };
|
||||
uint8_t *pa_features;
|
||||
size_t pa_size;
|
||||
|
||||
_FDT((fdt_setprop_cell(fdt, offset, "reg", index)));
|
||||
_FDT((fdt_setprop_string(fdt, offset, "device_type", "cpu")));
|
||||
|
||||
@@ -705,18 +732,7 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
|
||||
page_sizes_prop, page_sizes_prop_size)));
|
||||
}
|
||||
|
||||
/* Do the ibm,pa-features property, adjust it for ci-large-pages */
|
||||
if (env->mmu_model == POWERPC_MMU_2_06) {
|
||||
pa_features = pa_features_206;
|
||||
pa_size = sizeof(pa_features_206);
|
||||
} else /* env->mmu_model == POWERPC_MMU_2_07 */ {
|
||||
pa_features = pa_features_207;
|
||||
pa_size = sizeof(pa_features_207);
|
||||
}
|
||||
if (env->ci_large_pages) {
|
||||
pa_features[3] |= 0x20;
|
||||
}
|
||||
_FDT((fdt_setprop(fdt, offset, "ibm,pa-features", pa_features, pa_size)));
|
||||
spapr_populate_pa_features(env, fdt, offset);
|
||||
|
||||
_FDT((fdt_setprop_cell(fdt, offset, "ibm,chip-id",
|
||||
cs->cpu_index / vcpus_per_socket)));
|
||||
|
||||
+3
-5
@@ -141,7 +141,8 @@ out_err:
|
||||
int css_create_css_image(uint8_t cssid, bool default_image)
|
||||
{
|
||||
trace_css_new_image(cssid, default_image ? "(default)" : "");
|
||||
if (cssid > MAX_CSSID) {
|
||||
/* 255 is reserved */
|
||||
if (cssid == 255) {
|
||||
return -EINVAL;
|
||||
}
|
||||
if (channel_subsys.css[cssid]) {
|
||||
@@ -1267,7 +1268,7 @@ bool css_schid_final(int m, uint8_t cssid, uint8_t ssid, uint16_t schid)
|
||||
uint8_t real_cssid;
|
||||
|
||||
real_cssid = (!m && (cssid == 0)) ? channel_subsys.default_cssid : cssid;
|
||||
if (real_cssid > MAX_CSSID || ssid > MAX_SSID ||
|
||||
if (ssid > MAX_SSID ||
|
||||
!channel_subsys.css[real_cssid] ||
|
||||
!channel_subsys.css[real_cssid]->sch_set[ssid]) {
|
||||
return true;
|
||||
@@ -1282,9 +1283,6 @@ static int css_add_virtual_chpid(uint8_t cssid, uint8_t chpid, uint8_t type)
|
||||
CssImage *css;
|
||||
|
||||
trace_css_chpid_add(cssid, chpid, type);
|
||||
if (cssid > MAX_CSSID) {
|
||||
return -EINVAL;
|
||||
}
|
||||
css = channel_subsys.css[cssid];
|
||||
if (!css) {
|
||||
return -EINVAL;
|
||||
|
||||
@@ -330,6 +330,8 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
|
||||
if (!ccw.cda) {
|
||||
ret = -EFAULT;
|
||||
} else {
|
||||
VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
|
||||
|
||||
features.index = address_space_ldub(&address_space_memory,
|
||||
ccw.cda
|
||||
+ sizeof(features.features),
|
||||
@@ -339,7 +341,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
|
||||
if (dev->revision >= 1) {
|
||||
/* Don't offer legacy features for modern devices. */
|
||||
features.features = (uint32_t)
|
||||
(vdev->host_features & ~VIRTIO_LEGACY_FEATURES);
|
||||
(vdev->host_features & ~vdc->legacy_features);
|
||||
} else {
|
||||
features.features = (uint32_t)vdev->host_features;
|
||||
}
|
||||
|
||||
+5
-1
@@ -1981,7 +1981,11 @@ static void megasas_handle_frame(MegasasState *s, uint64_t frame_addr,
|
||||
break;
|
||||
}
|
||||
if (frame_status != MFI_STAT_INVALID_STATUS) {
|
||||
cmd->frame->header.cmd_status = frame_status;
|
||||
if (cmd->frame) {
|
||||
cmd->frame->header.cmd_status = frame_status;
|
||||
} else {
|
||||
megasas_frame_set_cmd_status(s, frame_addr, frame_status);
|
||||
}
|
||||
megasas_unmap_frame(s, cmd);
|
||||
megasas_complete_frame(s, cmd->context);
|
||||
}
|
||||
|
||||
+3
-3
@@ -158,7 +158,7 @@ static size_t mptsas_config_pack(uint8_t **data, const char *fmt, ...)
|
||||
va_end(ap);
|
||||
|
||||
if (data) {
|
||||
assert(ret < 256 && (ret % 4) == 0);
|
||||
assert(ret / 4 < 256 && (ret % 4) == 0);
|
||||
stb_p(*data + 1, ret / 4);
|
||||
}
|
||||
return ret;
|
||||
@@ -203,7 +203,7 @@ size_t mptsas_config_manufacturing_1(MPTSASState *s, uint8_t **data, int address
|
||||
{
|
||||
/* VPD - all zeros */
|
||||
return MPTSAS_CONFIG_PACK(1, MPI_CONFIG_PAGETYPE_MANUFACTURING, 0x00,
|
||||
"s256");
|
||||
"*s256");
|
||||
}
|
||||
|
||||
static
|
||||
@@ -328,7 +328,7 @@ size_t mptsas_config_ioc_0(MPTSASState *s, uint8_t **data, int address)
|
||||
return MPTSAS_CONFIG_PACK(0, MPI_CONFIG_PAGETYPE_IOC, 0x01,
|
||||
"*l*lwwb*b*b*blww",
|
||||
pcic->vendor_id, pcic->device_id, pcic->revision,
|
||||
pcic->subsystem_vendor_id,
|
||||
pcic->class_id, pcic->subsystem_vendor_id,
|
||||
pcic->subsystem_id);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -304,7 +304,7 @@ static int mptsas_process_scsi_io_request(MPTSASState *s,
|
||||
goto bad;
|
||||
}
|
||||
|
||||
req = g_new(MPTSASRequest, 1);
|
||||
req = g_new0(MPTSASRequest, 1);
|
||||
QTAILQ_INSERT_TAIL(&s->pending, req, next);
|
||||
req->scsi_io = *scsi_io;
|
||||
req->dev = s;
|
||||
|
||||
+12
-16
@@ -341,6 +341,7 @@ static void scsi_do_read(SCSIDiskReq *r, int ret)
|
||||
r->req.resid -= r->req.sg->size;
|
||||
r->req.aiocb = dma_blk_io(blk_get_aio_context(s->qdev.conf.blk),
|
||||
r->req.sg, r->sector << BDRV_SECTOR_BITS,
|
||||
BDRV_SECTOR_SIZE,
|
||||
sdc->dma_readv, r, scsi_dma_complete, r,
|
||||
DMA_DIRECTION_FROM_DEVICE);
|
||||
} else {
|
||||
@@ -396,7 +397,7 @@ static void scsi_read_data(SCSIRequest *req)
|
||||
return;
|
||||
}
|
||||
|
||||
if (s->tray_open) {
|
||||
if (!blk_is_available(req->dev->conf.blk)) {
|
||||
scsi_read_complete(r, -ENOMEDIUM);
|
||||
return;
|
||||
}
|
||||
@@ -519,7 +520,7 @@ static void scsi_write_data(SCSIRequest *req)
|
||||
scsi_write_complete_noio(r, 0);
|
||||
return;
|
||||
}
|
||||
if (s->tray_open) {
|
||||
if (!blk_is_available(req->dev->conf.blk)) {
|
||||
scsi_write_complete_noio(r, -ENOMEDIUM);
|
||||
return;
|
||||
}
|
||||
@@ -539,6 +540,7 @@ static void scsi_write_data(SCSIRequest *req)
|
||||
r->req.resid -= r->req.sg->size;
|
||||
r->req.aiocb = dma_blk_io(blk_get_aio_context(s->qdev.conf.blk),
|
||||
r->req.sg, r->sector << BDRV_SECTOR_BITS,
|
||||
BDRV_SECTOR_SIZE,
|
||||
sdc->dma_writev, r, scsi_dma_complete, r,
|
||||
DMA_DIRECTION_TO_DEVICE);
|
||||
} else {
|
||||
@@ -599,8 +601,8 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
|
||||
}
|
||||
|
||||
l = strlen(s->serial);
|
||||
if (l > 20) {
|
||||
l = 20;
|
||||
if (l > 36) {
|
||||
l = 36;
|
||||
}
|
||||
|
||||
DPRINTF("Inquiry EVPD[Serial number] "
|
||||
@@ -792,10 +794,7 @@ static inline bool media_is_dvd(SCSIDiskState *s)
|
||||
if (s->qdev.type != TYPE_ROM) {
|
||||
return false;
|
||||
}
|
||||
if (!blk_is_inserted(s->qdev.conf.blk)) {
|
||||
return false;
|
||||
}
|
||||
if (s->tray_open) {
|
||||
if (!blk_is_available(s->qdev.conf.blk)) {
|
||||
return false;
|
||||
}
|
||||
blk_get_geometry(s->qdev.conf.blk, &nb_sectors);
|
||||
@@ -808,10 +807,7 @@ static inline bool media_is_cd(SCSIDiskState *s)
|
||||
if (s->qdev.type != TYPE_ROM) {
|
||||
return false;
|
||||
}
|
||||
if (!blk_is_inserted(s->qdev.conf.blk)) {
|
||||
return false;
|
||||
}
|
||||
if (s->tray_open) {
|
||||
if (!blk_is_available(s->qdev.conf.blk)) {
|
||||
return false;
|
||||
}
|
||||
blk_get_geometry(s->qdev.conf.blk, &nb_sectors);
|
||||
@@ -875,7 +871,7 @@ static int scsi_read_dvd_structure(SCSIDiskState *s, SCSIDiskReq *r,
|
||||
}
|
||||
|
||||
if (format != 0xff) {
|
||||
if (s->tray_open || !blk_is_inserted(s->qdev.conf.blk)) {
|
||||
if (!blk_is_available(s->qdev.conf.blk)) {
|
||||
scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
|
||||
return -1;
|
||||
}
|
||||
@@ -1857,7 +1853,7 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf)
|
||||
break;
|
||||
|
||||
default:
|
||||
if (s->tray_open || !blk_is_inserted(s->qdev.conf.blk)) {
|
||||
if (!blk_is_available(s->qdev.conf.blk)) {
|
||||
scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
|
||||
return 0;
|
||||
}
|
||||
@@ -1886,7 +1882,7 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf)
|
||||
memset(outbuf, 0, r->buflen);
|
||||
switch (req->cmd.buf[0]) {
|
||||
case TEST_UNIT_READY:
|
||||
assert(!s->tray_open && blk_is_inserted(s->qdev.conf.blk));
|
||||
assert(blk_is_available(s->qdev.conf.blk));
|
||||
break;
|
||||
case INQUIRY:
|
||||
buflen = scsi_disk_emulate_inquiry(req, outbuf);
|
||||
@@ -2126,7 +2122,7 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf)
|
||||
|
||||
command = buf[0];
|
||||
|
||||
if (s->tray_open || !blk_is_inserted(s->qdev.conf.blk)) {
|
||||
if (!blk_is_available(s->qdev.conf.blk)) {
|
||||
scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -236,6 +236,13 @@ static void virtio_scsi_cancel_notify(Notifier *notifier, void *data)
|
||||
g_free(n);
|
||||
}
|
||||
|
||||
static inline void virtio_scsi_ctx_check(VirtIOSCSI *s, SCSIDevice *d)
|
||||
{
|
||||
if (s->dataplane_started && d && blk_is_available(d->conf.blk)) {
|
||||
assert(blk_get_aio_context(d->conf.blk) == s->ctx);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return 0 if the request is ready to be completed and return to guest;
|
||||
* -EINPROGRESS if the request is submitted and will be completed later, in the
|
||||
* case of async cancellation. */
|
||||
@@ -247,9 +254,7 @@ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req)
|
||||
int target;
|
||||
int ret = 0;
|
||||
|
||||
if (s->dataplane_started && d) {
|
||||
assert(blk_get_aio_context(d->conf.blk) == s->ctx);
|
||||
}
|
||||
virtio_scsi_ctx_check(s, d);
|
||||
/* Here VIRTIO_SCSI_S_OK means "FUNCTION COMPLETE". */
|
||||
req->resp.tmf.response = VIRTIO_SCSI_S_OK;
|
||||
|
||||
@@ -539,9 +544,7 @@ static bool virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req
|
||||
virtio_scsi_complete_cmd_req(req);
|
||||
return false;
|
||||
}
|
||||
if (s->dataplane_started) {
|
||||
assert(blk_get_aio_context(d->conf.blk) == s->ctx);
|
||||
}
|
||||
virtio_scsi_ctx_check(s, d);
|
||||
req->sreq = scsi_req_new(d, req->req.cmd.tag,
|
||||
virtio_scsi_get_lun(req->req.cmd.lun),
|
||||
req->req.cmd.cdb, req);
|
||||
|
||||
+13
-11
@@ -152,7 +152,7 @@ pvscsi_log2(uint32_t input)
|
||||
return log;
|
||||
}
|
||||
|
||||
static int
|
||||
static void
|
||||
pvscsi_ring_init_data(PVSCSIRingInfo *m, PVSCSICmdDescSetupRings *ri)
|
||||
{
|
||||
int i;
|
||||
@@ -160,10 +160,6 @@ pvscsi_ring_init_data(PVSCSIRingInfo *m, PVSCSICmdDescSetupRings *ri)
|
||||
uint32_t req_ring_size, cmp_ring_size;
|
||||
m->rs_pa = ri->ringsStatePPN << VMW_PAGE_SHIFT;
|
||||
|
||||
if ((ri->reqRingNumPages > PVSCSI_SETUP_RINGS_MAX_NUM_PAGES)
|
||||
|| (ri->cmpRingNumPages > PVSCSI_SETUP_RINGS_MAX_NUM_PAGES)) {
|
||||
return -1;
|
||||
}
|
||||
req_ring_size = ri->reqRingNumPages * PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE;
|
||||
cmp_ring_size = ri->cmpRingNumPages * PVSCSI_MAX_NUM_CMP_ENTRIES_PER_PAGE;
|
||||
txr_len_log2 = pvscsi_log2(req_ring_size - 1);
|
||||
@@ -195,8 +191,6 @@ pvscsi_ring_init_data(PVSCSIRingInfo *m, PVSCSICmdDescSetupRings *ri)
|
||||
|
||||
/* Flush ring state page changes */
|
||||
smp_wmb();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -251,8 +245,11 @@ static hwaddr
|
||||
pvscsi_ring_pop_req_descr(PVSCSIRingInfo *mgr)
|
||||
{
|
||||
uint32_t ready_ptr = RS_GET_FIELD(mgr, reqProdIdx);
|
||||
uint32_t ring_size = PVSCSI_MAX_NUM_PAGES_REQ_RING
|
||||
* PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE;
|
||||
|
||||
if (ready_ptr != mgr->consumed_ptr) {
|
||||
if (ready_ptr != mgr->consumed_ptr
|
||||
&& ready_ptr - mgr->consumed_ptr < ring_size) {
|
||||
uint32_t next_ready_ptr =
|
||||
mgr->consumed_ptr++ & mgr->txr_len_mask;
|
||||
uint32_t next_ready_page =
|
||||
@@ -746,7 +743,7 @@ pvscsi_dbg_dump_tx_rings_config(PVSCSICmdDescSetupRings *rc)
|
||||
|
||||
trace_pvscsi_tx_rings_num_pages("Confirm Ring", rc->cmpRingNumPages);
|
||||
for (i = 0; i < rc->cmpRingNumPages; i++) {
|
||||
trace_pvscsi_tx_rings_ppn("Confirm Ring", rc->reqRingPPNs[i]);
|
||||
trace_pvscsi_tx_rings_ppn("Confirm Ring", rc->cmpRingPPNs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -779,11 +776,16 @@ pvscsi_on_cmd_setup_rings(PVSCSIState *s)
|
||||
|
||||
trace_pvscsi_on_cmd_arrived("PVSCSI_CMD_SETUP_RINGS");
|
||||
|
||||
pvscsi_dbg_dump_tx_rings_config(rc);
|
||||
if (pvscsi_ring_init_data(&s->rings, rc) < 0) {
|
||||
if (!rc->reqRingNumPages
|
||||
|| rc->reqRingNumPages > PVSCSI_SETUP_RINGS_MAX_NUM_PAGES
|
||||
|| !rc->cmpRingNumPages
|
||||
|| rc->cmpRingNumPages > PVSCSI_SETUP_RINGS_MAX_NUM_PAGES) {
|
||||
return PVSCSI_COMMAND_PROCESSING_FAILED;
|
||||
}
|
||||
|
||||
pvscsi_dbg_dump_tx_rings_config(rc);
|
||||
pvscsi_ring_init_data(&s->rings, rc);
|
||||
|
||||
s->rings_info_valid = TRUE;
|
||||
return PVSCSI_COMMAND_PROCESSING_SUCCEEDED;
|
||||
}
|
||||
|
||||
+4
-5
@@ -723,12 +723,11 @@ int vfio_region_mmap(VFIORegion *region)
|
||||
|
||||
name = g_strdup_printf("%s mmaps[%d]",
|
||||
memory_region_name(region->mem), i);
|
||||
memory_region_init_ram_ptr(®ion->mmaps[i].mem,
|
||||
memory_region_owner(region->mem),
|
||||
name, region->mmaps[i].size,
|
||||
region->mmaps[i].mmap);
|
||||
memory_region_init_ram_device_ptr(®ion->mmaps[i].mem,
|
||||
memory_region_owner(region->mem),
|
||||
name, region->mmaps[i].size,
|
||||
region->mmaps[i].mmap);
|
||||
g_free(name);
|
||||
memory_region_set_skip_dump(®ion->mmaps[i].mem);
|
||||
memory_region_add_subregion(region->mem, region->mmaps[i].offset,
|
||||
®ion->mmaps[i].mem);
|
||||
|
||||
|
||||
@@ -898,7 +898,7 @@ static uint64_t vfio_rtl8168_quirk_data_read(void *opaque,
|
||||
{
|
||||
VFIOrtl8168Quirk *rtl = opaque;
|
||||
VFIOPCIDevice *vdev = rtl->vdev;
|
||||
uint64_t data = vfio_region_read(&vdev->bars[2].region, addr + 0x74, size);
|
||||
uint64_t data = vfio_region_read(&vdev->bars[2].region, addr + 0x70, size);
|
||||
|
||||
if (rtl->enabled && (vdev->pdev.cap_present & QEMU_PCI_CAP_MSIX)) {
|
||||
hwaddr offset = rtl->addr & 0xfff;
|
||||
|
||||
+3
-1
@@ -496,7 +496,9 @@ static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,
|
||||
vfio_update_kvm_msi_virq(vector, *msg, pdev);
|
||||
}
|
||||
} else {
|
||||
vfio_add_kvm_msi_virq(vdev, vector, nr, true);
|
||||
if (msg) {
|
||||
vfio_add_kvm_msi_virq(vdev, vector, nr, true);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ static bool vfio_prereg_listener_skipped_section(MemoryRegionSection *section)
|
||||
}
|
||||
|
||||
return !memory_region_is_ram(section->mr) ||
|
||||
memory_region_is_skip_dump(section->mr);
|
||||
memory_region_is_ram_device(section->mr);
|
||||
}
|
||||
|
||||
static void *vfio_prereg_gpa_to_vaddr(MemoryRegionSection *section, hwaddr gpa)
|
||||
|
||||
+60
-32
@@ -421,32 +421,73 @@ static inline void vhost_dev_log_resize(struct vhost_dev *dev, uint64_t size)
|
||||
dev->log_size = size;
|
||||
}
|
||||
|
||||
|
||||
static int vhost_verify_ring_part_mapping(void *part,
|
||||
uint64_t part_addr,
|
||||
uint64_t part_size,
|
||||
uint64_t start_addr,
|
||||
uint64_t size)
|
||||
{
|
||||
hwaddr l;
|
||||
void *p;
|
||||
int r = 0;
|
||||
|
||||
if (!ranges_overlap(start_addr, size, part_addr, part_size)) {
|
||||
return 0;
|
||||
}
|
||||
l = part_size;
|
||||
p = cpu_physical_memory_map(part_addr, &l, 1);
|
||||
if (!p || l != part_size) {
|
||||
r = -ENOMEM;
|
||||
}
|
||||
if (p != part) {
|
||||
r = -EBUSY;
|
||||
}
|
||||
cpu_physical_memory_unmap(p, l, 0, 0);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int vhost_verify_ring_mappings(struct vhost_dev *dev,
|
||||
uint64_t start_addr,
|
||||
uint64_t size)
|
||||
{
|
||||
int i;
|
||||
int i, j;
|
||||
int r = 0;
|
||||
const char *part_name[] = {
|
||||
"descriptor table",
|
||||
"available ring",
|
||||
"used ring"
|
||||
};
|
||||
|
||||
for (i = 0; !r && i < dev->nvqs; ++i) {
|
||||
for (i = 0; i < dev->nvqs; ++i) {
|
||||
struct vhost_virtqueue *vq = dev->vqs + i;
|
||||
hwaddr l;
|
||||
void *p;
|
||||
|
||||
if (!ranges_overlap(start_addr, size, vq->ring_phys, vq->ring_size)) {
|
||||
continue;
|
||||
j = 0;
|
||||
r = vhost_verify_ring_part_mapping(vq->desc, vq->desc_phys,
|
||||
vq->desc_size, start_addr, size);
|
||||
if (!r) {
|
||||
break;
|
||||
}
|
||||
l = vq->ring_size;
|
||||
p = cpu_physical_memory_map(vq->ring_phys, &l, 1);
|
||||
if (!p || l != vq->ring_size) {
|
||||
error_report("Unable to map ring buffer for ring %d", i);
|
||||
r = -ENOMEM;
|
||||
|
||||
j++;
|
||||
r = vhost_verify_ring_part_mapping(vq->avail, vq->avail_phys,
|
||||
vq->avail_size, start_addr, size);
|
||||
if (!r) {
|
||||
break;
|
||||
}
|
||||
if (p != vq->ring) {
|
||||
error_report("Ring buffer relocated for ring %d", i);
|
||||
r = -EBUSY;
|
||||
|
||||
j++;
|
||||
r = vhost_verify_ring_part_mapping(vq->used, vq->used_phys,
|
||||
vq->used_size, start_addr, size);
|
||||
if (!r) {
|
||||
break;
|
||||
}
|
||||
cpu_physical_memory_unmap(p, l, 0, 0);
|
||||
}
|
||||
|
||||
if (r == -ENOMEM) {
|
||||
error_report("Unable to map %s for ring %d", part_name[j], i);
|
||||
} else if (r == -EBUSY) {
|
||||
error_report("%s relocated for ring %d", part_name[j], i);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
@@ -857,15 +898,15 @@ static int vhost_virtqueue_start(struct vhost_dev *dev,
|
||||
}
|
||||
}
|
||||
|
||||
s = l = virtio_queue_get_desc_size(vdev, idx);
|
||||
a = virtio_queue_get_desc_addr(vdev, idx);
|
||||
vq->desc_size = s = l = virtio_queue_get_desc_size(vdev, idx);
|
||||
vq->desc_phys = a = virtio_queue_get_desc_addr(vdev, idx);
|
||||
vq->desc = cpu_physical_memory_map(a, &l, 0);
|
||||
if (!vq->desc || l != s) {
|
||||
r = -ENOMEM;
|
||||
goto fail_alloc_desc;
|
||||
}
|
||||
s = l = virtio_queue_get_avail_size(vdev, idx);
|
||||
a = virtio_queue_get_avail_addr(vdev, idx);
|
||||
vq->avail_size = s = l = virtio_queue_get_avail_size(vdev, idx);
|
||||
vq->avail_phys = a = virtio_queue_get_avail_addr(vdev, idx);
|
||||
vq->avail = cpu_physical_memory_map(a, &l, 0);
|
||||
if (!vq->avail || l != s) {
|
||||
r = -ENOMEM;
|
||||
@@ -879,14 +920,6 @@ static int vhost_virtqueue_start(struct vhost_dev *dev,
|
||||
goto fail_alloc_used;
|
||||
}
|
||||
|
||||
vq->ring_size = s = l = virtio_queue_get_ring_size(vdev, idx);
|
||||
vq->ring_phys = a = virtio_queue_get_ring_addr(vdev, idx);
|
||||
vq->ring = cpu_physical_memory_map(a, &l, 1);
|
||||
if (!vq->ring || l != s) {
|
||||
r = -ENOMEM;
|
||||
goto fail_alloc_ring;
|
||||
}
|
||||
|
||||
r = vhost_virtqueue_set_addr(dev, vq, vhost_vq_index, dev->log_enabled);
|
||||
if (r < 0) {
|
||||
r = -errno;
|
||||
@@ -916,9 +949,6 @@ static int vhost_virtqueue_start(struct vhost_dev *dev,
|
||||
|
||||
fail_kick:
|
||||
fail_alloc:
|
||||
cpu_physical_memory_unmap(vq->ring, virtio_queue_get_ring_size(vdev, idx),
|
||||
0, 0);
|
||||
fail_alloc_ring:
|
||||
cpu_physical_memory_unmap(vq->used, virtio_queue_get_used_size(vdev, idx),
|
||||
0, 0);
|
||||
fail_alloc_used:
|
||||
@@ -959,8 +989,6 @@ static void vhost_virtqueue_stop(struct vhost_dev *dev,
|
||||
vhost_vq_index);
|
||||
}
|
||||
|
||||
cpu_physical_memory_unmap(vq->ring, virtio_queue_get_ring_size(vdev, idx),
|
||||
0, virtio_queue_get_ring_size(vdev, idx));
|
||||
cpu_physical_memory_unmap(vq->used, virtio_queue_get_used_size(vdev, idx),
|
||||
1, virtio_queue_get_used_size(vdev, idx));
|
||||
cpu_physical_memory_unmap(vq->avail, virtio_queue_get_avail_size(vdev, idx),
|
||||
|
||||
@@ -463,6 +463,7 @@ static void virtio_balloon_device_reset(VirtIODevice *vdev)
|
||||
VirtIOBalloon *s = VIRTIO_BALLOON(vdev);
|
||||
|
||||
if (s->stats_vq_elem != NULL) {
|
||||
virtqueue_discard(s->svq, s->stats_vq_elem, 0);
|
||||
g_free(s->stats_vq_elem);
|
||||
s->stats_vq_elem = NULL;
|
||||
}
|
||||
|
||||
@@ -1192,7 +1192,9 @@ static uint64_t virtio_pci_common_read(void *opaque, hwaddr addr,
|
||||
break;
|
||||
case VIRTIO_PCI_COMMON_DF:
|
||||
if (proxy->dfselect <= 1) {
|
||||
val = (vdev->host_features & ~VIRTIO_LEGACY_FEATURES) >>
|
||||
VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
|
||||
|
||||
val = (vdev->host_features & ~vdc->legacy_features) >>
|
||||
(32 * proxy->dfselect);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -268,6 +268,7 @@ void virtqueue_discard(VirtQueue *vq, const VirtQueueElement *elem,
|
||||
unsigned int len)
|
||||
{
|
||||
vq->last_avail_idx--;
|
||||
vq->inuse--;
|
||||
virtqueue_unmap_sg(vq, elem, len);
|
||||
}
|
||||
|
||||
@@ -821,6 +822,7 @@ void virtio_reset(void *opaque)
|
||||
vdev->vq[i].signalled_used_valid = false;
|
||||
vdev->vq[i].notification = true;
|
||||
vdev->vq[i].vring.num = vdev->vq[i].vring.num_default;
|
||||
vdev->vq[i].inuse = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1648,6 +1650,21 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
|
||||
}
|
||||
vdev->vq[i].used_idx = vring_used_idx(&vdev->vq[i]);
|
||||
vdev->vq[i].shadow_avail_idx = vring_avail_idx(&vdev->vq[i]);
|
||||
|
||||
/*
|
||||
* Some devices migrate VirtQueueElements that have been popped
|
||||
* from the avail ring but not yet returned to the used ring.
|
||||
*/
|
||||
vdev->vq[i].inuse = vdev->vq[i].last_avail_idx -
|
||||
vdev->vq[i].used_idx;
|
||||
if (vdev->vq[i].inuse > vdev->vq[i].vring.num) {
|
||||
error_report("VQ %d size 0x%x < last_avail_idx 0x%x - "
|
||||
"used_idx 0x%x",
|
||||
i, vdev->vq[i].vring.num,
|
||||
vdev->vq[i].last_avail_idx,
|
||||
vdev->vq[i].used_idx);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1949,12 +1966,15 @@ static Property virtio_properties[] = {
|
||||
static void virtio_device_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
/* Set the default value here. */
|
||||
VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
dc->realize = virtio_device_realize;
|
||||
dc->unrealize = virtio_device_unrealize;
|
||||
dc->bus_type = TYPE_VIRTIO_BUS;
|
||||
dc->props = virtio_properties;
|
||||
|
||||
vdc->legacy_features |= VIRTIO_LEGACY_FEATURES;
|
||||
}
|
||||
|
||||
static const TypeInfo virtio_device_info = {
|
||||
|
||||
@@ -336,6 +336,7 @@ int bdrv_inactivate_all(void);
|
||||
/* Ensure contents are flushed to disk. */
|
||||
int bdrv_flush(BlockDriverState *bs);
|
||||
int coroutine_fn bdrv_co_flush(BlockDriverState *bs);
|
||||
int bdrv_flush_all(void);
|
||||
void bdrv_close_all(void);
|
||||
void bdrv_drain(BlockDriverState *bs);
|
||||
void coroutine_fn bdrv_co_drain(BlockDriverState *bs);
|
||||
|
||||
@@ -443,8 +443,8 @@ struct BlockDriverState {
|
||||
note this is a reference count */
|
||||
|
||||
CoQueue flush_queue; /* Serializing flush queue */
|
||||
BdrvTrackedRequest *active_flush_req; /* Flush request in flight */
|
||||
unsigned int write_gen; /* Current data generation */
|
||||
unsigned int flush_started_gen; /* Generation for which flush has started */
|
||||
unsigned int flushed_gen; /* Flushed write generation */
|
||||
|
||||
BlockDriver *drv; /* NULL means no media */
|
||||
|
||||
+32
-15
@@ -188,7 +188,7 @@ struct MemoryRegion {
|
||||
void (*destructor)(MemoryRegion *mr);
|
||||
uint64_t align;
|
||||
bool terminates;
|
||||
bool skip_dump;
|
||||
bool ram_device;
|
||||
bool enabled;
|
||||
bool warning_printed; /* For reservations */
|
||||
uint8_t vga_logging_count;
|
||||
@@ -425,6 +425,30 @@ void memory_region_init_ram_ptr(MemoryRegion *mr,
|
||||
uint64_t size,
|
||||
void *ptr);
|
||||
|
||||
/**
|
||||
* memory_region_init_ram_device_ptr: Initialize RAM device memory region from
|
||||
* a user-provided pointer.
|
||||
*
|
||||
* A RAM device represents a mapping to a physical device, such as to a PCI
|
||||
* MMIO BAR of an vfio-pci assigned device. The memory region may be mapped
|
||||
* into the VM address space and access to the region will modify memory
|
||||
* directly. However, the memory region should not be included in a memory
|
||||
* dump (device may not be enabled/mapped at the time of the dump), and
|
||||
* operations incompatible with manipulating MMIO should be avoided. Replaces
|
||||
* skip_dump flag.
|
||||
*
|
||||
* @mr: the #MemoryRegion to be initialized.
|
||||
* @owner: the object that tracks the region's reference count
|
||||
* @name: the name of the region.
|
||||
* @size: size of the region.
|
||||
* @ptr: memory to be mapped; must contain at least @size bytes.
|
||||
*/
|
||||
void memory_region_init_ram_device_ptr(MemoryRegion *mr,
|
||||
struct Object *owner,
|
||||
const char *name,
|
||||
uint64_t size,
|
||||
void *ptr);
|
||||
|
||||
/**
|
||||
* memory_region_init_alias: Initialize a memory region that aliases all or a
|
||||
* part of another memory region.
|
||||
@@ -551,22 +575,13 @@ static inline bool memory_region_is_ram(MemoryRegion *mr)
|
||||
}
|
||||
|
||||
/**
|
||||
* memory_region_is_skip_dump: check whether a memory region should not be
|
||||
* dumped
|
||||
* memory_region_is_ram_device: check whether a memory region is a ram device
|
||||
*
|
||||
* Returns %true is a memory region should not be dumped(e.g. VFIO BAR MMAP).
|
||||
* Returns %true is a memory region is a device backed ram region
|
||||
*
|
||||
* @mr: the memory region being queried
|
||||
*/
|
||||
bool memory_region_is_skip_dump(MemoryRegion *mr);
|
||||
|
||||
/**
|
||||
* memory_region_set_skip_dump: Set skip_dump flag, dump will ignore this memory
|
||||
* region
|
||||
*
|
||||
* @mr: the memory region being queried
|
||||
*/
|
||||
void memory_region_set_skip_dump(MemoryRegion *mr);
|
||||
bool memory_region_is_ram_device(MemoryRegion *mr);
|
||||
|
||||
/**
|
||||
* memory_region_is_romd: check whether a memory region is in ROMD mode
|
||||
@@ -1431,9 +1446,11 @@ void *qemu_map_ram_ptr(RAMBlock *ram_block, ram_addr_t addr);
|
||||
static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
|
||||
{
|
||||
if (is_write) {
|
||||
return memory_region_is_ram(mr) && !mr->readonly;
|
||||
return memory_region_is_ram(mr) &&
|
||||
!mr->readonly && !memory_region_is_ram_device(mr);
|
||||
} else {
|
||||
return memory_region_is_ram(mr) || memory_region_is_romd(mr);
|
||||
return (memory_region_is_ram(mr) && !memory_region_is_ram_device(mr)) ||
|
||||
memory_region_is_romd(mr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,26 @@ static inline gint64 qemu_g_get_monotonic_time(void)
|
||||
gint g_poll_fixed(GPollFD *fds, guint nfds, gint timeout);
|
||||
#endif
|
||||
|
||||
#if !GLIB_CHECK_VERSION(2, 30, 0)
|
||||
/* Not a 100% compatible implementation, but good enough for most
|
||||
* cases. Placeholders are only supported at the end of the
|
||||
* template. */
|
||||
static inline gchar *qemu_g_dir_make_tmp(gchar const *tmpl, GError **error)
|
||||
{
|
||||
gchar *path = g_build_filename(g_get_tmp_dir(), tmpl ?: ".XXXXXX", NULL);
|
||||
|
||||
if (mkdtemp(path) != NULL) {
|
||||
return path;
|
||||
}
|
||||
/* Error occurred, clean up. */
|
||||
g_set_error(error, G_FILE_ERROR, g_file_error_from_errno(errno),
|
||||
"mkdtemp() failed");
|
||||
g_free(path);
|
||||
return NULL;
|
||||
}
|
||||
#define g_dir_make_tmp(tmpl, error) qemu_g_dir_make_tmp(tmpl, error)
|
||||
#endif /* glib 2.30 */
|
||||
|
||||
#if !GLIB_CHECK_VERSION(2, 31, 0)
|
||||
/* before glib-2.31, GMutex and GCond was dynamic-only (there was a separate
|
||||
* GStaticMutex, but it didn't work with condition variables).
|
||||
|
||||
@@ -480,6 +480,9 @@ struct IDEBus {
|
||||
uint8_t retry_unit;
|
||||
int64_t retry_sector_num;
|
||||
uint32_t retry_nsector;
|
||||
PortioList portio_list;
|
||||
PortioList portio2_list;
|
||||
VMChangeStateEntry *vmstate;
|
||||
};
|
||||
|
||||
#define TYPE_IDE_DEVICE "ide-device"
|
||||
|
||||
@@ -36,6 +36,8 @@ typedef struct I8257State {
|
||||
QEMUBH *dma_bh;
|
||||
bool dma_bh_scheduled;
|
||||
int running;
|
||||
PortioList portio_page;
|
||||
PortioList portio_pageh;
|
||||
} I8257State;
|
||||
|
||||
#endif
|
||||
@@ -134,12 +134,15 @@ void isa_register_ioport(ISADevice *dev, MemoryRegion *io, uint16_t start);
|
||||
* device and use the legacy portio routines.
|
||||
*
|
||||
* @dev: the ISADevice against which these are registered; may be NULL.
|
||||
* @piolist: the PortioList associated with the io ports
|
||||
* @start: the base I/O port against which the portio->offset is applied.
|
||||
* @portio: the ports, sorted by offset.
|
||||
* @opaque: passed into the portio callbacks.
|
||||
* @name: passed into memory_region_init_io.
|
||||
*/
|
||||
void isa_register_portio_list(ISADevice *dev, uint16_t start,
|
||||
void isa_register_portio_list(ISADevice *dev,
|
||||
PortioList *piolist,
|
||||
uint16_t start,
|
||||
const MemoryRegionPortio *portio,
|
||||
void *opaque, const char *name);
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#define MAX_DEVNO 65535
|
||||
#define MAX_SCHID 65535
|
||||
#define MAX_SSID 3
|
||||
#define MAX_CSSID 254 /* 255 is reserved */
|
||||
#define MAX_CSSID 255
|
||||
#define MAX_CHPID 255
|
||||
|
||||
#define MAX_CIWS 62
|
||||
|
||||
@@ -14,11 +14,12 @@ struct vhost_virtqueue {
|
||||
void *avail;
|
||||
void *used;
|
||||
int num;
|
||||
unsigned long long desc_phys;
|
||||
unsigned desc_size;
|
||||
unsigned long long avail_phys;
|
||||
unsigned avail_size;
|
||||
unsigned long long used_phys;
|
||||
unsigned used_size;
|
||||
void *ring;
|
||||
unsigned long long ring_phys;
|
||||
unsigned ring_size;
|
||||
EventNotifier masked_notifier;
|
||||
};
|
||||
|
||||
|
||||
@@ -112,6 +112,11 @@ typedef struct VirtioDeviceClass {
|
||||
void (*set_config)(VirtIODevice *vdev, const uint8_t *config);
|
||||
void (*reset)(VirtIODevice *vdev);
|
||||
void (*set_status)(VirtIODevice *vdev, uint8_t val);
|
||||
/* For transitional devices, this is a bitmap of features
|
||||
* that are only exposed on the legacy interface but not
|
||||
* the modern one.
|
||||
*/
|
||||
uint64_t legacy_features;
|
||||
/* Test and clear event pending status.
|
||||
* Should be called after unmask to avoid losing events.
|
||||
* If backend does not support masking,
|
||||
|
||||
@@ -611,6 +611,37 @@
|
||||
#define KEY_KBDINPUTASSIST_ACCEPT 0x264
|
||||
#define KEY_KBDINPUTASSIST_CANCEL 0x265
|
||||
|
||||
/* Diagonal movement keys */
|
||||
#define KEY_RIGHT_UP 0x266
|
||||
#define KEY_RIGHT_DOWN 0x267
|
||||
#define KEY_LEFT_UP 0x268
|
||||
#define KEY_LEFT_DOWN 0x269
|
||||
|
||||
#define KEY_ROOT_MENU 0x26a /* Show Device's Root Menu */
|
||||
/* Show Top Menu of the Media (e.g. DVD) */
|
||||
#define KEY_MEDIA_TOP_MENU 0x26b
|
||||
#define KEY_NUMERIC_11 0x26c
|
||||
#define KEY_NUMERIC_12 0x26d
|
||||
/*
|
||||
* Toggle Audio Description: refers to an audio service that helps blind and
|
||||
* visually impaired consumers understand the action in a program. Note: in
|
||||
* some countries this is referred to as "Video Description".
|
||||
*/
|
||||
#define KEY_AUDIO_DESC 0x26e
|
||||
#define KEY_3D_MODE 0x26f
|
||||
#define KEY_NEXT_FAVORITE 0x270
|
||||
#define KEY_STOP_RECORD 0x271
|
||||
#define KEY_PAUSE_RECORD 0x272
|
||||
#define KEY_VOD 0x273 /* Video on Demand */
|
||||
#define KEY_UNMUTE 0x274
|
||||
#define KEY_FASTREVERSE 0x275
|
||||
#define KEY_SLOWREVERSE 0x276
|
||||
/*
|
||||
* Control a data application associated with the currently viewed channel,
|
||||
* e.g. teletext or data broadcast application (MHEG, MHP, HbbTV, etc.)
|
||||
*/
|
||||
#define KEY_DATA 0x275
|
||||
|
||||
#define BTN_TRIGGER_HAPPY 0x2c0
|
||||
#define BTN_TRIGGER_HAPPY1 0x2c0
|
||||
#define BTN_TRIGGER_HAPPY2 0x2c1
|
||||
@@ -749,6 +780,7 @@
|
||||
#define SW_ROTATE_LOCK 0x0c /* set = rotate locked/disabled */
|
||||
#define SW_LINEIN_INSERT 0x0d /* set = inserted */
|
||||
#define SW_MUTE_DEVICE 0x0e /* set = device disabled */
|
||||
#define SW_PEN_INSERTED 0x0f /* set = pen inserted */
|
||||
#define SW_MAX_ 0x0f
|
||||
#define SW_CNT (SW_MAX_+1)
|
||||
|
||||
|
||||
@@ -244,6 +244,7 @@ struct input_mask {
|
||||
#define BUS_ATARI 0x1B
|
||||
#define BUS_SPI 0x1C
|
||||
#define BUS_RMI 0x1D
|
||||
#define BUS_CEC 0x1E
|
||||
|
||||
/*
|
||||
* MT_TOOL types
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
* transport being used (eg. virtio_ring), the rest are per-device feature
|
||||
* bits. */
|
||||
#define VIRTIO_TRANSPORT_F_START 28
|
||||
#define VIRTIO_TRANSPORT_F_END 33
|
||||
#define VIRTIO_TRANSPORT_F_END 34
|
||||
|
||||
#ifndef VIRTIO_CONFIG_NO_LEGACY
|
||||
/* Do we get callbacks when the ring is completely used, even if we've
|
||||
@@ -63,4 +63,12 @@
|
||||
/* v1.0 compliant. */
|
||||
#define VIRTIO_F_VERSION_1 32
|
||||
|
||||
/*
|
||||
* If clear - device has the IOMMU bypass quirk feature.
|
||||
* If set - use platform tools to detect the IOMMU.
|
||||
*
|
||||
* Note the reverse polarity (compared to most other features),
|
||||
* this is for compatibility with legacy systems.
|
||||
*/
|
||||
#define VIRTIO_F_IOMMU_PLATFORM 33
|
||||
#endif /* _LINUX_VIRTIO_CONFIG_H */
|
||||
@@ -41,5 +41,6 @@
|
||||
#define VIRTIO_ID_CAIF 12 /* Virtio caif */
|
||||
#define VIRTIO_ID_GPU 16 /* virtio GPU */
|
||||
#define VIRTIO_ID_INPUT 18 /* virtio input */
|
||||
#define VIRTIO_ID_VSOCK 19 /* virtio vsock transport */
|
||||
|
||||
#endif /* _LINUX_VIRTIO_IDS_H */
|
||||
@@ -35,6 +35,7 @@
|
||||
#define VIRTIO_NET_F_CSUM 0 /* Host handles pkts w/ partial csum */
|
||||
#define VIRTIO_NET_F_GUEST_CSUM 1 /* Guest handles pkts w/ partial csum */
|
||||
#define VIRTIO_NET_F_CTRL_GUEST_OFFLOADS 2 /* Dynamic offload configuration. */
|
||||
#define VIRTIO_NET_F_MTU 3 /* Initial MTU advice */
|
||||
#define VIRTIO_NET_F_MAC 5 /* Host has given MAC address. */
|
||||
#define VIRTIO_NET_F_GUEST_TSO4 7 /* Guest can handle TSOv4 in. */
|
||||
#define VIRTIO_NET_F_GUEST_TSO6 8 /* Guest can handle TSOv6 in. */
|
||||
@@ -73,6 +74,8 @@ struct virtio_net_config {
|
||||
* Legal values are between 1 and 0x8000
|
||||
*/
|
||||
uint16_t max_virtqueue_pairs;
|
||||
/* Default maximum transmit unit advice */
|
||||
uint16_t mtu;
|
||||
} QEMU_PACKED;
|
||||
|
||||
/*
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so
|
||||
* anyone can use the definitions to implement compatible drivers/servers:
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of IBM nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Copyright (C) Red Hat, Inc., 2013-2015
|
||||
* Copyright (C) Asias He <asias@redhat.com>, 2013
|
||||
* Copyright (C) Stefan Hajnoczi <stefanha@redhat.com>, 2015
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_VIRTIO_VSOCK_H
|
||||
#define _LINUX_VIRTIO_VSOCK_H
|
||||
|
||||
#include "standard-headers/linux/types.h"
|
||||
#include "standard-headers/linux/virtio_ids.h"
|
||||
#include "standard-headers/linux/virtio_config.h"
|
||||
|
||||
struct virtio_vsock_config {
|
||||
uint64_t guest_cid;
|
||||
} QEMU_PACKED;
|
||||
|
||||
enum virtio_vsock_event_id {
|
||||
VIRTIO_VSOCK_EVENT_TRANSPORT_RESET = 0,
|
||||
};
|
||||
|
||||
struct virtio_vsock_event {
|
||||
uint32_t id;
|
||||
} QEMU_PACKED;
|
||||
|
||||
struct virtio_vsock_hdr {
|
||||
uint64_t src_cid;
|
||||
uint64_t dst_cid;
|
||||
uint32_t src_port;
|
||||
uint32_t dst_port;
|
||||
uint32_t len;
|
||||
uint16_t type; /* enum virtio_vsock_type */
|
||||
uint16_t op; /* enum virtio_vsock_op */
|
||||
uint32_t flags;
|
||||
uint32_t buf_alloc;
|
||||
uint32_t fwd_cnt;
|
||||
} QEMU_PACKED;
|
||||
|
||||
enum virtio_vsock_type {
|
||||
VIRTIO_VSOCK_TYPE_STREAM = 1,
|
||||
};
|
||||
|
||||
enum virtio_vsock_op {
|
||||
VIRTIO_VSOCK_OP_INVALID = 0,
|
||||
|
||||
/* Connect operations */
|
||||
VIRTIO_VSOCK_OP_REQUEST = 1,
|
||||
VIRTIO_VSOCK_OP_RESPONSE = 2,
|
||||
VIRTIO_VSOCK_OP_RST = 3,
|
||||
VIRTIO_VSOCK_OP_SHUTDOWN = 4,
|
||||
|
||||
/* To send payload */
|
||||
VIRTIO_VSOCK_OP_RW = 5,
|
||||
|
||||
/* Tell the peer our credit info */
|
||||
VIRTIO_VSOCK_OP_CREDIT_UPDATE = 6,
|
||||
/* Request the peer to send the credit info to us */
|
||||
VIRTIO_VSOCK_OP_CREDIT_REQUEST = 7,
|
||||
};
|
||||
|
||||
/* VIRTIO_VSOCK_OP_SHUTDOWN flags values */
|
||||
enum virtio_vsock_shutdown {
|
||||
VIRTIO_VSOCK_SHUTDOWN_RCV = 1,
|
||||
VIRTIO_VSOCK_SHUTDOWN_SEND = 2,
|
||||
};
|
||||
|
||||
#endif /* _LINUX_VIRTIO_VSOCK_H */
|
||||
@@ -149,7 +149,6 @@ BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf,
|
||||
int blk_co_pdiscard(BlockBackend *blk, int64_t offset, int count);
|
||||
int blk_co_flush(BlockBackend *blk);
|
||||
int blk_flush(BlockBackend *blk);
|
||||
int blk_flush_all(void);
|
||||
int blk_commit_all(void);
|
||||
void blk_drain(BlockBackend *blk);
|
||||
void blk_drain_all(void);
|
||||
|
||||
@@ -199,14 +199,14 @@ typedef BlockAIOCB *DMAIOFunc(int64_t offset, QEMUIOVector *iov,
|
||||
void *opaque);
|
||||
|
||||
BlockAIOCB *dma_blk_io(AioContext *ctx,
|
||||
QEMUSGList *sg, uint64_t offset,
|
||||
QEMUSGList *sg, uint64_t offset, uint32_t align,
|
||||
DMAIOFunc *io_func, void *io_func_opaque,
|
||||
BlockCompletionFunc *cb, void *opaque, DMADirection dir);
|
||||
BlockAIOCB *dma_blk_read(BlockBackend *blk,
|
||||
QEMUSGList *sg, uint64_t offset,
|
||||
QEMUSGList *sg, uint64_t offset, uint32_t align,
|
||||
BlockCompletionFunc *cb, void *opaque);
|
||||
BlockAIOCB *dma_blk_write(BlockBackend *blk,
|
||||
QEMUSGList *sg, uint64_t offset,
|
||||
QEMUSGList *sg, uint64_t offset, uint32_t align,
|
||||
BlockCompletionFunc *cb, void *opaque);
|
||||
uint64_t dma_buf_read(uint8_t *ptr, int32_t len, QEMUSGList *sg);
|
||||
uint64_t dma_buf_write(uint8_t *ptr, int32_t len, QEMUSGList *sg);
|
||||
|
||||
@@ -35,5 +35,6 @@ typedef struct {
|
||||
|
||||
char *iothread_get_id(IOThread *iothread);
|
||||
AioContext *iothread_get_aio_context(IOThread *iothread);
|
||||
void iothread_stop_all(void);
|
||||
|
||||
#endif /* IOTHREAD_H */
|
||||
+20
-4
@@ -54,16 +54,25 @@ static void *iothread_run(void *opaque)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void iothread_instance_finalize(Object *obj)
|
||||
static int iothread_stop(Object *object, void *opaque)
|
||||
{
|
||||
IOThread *iothread = IOTHREAD(obj);
|
||||
IOThread *iothread;
|
||||
|
||||
if (!iothread->ctx) {
|
||||
return;
|
||||
iothread = (IOThread *)object_dynamic_cast(object, TYPE_IOTHREAD);
|
||||
if (!iothread || !iothread->ctx) {
|
||||
return 0;
|
||||
}
|
||||
iothread->stopping = true;
|
||||
aio_notify(iothread->ctx);
|
||||
qemu_thread_join(&iothread->thread);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void iothread_instance_finalize(Object *obj)
|
||||
{
|
||||
IOThread *iothread = IOTHREAD(obj);
|
||||
|
||||
iothread_stop(obj, NULL);
|
||||
qemu_cond_destroy(&iothread->init_done_cond);
|
||||
qemu_mutex_destroy(&iothread->init_done_lock);
|
||||
aio_context_unref(iothread->ctx);
|
||||
@@ -174,3 +183,10 @@ IOThreadInfoList *qmp_query_iothreads(Error **errp)
|
||||
object_child_foreach(container, query_one_iothread, &prev);
|
||||
return head;
|
||||
}
|
||||
|
||||
void iothread_stop_all(void)
|
||||
{
|
||||
Object *container = object_get_objects_root();
|
||||
|
||||
object_child_foreach(container, iothread_stop, NULL);
|
||||
}
|
||||
@@ -139,8 +139,8 @@ struct kvm_arch_memory_slot {
|
||||
#define ARM_CP15_REG64(...) __ARM_CP15_REG64(__VA_ARGS__)
|
||||
|
||||
#define KVM_REG_ARM_TIMER_CTL ARM_CP15_REG32(0, 14, 3, 1)
|
||||
#define KVM_REG_ARM_TIMER_CNT ARM_CP15_REG64(1, 14)
|
||||
#define KVM_REG_ARM_TIMER_CVAL ARM_CP15_REG64(3, 14)
|
||||
#define KVM_REG_ARM_TIMER_CNT ARM_CP15_REG64(1, 14)
|
||||
#define KVM_REG_ARM_TIMER_CVAL ARM_CP15_REG64(3, 14)
|
||||
|
||||
/* Normal registers are mapped as coprocessor 16. */
|
||||
#define KVM_REG_ARM_CORE (0x0010 << KVM_REG_ARM_COPROC_SHIFT)
|
||||
|
||||
@@ -87,9 +87,11 @@ struct kvm_regs {
|
||||
/* Supported VGICv3 address types */
|
||||
#define KVM_VGIC_V3_ADDR_TYPE_DIST 2
|
||||
#define KVM_VGIC_V3_ADDR_TYPE_REDIST 3
|
||||
#define KVM_VGIC_ITS_ADDR_TYPE 4
|
||||
|
||||
#define KVM_VGIC_V3_DIST_SIZE SZ_64K
|
||||
#define KVM_VGIC_V3_REDIST_SIZE (2 * SZ_64K)
|
||||
#define KVM_VGIC_V3_ITS_SIZE (2 * SZ_64K)
|
||||
|
||||
#define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
|
||||
#define KVM_ARM_VCPU_EL1_32BIT 1 /* CPU running a 32bit VM */
|
||||
|
||||
@@ -93,6 +93,47 @@ struct kvm_s390_vm_cpu_machine {
|
||||
__u64 fac_list[256];
|
||||
};
|
||||
|
||||
#define KVM_S390_VM_CPU_PROCESSOR_FEAT 2
|
||||
#define KVM_S390_VM_CPU_MACHINE_FEAT 3
|
||||
|
||||
#define KVM_S390_VM_CPU_FEAT_NR_BITS 1024
|
||||
#define KVM_S390_VM_CPU_FEAT_ESOP 0
|
||||
#define KVM_S390_VM_CPU_FEAT_SIEF2 1
|
||||
#define KVM_S390_VM_CPU_FEAT_64BSCAO 2
|
||||
#define KVM_S390_VM_CPU_FEAT_SIIF 3
|
||||
#define KVM_S390_VM_CPU_FEAT_GPERE 4
|
||||
#define KVM_S390_VM_CPU_FEAT_GSLS 5
|
||||
#define KVM_S390_VM_CPU_FEAT_IB 6
|
||||
#define KVM_S390_VM_CPU_FEAT_CEI 7
|
||||
#define KVM_S390_VM_CPU_FEAT_IBS 8
|
||||
#define KVM_S390_VM_CPU_FEAT_SKEY 9
|
||||
#define KVM_S390_VM_CPU_FEAT_CMMA 10
|
||||
#define KVM_S390_VM_CPU_FEAT_PFMFI 11
|
||||
#define KVM_S390_VM_CPU_FEAT_SIGPIF 12
|
||||
struct kvm_s390_vm_cpu_feat {
|
||||
__u64 feat[16];
|
||||
};
|
||||
|
||||
#define KVM_S390_VM_CPU_PROCESSOR_SUBFUNC 4
|
||||
#define KVM_S390_VM_CPU_MACHINE_SUBFUNC 5
|
||||
/* for "test bit" instructions MSB 0 bit ordering, for "query" raw blocks */
|
||||
struct kvm_s390_vm_cpu_subfunc {
|
||||
__u8 plo[32]; /* always */
|
||||
__u8 ptff[16]; /* with TOD-clock steering */
|
||||
__u8 kmac[16]; /* with MSA */
|
||||
__u8 kmc[16]; /* with MSA */
|
||||
__u8 km[16]; /* with MSA */
|
||||
__u8 kimd[16]; /* with MSA */
|
||||
__u8 klmd[16]; /* with MSA */
|
||||
__u8 pckmo[16]; /* with MSA3 */
|
||||
__u8 kmctr[16]; /* with MSA4 */
|
||||
__u8 kmf[16]; /* with MSA4 */
|
||||
__u8 kmo[16]; /* with MSA4 */
|
||||
__u8 pcc[16]; /* with MSA4 */
|
||||
__u8 ppno[16]; /* with MSA5 */
|
||||
__u8 reserved[1824];
|
||||
};
|
||||
|
||||
/* kvm attributes for crypto */
|
||||
#define KVM_S390_VM_CRYPTO_ENABLE_AES_KW 0
|
||||
#define KVM_S390_VM_CRYPTO_ENABLE_DEA_KW 1
|
||||
|
||||
@@ -306,9 +306,7 @@
|
||||
#define __NR_vmsplice (__X32_SYSCALL_BIT + 532)
|
||||
#define __NR_move_pages (__X32_SYSCALL_BIT + 533)
|
||||
#define __NR_preadv (__X32_SYSCALL_BIT + 534)
|
||||
#define __NR_preadv2 (__X32_SYSCALL_BIT + 534)
|
||||
#define __NR_pwritev (__X32_SYSCALL_BIT + 535)
|
||||
#define __NR_pwritev2 (__X32_SYSCALL_BIT + 535)
|
||||
#define __NR_rt_tgsigqueueinfo (__X32_SYSCALL_BIT + 536)
|
||||
#define __NR_recvmmsg (__X32_SYSCALL_BIT + 537)
|
||||
#define __NR_sendmmsg (__X32_SYSCALL_BIT + 538)
|
||||
@@ -319,5 +317,7 @@
|
||||
#define __NR_io_setup (__X32_SYSCALL_BIT + 543)
|
||||
#define __NR_io_submit (__X32_SYSCALL_BIT + 544)
|
||||
#define __NR_execveat (__X32_SYSCALL_BIT + 545)
|
||||
#define __NR_preadv2 (__X32_SYSCALL_BIT + 546)
|
||||
#define __NR_pwritev2 (__X32_SYSCALL_BIT + 547)
|
||||
|
||||
#endif /* _ASM_X86_UNISTD_X32_H */
|
||||
@@ -866,6 +866,10 @@ struct kvm_ppc_smmu_info {
|
||||
#define KVM_CAP_ARM_PMU_V3 126
|
||||
#define KVM_CAP_VCPU_ATTRIBUTES 127
|
||||
#define KVM_CAP_MAX_VCPU_ID 128
|
||||
#define KVM_CAP_X2APIC_API 129
|
||||
#define KVM_CAP_S390_USER_INSTR0 130
|
||||
#define KVM_CAP_MSI_DEVID 131
|
||||
#define KVM_CAP_PPC_HTM 132
|
||||
|
||||
#ifdef KVM_CAP_IRQ_ROUTING
|
||||
|
||||
@@ -878,7 +882,10 @@ struct kvm_irq_routing_msi {
|
||||
__u32 address_lo;
|
||||
__u32 address_hi;
|
||||
__u32 data;
|
||||
__u32 pad;
|
||||
union {
|
||||
__u32 pad;
|
||||
__u32 devid;
|
||||
};
|
||||
};
|
||||
|
||||
struct kvm_irq_routing_s390_adapter {
|
||||
@@ -1024,12 +1031,14 @@ struct kvm_one_reg {
|
||||
__u64 addr;
|
||||
};
|
||||
|
||||
#define KVM_MSI_VALID_DEVID (1U << 0)
|
||||
struct kvm_msi {
|
||||
__u32 address_lo;
|
||||
__u32 address_hi;
|
||||
__u32 data;
|
||||
__u32 flags;
|
||||
__u8 pad[16];
|
||||
__u32 devid;
|
||||
__u8 pad[12];
|
||||
};
|
||||
|
||||
struct kvm_arm_device_addr {
|
||||
@@ -1074,6 +1083,8 @@ enum kvm_device_type {
|
||||
#define KVM_DEV_TYPE_FLIC KVM_DEV_TYPE_FLIC
|
||||
KVM_DEV_TYPE_ARM_VGIC_V3,
|
||||
#define KVM_DEV_TYPE_ARM_VGIC_V3 KVM_DEV_TYPE_ARM_VGIC_V3
|
||||
KVM_DEV_TYPE_ARM_VGIC_ITS,
|
||||
#define KVM_DEV_TYPE_ARM_VGIC_ITS KVM_DEV_TYPE_ARM_VGIC_ITS
|
||||
KVM_DEV_TYPE_MAX,
|
||||
};
|
||||
|
||||
@@ -1313,4 +1324,7 @@ struct kvm_assigned_msix_entry {
|
||||
__u16 padding[3];
|
||||
};
|
||||
|
||||
#define KVM_X2APIC_API_USE_32BIT_IDS (1ULL << 0)
|
||||
#define KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK (1ULL << 1)
|
||||
|
||||
#endif /* __LINUX_KVM_H */
|
||||
@@ -47,6 +47,32 @@ struct vhost_vring_addr {
|
||||
__u64 log_guest_addr;
|
||||
};
|
||||
|
||||
/* no alignment requirement */
|
||||
struct vhost_iotlb_msg {
|
||||
__u64 iova;
|
||||
__u64 size;
|
||||
__u64 uaddr;
|
||||
#define VHOST_ACCESS_RO 0x1
|
||||
#define VHOST_ACCESS_WO 0x2
|
||||
#define VHOST_ACCESS_RW 0x3
|
||||
__u8 perm;
|
||||
#define VHOST_IOTLB_MISS 1
|
||||
#define VHOST_IOTLB_UPDATE 2
|
||||
#define VHOST_IOTLB_INVALIDATE 3
|
||||
#define VHOST_IOTLB_ACCESS_FAIL 4
|
||||
__u8 type;
|
||||
};
|
||||
|
||||
#define VHOST_IOTLB_MSG 0x1
|
||||
|
||||
struct vhost_msg {
|
||||
int type;
|
||||
union {
|
||||
struct vhost_iotlb_msg iotlb;
|
||||
__u8 padding[64];
|
||||
};
|
||||
};
|
||||
|
||||
struct vhost_memory_region {
|
||||
__u64 guest_phys_addr;
|
||||
__u64 memory_size; /* bytes */
|
||||
@@ -146,6 +172,8 @@ struct vhost_memory {
|
||||
#define VHOST_F_LOG_ALL 26
|
||||
/* vhost-net should add virtio_net_hdr for RX, and strip for TX packets. */
|
||||
#define VHOST_NET_F_VIRTIO_NET_HDR 27
|
||||
/* Vhost have device IOTLB */
|
||||
#define VHOST_F_DEVICE_IOTLB 63
|
||||
|
||||
/* VHOST_SCSI specific definitions */
|
||||
|
||||
@@ -175,4 +203,9 @@ struct vhost_scsi_target {
|
||||
#define VHOST_SCSI_SET_EVENTS_MISSED _IOW(VHOST_VIRTIO, 0x43, __u32)
|
||||
#define VHOST_SCSI_GET_EVENTS_MISSED _IOW(VHOST_VIRTIO, 0x44, __u32)
|
||||
|
||||
/* VHOST_VSOCK specific defines */
|
||||
|
||||
#define VHOST_VSOCK_SET_GUEST_CID _IOW(VHOST_VIRTIO, 0x60, __u64)
|
||||
#define VHOST_VSOCK_SET_RUNNING _IOW(VHOST_VIRTIO, 0x61, int)
|
||||
|
||||
#endif
|
||||
+264
-195
@@ -289,6 +289,161 @@ static bitmask_transtbl fcntl_flags_tbl[] = {
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
enum {
|
||||
QEMU_IFLA_BR_UNSPEC,
|
||||
QEMU_IFLA_BR_FORWARD_DELAY,
|
||||
QEMU_IFLA_BR_HELLO_TIME,
|
||||
QEMU_IFLA_BR_MAX_AGE,
|
||||
QEMU_IFLA_BR_AGEING_TIME,
|
||||
QEMU_IFLA_BR_STP_STATE,
|
||||
QEMU_IFLA_BR_PRIORITY,
|
||||
QEMU_IFLA_BR_VLAN_FILTERING,
|
||||
QEMU_IFLA_BR_VLAN_PROTOCOL,
|
||||
QEMU_IFLA_BR_GROUP_FWD_MASK,
|
||||
QEMU_IFLA_BR_ROOT_ID,
|
||||
QEMU_IFLA_BR_BRIDGE_ID,
|
||||
QEMU_IFLA_BR_ROOT_PORT,
|
||||
QEMU_IFLA_BR_ROOT_PATH_COST,
|
||||
QEMU_IFLA_BR_TOPOLOGY_CHANGE,
|
||||
QEMU_IFLA_BR_TOPOLOGY_CHANGE_DETECTED,
|
||||
QEMU_IFLA_BR_HELLO_TIMER,
|
||||
QEMU_IFLA_BR_TCN_TIMER,
|
||||
QEMU_IFLA_BR_TOPOLOGY_CHANGE_TIMER,
|
||||
QEMU_IFLA_BR_GC_TIMER,
|
||||
QEMU_IFLA_BR_GROUP_ADDR,
|
||||
QEMU_IFLA_BR_FDB_FLUSH,
|
||||
QEMU_IFLA_BR_MCAST_ROUTER,
|
||||
QEMU_IFLA_BR_MCAST_SNOOPING,
|
||||
QEMU_IFLA_BR_MCAST_QUERY_USE_IFADDR,
|
||||
QEMU_IFLA_BR_MCAST_QUERIER,
|
||||
QEMU_IFLA_BR_MCAST_HASH_ELASTICITY,
|
||||
QEMU_IFLA_BR_MCAST_HASH_MAX,
|
||||
QEMU_IFLA_BR_MCAST_LAST_MEMBER_CNT,
|
||||
QEMU_IFLA_BR_MCAST_STARTUP_QUERY_CNT,
|
||||
QEMU_IFLA_BR_MCAST_LAST_MEMBER_INTVL,
|
||||
QEMU_IFLA_BR_MCAST_MEMBERSHIP_INTVL,
|
||||
QEMU_IFLA_BR_MCAST_QUERIER_INTVL,
|
||||
QEMU_IFLA_BR_MCAST_QUERY_INTVL,
|
||||
QEMU_IFLA_BR_MCAST_QUERY_RESPONSE_INTVL,
|
||||
QEMU_IFLA_BR_MCAST_STARTUP_QUERY_INTVL,
|
||||
QEMU_IFLA_BR_NF_CALL_IPTABLES,
|
||||
QEMU_IFLA_BR_NF_CALL_IP6TABLES,
|
||||
QEMU_IFLA_BR_NF_CALL_ARPTABLES,
|
||||
QEMU_IFLA_BR_VLAN_DEFAULT_PVID,
|
||||
QEMU_IFLA_BR_PAD,
|
||||
QEMU_IFLA_BR_VLAN_STATS_ENABLED,
|
||||
QEMU_IFLA_BR_MCAST_STATS_ENABLED,
|
||||
QEMU___IFLA_BR_MAX,
|
||||
};
|
||||
|
||||
enum {
|
||||
QEMU_IFLA_UNSPEC,
|
||||
QEMU_IFLA_ADDRESS,
|
||||
QEMU_IFLA_BROADCAST,
|
||||
QEMU_IFLA_IFNAME,
|
||||
QEMU_IFLA_MTU,
|
||||
QEMU_IFLA_LINK,
|
||||
QEMU_IFLA_QDISC,
|
||||
QEMU_IFLA_STATS,
|
||||
QEMU_IFLA_COST,
|
||||
QEMU_IFLA_PRIORITY,
|
||||
QEMU_IFLA_MASTER,
|
||||
QEMU_IFLA_WIRELESS,
|
||||
QEMU_IFLA_PROTINFO,
|
||||
QEMU_IFLA_TXQLEN,
|
||||
QEMU_IFLA_MAP,
|
||||
QEMU_IFLA_WEIGHT,
|
||||
QEMU_IFLA_OPERSTATE,
|
||||
QEMU_IFLA_LINKMODE,
|
||||
QEMU_IFLA_LINKINFO,
|
||||
QEMU_IFLA_NET_NS_PID,
|
||||
QEMU_IFLA_IFALIAS,
|
||||
QEMU_IFLA_NUM_VF,
|
||||
QEMU_IFLA_VFINFO_LIST,
|
||||
QEMU_IFLA_STATS64,
|
||||
QEMU_IFLA_VF_PORTS,
|
||||
QEMU_IFLA_PORT_SELF,
|
||||
QEMU_IFLA_AF_SPEC,
|
||||
QEMU_IFLA_GROUP,
|
||||
QEMU_IFLA_NET_NS_FD,
|
||||
QEMU_IFLA_EXT_MASK,
|
||||
QEMU_IFLA_PROMISCUITY,
|
||||
QEMU_IFLA_NUM_TX_QUEUES,
|
||||
QEMU_IFLA_NUM_RX_QUEUES,
|
||||
QEMU_IFLA_CARRIER,
|
||||
QEMU_IFLA_PHYS_PORT_ID,
|
||||
QEMU_IFLA_CARRIER_CHANGES,
|
||||
QEMU_IFLA_PHYS_SWITCH_ID,
|
||||
QEMU_IFLA_LINK_NETNSID,
|
||||
QEMU_IFLA_PHYS_PORT_NAME,
|
||||
QEMU_IFLA_PROTO_DOWN,
|
||||
QEMU_IFLA_GSO_MAX_SEGS,
|
||||
QEMU_IFLA_GSO_MAX_SIZE,
|
||||
QEMU_IFLA_PAD,
|
||||
QEMU_IFLA_XDP,
|
||||
QEMU___IFLA_MAX
|
||||
};
|
||||
|
||||
enum {
|
||||
QEMU_IFLA_BRPORT_UNSPEC,
|
||||
QEMU_IFLA_BRPORT_STATE,
|
||||
QEMU_IFLA_BRPORT_PRIORITY,
|
||||
QEMU_IFLA_BRPORT_COST,
|
||||
QEMU_IFLA_BRPORT_MODE,
|
||||
QEMU_IFLA_BRPORT_GUARD,
|
||||
QEMU_IFLA_BRPORT_PROTECT,
|
||||
QEMU_IFLA_BRPORT_FAST_LEAVE,
|
||||
QEMU_IFLA_BRPORT_LEARNING,
|
||||
QEMU_IFLA_BRPORT_UNICAST_FLOOD,
|
||||
QEMU_IFLA_BRPORT_PROXYARP,
|
||||
QEMU_IFLA_BRPORT_LEARNING_SYNC,
|
||||
QEMU_IFLA_BRPORT_PROXYARP_WIFI,
|
||||
QEMU_IFLA_BRPORT_ROOT_ID,
|
||||
QEMU_IFLA_BRPORT_BRIDGE_ID,
|
||||
QEMU_IFLA_BRPORT_DESIGNATED_PORT,
|
||||
QEMU_IFLA_BRPORT_DESIGNATED_COST,
|
||||
QEMU_IFLA_BRPORT_ID,
|
||||
QEMU_IFLA_BRPORT_NO,
|
||||
QEMU_IFLA_BRPORT_TOPOLOGY_CHANGE_ACK,
|
||||
QEMU_IFLA_BRPORT_CONFIG_PENDING,
|
||||
QEMU_IFLA_BRPORT_MESSAGE_AGE_TIMER,
|
||||
QEMU_IFLA_BRPORT_FORWARD_DELAY_TIMER,
|
||||
QEMU_IFLA_BRPORT_HOLD_TIMER,
|
||||
QEMU_IFLA_BRPORT_FLUSH,
|
||||
QEMU_IFLA_BRPORT_MULTICAST_ROUTER,
|
||||
QEMU_IFLA_BRPORT_PAD,
|
||||
QEMU___IFLA_BRPORT_MAX
|
||||
};
|
||||
|
||||
enum {
|
||||
QEMU_IFLA_INFO_UNSPEC,
|
||||
QEMU_IFLA_INFO_KIND,
|
||||
QEMU_IFLA_INFO_DATA,
|
||||
QEMU_IFLA_INFO_XSTATS,
|
||||
QEMU_IFLA_INFO_SLAVE_KIND,
|
||||
QEMU_IFLA_INFO_SLAVE_DATA,
|
||||
QEMU___IFLA_INFO_MAX,
|
||||
};
|
||||
|
||||
enum {
|
||||
QEMU_IFLA_INET_UNSPEC,
|
||||
QEMU_IFLA_INET_CONF,
|
||||
QEMU___IFLA_INET_MAX,
|
||||
};
|
||||
|
||||
enum {
|
||||
QEMU_IFLA_INET6_UNSPEC,
|
||||
QEMU_IFLA_INET6_FLAGS,
|
||||
QEMU_IFLA_INET6_CONF,
|
||||
QEMU_IFLA_INET6_STATS,
|
||||
QEMU_IFLA_INET6_MCAST,
|
||||
QEMU_IFLA_INET6_CACHEINFO,
|
||||
QEMU_IFLA_INET6_ICMP6STATS,
|
||||
QEMU_IFLA_INET6_TOKEN,
|
||||
QEMU_IFLA_INET6_ADDR_GEN_MODE,
|
||||
QEMU___IFLA_INET6_MAX
|
||||
};
|
||||
|
||||
typedef abi_long (*TargetFdDataFunc)(void *, size_t);
|
||||
typedef abi_long (*TargetFdAddrFunc)(void *, abi_ulong, socklen_t);
|
||||
typedef struct TargetFdTrans {
|
||||
@@ -1783,129 +1938,67 @@ static abi_long host_to_target_data_bridge_nlattr(struct nlattr *nlattr,
|
||||
uint64_t *u64;
|
||||
|
||||
switch (nlattr->nla_type) {
|
||||
#ifdef IFLA_BR_FDB_FLUSH
|
||||
/* no data */
|
||||
case IFLA_BR_FDB_FLUSH:
|
||||
case QEMU_IFLA_BR_FDB_FLUSH:
|
||||
break;
|
||||
#endif
|
||||
#ifdef IFLA_BR_GROUP_ADDR
|
||||
/* binary */
|
||||
case IFLA_BR_GROUP_ADDR:
|
||||
case QEMU_IFLA_BR_GROUP_ADDR:
|
||||
break;
|
||||
#endif
|
||||
/* uint8_t */
|
||||
case IFLA_BR_VLAN_FILTERING:
|
||||
#ifdef IFLA_BR_TOPOLOGY_CHANGE
|
||||
case IFLA_BR_TOPOLOGY_CHANGE:
|
||||
#endif
|
||||
#ifdef IFLA_BR_TOPOLOGY_CHANGE_DETECTED
|
||||
case IFLA_BR_TOPOLOGY_CHANGE_DETECTED:
|
||||
#endif
|
||||
#ifdef IFLA_BR_MCAST_ROUTER
|
||||
case IFLA_BR_MCAST_ROUTER:
|
||||
#endif
|
||||
#ifdef IFLA_BR_MCAST_SNOOPING
|
||||
case IFLA_BR_MCAST_SNOOPING:
|
||||
#endif
|
||||
#ifdef IFLA_BR_MCAST_QUERY_USE_IFADDR
|
||||
case IFLA_BR_MCAST_QUERY_USE_IFADDR:
|
||||
#endif
|
||||
#ifdef IFLA_BR_MCAST_QUERIER
|
||||
case IFLA_BR_MCAST_QUERIER:
|
||||
#endif
|
||||
#ifdef IFLA_BR_NF_CALL_IPTABLES
|
||||
case IFLA_BR_NF_CALL_IPTABLES:
|
||||
#endif
|
||||
#ifdef IFLA_BR_NF_CALL_IP6TABLES
|
||||
case IFLA_BR_NF_CALL_IP6TABLES:
|
||||
#endif
|
||||
#ifdef IFLA_BR_NF_CALL_ARPTABLES
|
||||
case IFLA_BR_NF_CALL_ARPTABLES:
|
||||
#endif
|
||||
case QEMU_IFLA_BR_VLAN_FILTERING:
|
||||
case QEMU_IFLA_BR_TOPOLOGY_CHANGE:
|
||||
case QEMU_IFLA_BR_TOPOLOGY_CHANGE_DETECTED:
|
||||
case QEMU_IFLA_BR_MCAST_ROUTER:
|
||||
case QEMU_IFLA_BR_MCAST_SNOOPING:
|
||||
case QEMU_IFLA_BR_MCAST_QUERY_USE_IFADDR:
|
||||
case QEMU_IFLA_BR_MCAST_QUERIER:
|
||||
case QEMU_IFLA_BR_NF_CALL_IPTABLES:
|
||||
case QEMU_IFLA_BR_NF_CALL_IP6TABLES:
|
||||
case QEMU_IFLA_BR_NF_CALL_ARPTABLES:
|
||||
break;
|
||||
/* uint16_t */
|
||||
case IFLA_BR_PRIORITY:
|
||||
case IFLA_BR_VLAN_PROTOCOL:
|
||||
#ifdef IFLA_BR_GROUP_FWD_MASK
|
||||
case IFLA_BR_GROUP_FWD_MASK:
|
||||
#endif
|
||||
#ifdef IFLA_BR_ROOT_PORT
|
||||
case IFLA_BR_ROOT_PORT:
|
||||
#endif
|
||||
#ifdef IFLA_BR_VLAN_DEFAULT_PVID
|
||||
case IFLA_BR_VLAN_DEFAULT_PVID:
|
||||
#endif
|
||||
case QEMU_IFLA_BR_PRIORITY:
|
||||
case QEMU_IFLA_BR_VLAN_PROTOCOL:
|
||||
case QEMU_IFLA_BR_GROUP_FWD_MASK:
|
||||
case QEMU_IFLA_BR_ROOT_PORT:
|
||||
case QEMU_IFLA_BR_VLAN_DEFAULT_PVID:
|
||||
u16 = NLA_DATA(nlattr);
|
||||
*u16 = tswap16(*u16);
|
||||
break;
|
||||
/* uint32_t */
|
||||
case IFLA_BR_FORWARD_DELAY:
|
||||
case IFLA_BR_HELLO_TIME:
|
||||
case IFLA_BR_MAX_AGE:
|
||||
case IFLA_BR_AGEING_TIME:
|
||||
case IFLA_BR_STP_STATE:
|
||||
#ifdef IFLA_BR_ROOT_PATH_COST
|
||||
case IFLA_BR_ROOT_PATH_COST:
|
||||
#endif
|
||||
#ifdef IFLA_BR_MCAST_HASH_ELASTICITY
|
||||
case IFLA_BR_MCAST_HASH_ELASTICITY:
|
||||
#endif
|
||||
#ifdef IFLA_BR_MCAST_HASH_MAX
|
||||
case IFLA_BR_MCAST_HASH_MAX:
|
||||
#endif
|
||||
#ifdef IFLA_BR_MCAST_LAST_MEMBER_CNT
|
||||
case IFLA_BR_MCAST_LAST_MEMBER_CNT:
|
||||
#endif
|
||||
#ifdef IFLA_BR_MCAST_STARTUP_QUERY_CNT
|
||||
case IFLA_BR_MCAST_STARTUP_QUERY_CNT:
|
||||
#endif
|
||||
case QEMU_IFLA_BR_FORWARD_DELAY:
|
||||
case QEMU_IFLA_BR_HELLO_TIME:
|
||||
case QEMU_IFLA_BR_MAX_AGE:
|
||||
case QEMU_IFLA_BR_AGEING_TIME:
|
||||
case QEMU_IFLA_BR_STP_STATE:
|
||||
case QEMU_IFLA_BR_ROOT_PATH_COST:
|
||||
case QEMU_IFLA_BR_MCAST_HASH_ELASTICITY:
|
||||
case QEMU_IFLA_BR_MCAST_HASH_MAX:
|
||||
case QEMU_IFLA_BR_MCAST_LAST_MEMBER_CNT:
|
||||
case QEMU_IFLA_BR_MCAST_STARTUP_QUERY_CNT:
|
||||
u32 = NLA_DATA(nlattr);
|
||||
*u32 = tswap32(*u32);
|
||||
break;
|
||||
/* uint64_t */
|
||||
#ifdef IFLA_BR_HELLO_TIMER
|
||||
case IFLA_BR_HELLO_TIMER:
|
||||
#endif
|
||||
#ifdef IFLA_BR_TCN_TIMER
|
||||
case IFLA_BR_TCN_TIMER:
|
||||
#endif
|
||||
#ifdef IFLA_BR_GC_TIMER
|
||||
case IFLA_BR_GC_TIMER:
|
||||
#endif
|
||||
#ifdef IFLA_BR_TOPOLOGY_CHANGE_TIMER
|
||||
case IFLA_BR_TOPOLOGY_CHANGE_TIMER:
|
||||
#endif
|
||||
#ifdef IFLA_BR_MCAST_LAST_MEMBER_INTVL
|
||||
case IFLA_BR_MCAST_LAST_MEMBER_INTVL:
|
||||
#endif
|
||||
#ifdef IFLA_BR_MCAST_MEMBERSHIP_INTVL
|
||||
case IFLA_BR_MCAST_MEMBERSHIP_INTVL:
|
||||
#endif
|
||||
#ifdef IFLA_BR_MCAST_QUERIER_INTVL
|
||||
case IFLA_BR_MCAST_QUERIER_INTVL:
|
||||
#endif
|
||||
#ifdef IFLA_BR_MCAST_QUERY_INTVL
|
||||
case IFLA_BR_MCAST_QUERY_INTVL:
|
||||
#endif
|
||||
#ifdef IFLA_BR_MCAST_QUERY_RESPONSE_INTVL
|
||||
case IFLA_BR_MCAST_QUERY_RESPONSE_INTVL:
|
||||
#endif
|
||||
#ifdef IFLA_BR_MCAST_STARTUP_QUERY_INTVL
|
||||
case IFLA_BR_MCAST_STARTUP_QUERY_INTVL:
|
||||
#endif
|
||||
case QEMU_IFLA_BR_HELLO_TIMER:
|
||||
case QEMU_IFLA_BR_TCN_TIMER:
|
||||
case QEMU_IFLA_BR_GC_TIMER:
|
||||
case QEMU_IFLA_BR_TOPOLOGY_CHANGE_TIMER:
|
||||
case QEMU_IFLA_BR_MCAST_LAST_MEMBER_INTVL:
|
||||
case QEMU_IFLA_BR_MCAST_MEMBERSHIP_INTVL:
|
||||
case QEMU_IFLA_BR_MCAST_QUERIER_INTVL:
|
||||
case QEMU_IFLA_BR_MCAST_QUERY_INTVL:
|
||||
case QEMU_IFLA_BR_MCAST_QUERY_RESPONSE_INTVL:
|
||||
case QEMU_IFLA_BR_MCAST_STARTUP_QUERY_INTVL:
|
||||
u64 = NLA_DATA(nlattr);
|
||||
*u64 = tswap64(*u64);
|
||||
break;
|
||||
/* ifla_bridge_id: uin8_t[] */
|
||||
#ifdef IFLA_BR_ROOT_ID
|
||||
case IFLA_BR_ROOT_ID:
|
||||
#endif
|
||||
#ifdef IFLA_BR_BRIDGE_ID
|
||||
case IFLA_BR_BRIDGE_ID:
|
||||
#endif
|
||||
case QEMU_IFLA_BR_ROOT_ID:
|
||||
case QEMU_IFLA_BR_BRIDGE_ID:
|
||||
break;
|
||||
default:
|
||||
gemu_log("Unknown IFLA_BR type %d\n", nlattr->nla_type);
|
||||
gemu_log("Unknown QEMU_IFLA_BR type %d\n", nlattr->nla_type);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
@@ -1920,71 +2013,47 @@ static abi_long host_to_target_slave_data_bridge_nlattr(struct nlattr *nlattr,
|
||||
|
||||
switch (nlattr->nla_type) {
|
||||
/* uint8_t */
|
||||
case IFLA_BRPORT_STATE:
|
||||
case IFLA_BRPORT_MODE:
|
||||
case IFLA_BRPORT_GUARD:
|
||||
case IFLA_BRPORT_PROTECT:
|
||||
case IFLA_BRPORT_FAST_LEAVE:
|
||||
case IFLA_BRPORT_LEARNING:
|
||||
case IFLA_BRPORT_UNICAST_FLOOD:
|
||||
case IFLA_BRPORT_PROXYARP:
|
||||
case IFLA_BRPORT_LEARNING_SYNC:
|
||||
case IFLA_BRPORT_PROXYARP_WIFI:
|
||||
#ifdef IFLA_BRPORT_TOPOLOGY_CHANGE_ACK
|
||||
case IFLA_BRPORT_TOPOLOGY_CHANGE_ACK:
|
||||
#endif
|
||||
#ifdef IFLA_BRPORT_CONFIG_PENDING
|
||||
case IFLA_BRPORT_CONFIG_PENDING:
|
||||
#endif
|
||||
#ifdef IFLA_BRPORT_MULTICAST_ROUTER
|
||||
case IFLA_BRPORT_MULTICAST_ROUTER:
|
||||
#endif
|
||||
case QEMU_IFLA_BRPORT_STATE:
|
||||
case QEMU_IFLA_BRPORT_MODE:
|
||||
case QEMU_IFLA_BRPORT_GUARD:
|
||||
case QEMU_IFLA_BRPORT_PROTECT:
|
||||
case QEMU_IFLA_BRPORT_FAST_LEAVE:
|
||||
case QEMU_IFLA_BRPORT_LEARNING:
|
||||
case QEMU_IFLA_BRPORT_UNICAST_FLOOD:
|
||||
case QEMU_IFLA_BRPORT_PROXYARP:
|
||||
case QEMU_IFLA_BRPORT_LEARNING_SYNC:
|
||||
case QEMU_IFLA_BRPORT_PROXYARP_WIFI:
|
||||
case QEMU_IFLA_BRPORT_TOPOLOGY_CHANGE_ACK:
|
||||
case QEMU_IFLA_BRPORT_CONFIG_PENDING:
|
||||
case QEMU_IFLA_BRPORT_MULTICAST_ROUTER:
|
||||
break;
|
||||
/* uint16_t */
|
||||
case IFLA_BRPORT_PRIORITY:
|
||||
#ifdef IFLA_BRPORT_DESIGNATED_PORT
|
||||
case IFLA_BRPORT_DESIGNATED_PORT:
|
||||
#endif
|
||||
#ifdef IFLA_BRPORT_DESIGNATED_COST
|
||||
case IFLA_BRPORT_DESIGNATED_COST:
|
||||
#endif
|
||||
#ifdef IFLA_BRPORT_ID
|
||||
case IFLA_BRPORT_ID:
|
||||
#endif
|
||||
#ifdef IFLA_BRPORT_NO
|
||||
case IFLA_BRPORT_NO:
|
||||
#endif
|
||||
case QEMU_IFLA_BRPORT_PRIORITY:
|
||||
case QEMU_IFLA_BRPORT_DESIGNATED_PORT:
|
||||
case QEMU_IFLA_BRPORT_DESIGNATED_COST:
|
||||
case QEMU_IFLA_BRPORT_ID:
|
||||
case QEMU_IFLA_BRPORT_NO:
|
||||
u16 = NLA_DATA(nlattr);
|
||||
*u16 = tswap16(*u16);
|
||||
break;
|
||||
/* uin32_t */
|
||||
case IFLA_BRPORT_COST:
|
||||
case QEMU_IFLA_BRPORT_COST:
|
||||
u32 = NLA_DATA(nlattr);
|
||||
*u32 = tswap32(*u32);
|
||||
break;
|
||||
/* uint64_t */
|
||||
#ifdef IFLA_BRPORT_MESSAGE_AGE_TIMER
|
||||
case IFLA_BRPORT_MESSAGE_AGE_TIMER:
|
||||
#endif
|
||||
#ifdef IFLA_BRPORT_FORWARD_DELAY_TIMER
|
||||
case IFLA_BRPORT_FORWARD_DELAY_TIMER:
|
||||
#endif
|
||||
#ifdef IFLA_BRPORT_HOLD_TIMER
|
||||
case IFLA_BRPORT_HOLD_TIMER:
|
||||
#endif
|
||||
case QEMU_IFLA_BRPORT_MESSAGE_AGE_TIMER:
|
||||
case QEMU_IFLA_BRPORT_FORWARD_DELAY_TIMER:
|
||||
case QEMU_IFLA_BRPORT_HOLD_TIMER:
|
||||
u64 = NLA_DATA(nlattr);
|
||||
*u64 = tswap64(*u64);
|
||||
break;
|
||||
/* ifla_bridge_id: uint8_t[] */
|
||||
#ifdef IFLA_BRPORT_ROOT_ID
|
||||
case IFLA_BRPORT_ROOT_ID:
|
||||
#endif
|
||||
#ifdef IFLA_BRPORT_BRIDGE_ID
|
||||
case IFLA_BRPORT_BRIDGE_ID:
|
||||
#endif
|
||||
case QEMU_IFLA_BRPORT_ROOT_ID:
|
||||
case QEMU_IFLA_BRPORT_BRIDGE_ID:
|
||||
break;
|
||||
default:
|
||||
gemu_log("Unknown IFLA_BRPORT type %d\n", nlattr->nla_type);
|
||||
gemu_log("Unknown QEMU_IFLA_BRPORT type %d\n", nlattr->nla_type);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
@@ -2004,20 +2073,20 @@ static abi_long host_to_target_data_linkinfo_nlattr(struct nlattr *nlattr,
|
||||
|
||||
switch (nlattr->nla_type) {
|
||||
/* string */
|
||||
case IFLA_INFO_KIND:
|
||||
case QEMU_IFLA_INFO_KIND:
|
||||
li_context->name = NLA_DATA(nlattr);
|
||||
li_context->len = nlattr->nla_len - NLA_HDRLEN;
|
||||
break;
|
||||
case IFLA_INFO_SLAVE_KIND:
|
||||
case QEMU_IFLA_INFO_SLAVE_KIND:
|
||||
li_context->slave_name = NLA_DATA(nlattr);
|
||||
li_context->slave_len = nlattr->nla_len - NLA_HDRLEN;
|
||||
break;
|
||||
/* stats */
|
||||
case IFLA_INFO_XSTATS:
|
||||
case QEMU_IFLA_INFO_XSTATS:
|
||||
/* FIXME: only used by CAN */
|
||||
break;
|
||||
/* nested */
|
||||
case IFLA_INFO_DATA:
|
||||
case QEMU_IFLA_INFO_DATA:
|
||||
if (strncmp(li_context->name, "bridge",
|
||||
li_context->len) == 0) {
|
||||
return host_to_target_for_each_nlattr(NLA_DATA(nlattr),
|
||||
@@ -2025,10 +2094,10 @@ static abi_long host_to_target_data_linkinfo_nlattr(struct nlattr *nlattr,
|
||||
NULL,
|
||||
host_to_target_data_bridge_nlattr);
|
||||
} else {
|
||||
gemu_log("Unknown IFLA_INFO_KIND %s\n", li_context->name);
|
||||
gemu_log("Unknown QEMU_IFLA_INFO_KIND %s\n", li_context->name);
|
||||
}
|
||||
break;
|
||||
case IFLA_INFO_SLAVE_DATA:
|
||||
case QEMU_IFLA_INFO_SLAVE_DATA:
|
||||
if (strncmp(li_context->slave_name, "bridge",
|
||||
li_context->slave_len) == 0) {
|
||||
return host_to_target_for_each_nlattr(NLA_DATA(nlattr),
|
||||
@@ -2036,12 +2105,12 @@ static abi_long host_to_target_data_linkinfo_nlattr(struct nlattr *nlattr,
|
||||
NULL,
|
||||
host_to_target_slave_data_bridge_nlattr);
|
||||
} else {
|
||||
gemu_log("Unknown IFLA_INFO_SLAVE_KIND %s\n",
|
||||
gemu_log("Unknown QEMU_IFLA_INFO_SLAVE_KIND %s\n",
|
||||
li_context->slave_name);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
gemu_log("Unknown host IFLA_INFO type: %d\n", nlattr->nla_type);
|
||||
gemu_log("Unknown host QEMU_IFLA_INFO type: %d\n", nlattr->nla_type);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2055,7 +2124,7 @@ static abi_long host_to_target_data_inet_nlattr(struct nlattr *nlattr,
|
||||
int i;
|
||||
|
||||
switch (nlattr->nla_type) {
|
||||
case IFLA_INET_CONF:
|
||||
case QEMU_IFLA_INET_CONF:
|
||||
u32 = NLA_DATA(nlattr);
|
||||
for (i = 0; i < (nlattr->nla_len - NLA_HDRLEN) / sizeof(*u32);
|
||||
i++) {
|
||||
@@ -2078,18 +2147,18 @@ static abi_long host_to_target_data_inet6_nlattr(struct nlattr *nlattr,
|
||||
|
||||
switch (nlattr->nla_type) {
|
||||
/* binaries */
|
||||
case IFLA_INET6_TOKEN:
|
||||
case QEMU_IFLA_INET6_TOKEN:
|
||||
break;
|
||||
/* uint8_t */
|
||||
case IFLA_INET6_ADDR_GEN_MODE:
|
||||
case QEMU_IFLA_INET6_ADDR_GEN_MODE:
|
||||
break;
|
||||
/* uint32_t */
|
||||
case IFLA_INET6_FLAGS:
|
||||
case QEMU_IFLA_INET6_FLAGS:
|
||||
u32 = NLA_DATA(nlattr);
|
||||
*u32 = tswap32(*u32);
|
||||
break;
|
||||
/* uint32_t[] */
|
||||
case IFLA_INET6_CONF:
|
||||
case QEMU_IFLA_INET6_CONF:
|
||||
u32 = NLA_DATA(nlattr);
|
||||
for (i = 0; i < (nlattr->nla_len - NLA_HDRLEN) / sizeof(*u32);
|
||||
i++) {
|
||||
@@ -2097,7 +2166,7 @@ static abi_long host_to_target_data_inet6_nlattr(struct nlattr *nlattr,
|
||||
}
|
||||
break;
|
||||
/* ifla_cacheinfo */
|
||||
case IFLA_INET6_CACHEINFO:
|
||||
case QEMU_IFLA_INET6_CACHEINFO:
|
||||
ci = NLA_DATA(nlattr);
|
||||
ci->max_reasm_len = tswap32(ci->max_reasm_len);
|
||||
ci->tstamp = tswap32(ci->tstamp);
|
||||
@@ -2105,8 +2174,8 @@ static abi_long host_to_target_data_inet6_nlattr(struct nlattr *nlattr,
|
||||
ci->retrans_time = tswap32(ci->retrans_time);
|
||||
break;
|
||||
/* uint64_t[] */
|
||||
case IFLA_INET6_STATS:
|
||||
case IFLA_INET6_ICMP6STATS:
|
||||
case QEMU_IFLA_INET6_STATS:
|
||||
case QEMU_IFLA_INET6_ICMP6STATS:
|
||||
u64 = NLA_DATA(nlattr);
|
||||
for (i = 0; i < (nlattr->nla_len - NLA_HDRLEN) / sizeof(*u64);
|
||||
i++) {
|
||||
@@ -2148,37 +2217,37 @@ static abi_long host_to_target_data_link_rtattr(struct rtattr *rtattr)
|
||||
|
||||
switch (rtattr->rta_type) {
|
||||
/* binary stream */
|
||||
case IFLA_ADDRESS:
|
||||
case IFLA_BROADCAST:
|
||||
case QEMU_IFLA_ADDRESS:
|
||||
case QEMU_IFLA_BROADCAST:
|
||||
/* string */
|
||||
case IFLA_IFNAME:
|
||||
case IFLA_QDISC:
|
||||
case QEMU_IFLA_IFNAME:
|
||||
case QEMU_IFLA_QDISC:
|
||||
break;
|
||||
/* uin8_t */
|
||||
case IFLA_OPERSTATE:
|
||||
case IFLA_LINKMODE:
|
||||
case IFLA_CARRIER:
|
||||
case IFLA_PROTO_DOWN:
|
||||
case QEMU_IFLA_OPERSTATE:
|
||||
case QEMU_IFLA_LINKMODE:
|
||||
case QEMU_IFLA_CARRIER:
|
||||
case QEMU_IFLA_PROTO_DOWN:
|
||||
break;
|
||||
/* uint32_t */
|
||||
case IFLA_MTU:
|
||||
case IFLA_LINK:
|
||||
case IFLA_WEIGHT:
|
||||
case IFLA_TXQLEN:
|
||||
case IFLA_CARRIER_CHANGES:
|
||||
case IFLA_NUM_RX_QUEUES:
|
||||
case IFLA_NUM_TX_QUEUES:
|
||||
case IFLA_PROMISCUITY:
|
||||
case IFLA_EXT_MASK:
|
||||
case IFLA_LINK_NETNSID:
|
||||
case IFLA_GROUP:
|
||||
case IFLA_MASTER:
|
||||
case IFLA_NUM_VF:
|
||||
case QEMU_IFLA_MTU:
|
||||
case QEMU_IFLA_LINK:
|
||||
case QEMU_IFLA_WEIGHT:
|
||||
case QEMU_IFLA_TXQLEN:
|
||||
case QEMU_IFLA_CARRIER_CHANGES:
|
||||
case QEMU_IFLA_NUM_RX_QUEUES:
|
||||
case QEMU_IFLA_NUM_TX_QUEUES:
|
||||
case QEMU_IFLA_PROMISCUITY:
|
||||
case QEMU_IFLA_EXT_MASK:
|
||||
case QEMU_IFLA_LINK_NETNSID:
|
||||
case QEMU_IFLA_GROUP:
|
||||
case QEMU_IFLA_MASTER:
|
||||
case QEMU_IFLA_NUM_VF:
|
||||
u32 = RTA_DATA(rtattr);
|
||||
*u32 = tswap32(*u32);
|
||||
break;
|
||||
/* struct rtnl_link_stats */
|
||||
case IFLA_STATS:
|
||||
case QEMU_IFLA_STATS:
|
||||
st = RTA_DATA(rtattr);
|
||||
st->rx_packets = tswap32(st->rx_packets);
|
||||
st->tx_packets = tswap32(st->tx_packets);
|
||||
@@ -2211,7 +2280,7 @@ static abi_long host_to_target_data_link_rtattr(struct rtattr *rtattr)
|
||||
st->tx_compressed = tswap32(st->tx_compressed);
|
||||
break;
|
||||
/* struct rtnl_link_stats64 */
|
||||
case IFLA_STATS64:
|
||||
case QEMU_IFLA_STATS64:
|
||||
st64 = RTA_DATA(rtattr);
|
||||
st64->rx_packets = tswap64(st64->rx_packets);
|
||||
st64->tx_packets = tswap64(st64->tx_packets);
|
||||
@@ -2244,7 +2313,7 @@ static abi_long host_to_target_data_link_rtattr(struct rtattr *rtattr)
|
||||
st64->tx_compressed = tswap64(st64->tx_compressed);
|
||||
break;
|
||||
/* struct rtnl_link_ifmap */
|
||||
case IFLA_MAP:
|
||||
case QEMU_IFLA_MAP:
|
||||
map = RTA_DATA(rtattr);
|
||||
map->mem_start = tswap64(map->mem_start);
|
||||
map->mem_end = tswap64(map->mem_end);
|
||||
@@ -2252,17 +2321,17 @@ static abi_long host_to_target_data_link_rtattr(struct rtattr *rtattr)
|
||||
map->irq = tswap16(map->irq);
|
||||
break;
|
||||
/* nested */
|
||||
case IFLA_LINKINFO:
|
||||
case QEMU_IFLA_LINKINFO:
|
||||
memset(&li_context, 0, sizeof(li_context));
|
||||
return host_to_target_for_each_nlattr(RTA_DATA(rtattr), rtattr->rta_len,
|
||||
&li_context,
|
||||
host_to_target_data_linkinfo_nlattr);
|
||||
case IFLA_AF_SPEC:
|
||||
case QEMU_IFLA_AF_SPEC:
|
||||
return host_to_target_for_each_nlattr(RTA_DATA(rtattr), rtattr->rta_len,
|
||||
NULL,
|
||||
host_to_target_data_spec_nlattr);
|
||||
default:
|
||||
gemu_log("Unknown host IFLA type: %d\n", rtattr->rta_type);
|
||||
gemu_log("Unknown host QEMU_IFLA type: %d\n", rtattr->rta_type);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
@@ -2429,7 +2498,7 @@ static abi_long target_to_host_data_link_rtattr(struct rtattr *rtattr)
|
||||
{
|
||||
switch (rtattr->rta_type) {
|
||||
default:
|
||||
gemu_log("Unknown target IFLA type: %d\n", rtattr->rta_type);
|
||||
gemu_log("Unknown target QEMU_IFLA type: %d\n", rtattr->rta_type);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -1132,6 +1132,71 @@ const MemoryRegionOps unassigned_mem_ops = {
|
||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
};
|
||||
|
||||
static uint64_t memory_region_ram_device_read(void *opaque,
|
||||
hwaddr addr, unsigned size)
|
||||
{
|
||||
MemoryRegion *mr = opaque;
|
||||
uint64_t data = (uint64_t)~0;
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
data = *(uint8_t *)(mr->ram_block->host + addr);
|
||||
break;
|
||||
case 2:
|
||||
data = *(uint16_t *)(mr->ram_block->host + addr);
|
||||
break;
|
||||
case 4:
|
||||
data = *(uint32_t *)(mr->ram_block->host + addr);
|
||||
break;
|
||||
case 8:
|
||||
data = *(uint64_t *)(mr->ram_block->host + addr);
|
||||
break;
|
||||
}
|
||||
|
||||
trace_memory_region_ram_device_read(get_cpu_index(), mr, addr, data, size);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static void memory_region_ram_device_write(void *opaque, hwaddr addr,
|
||||
uint64_t data, unsigned size)
|
||||
{
|
||||
MemoryRegion *mr = opaque;
|
||||
|
||||
trace_memory_region_ram_device_write(get_cpu_index(), mr, addr, data, size);
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
*(uint8_t *)(mr->ram_block->host + addr) = (uint8_t)data;
|
||||
break;
|
||||
case 2:
|
||||
*(uint16_t *)(mr->ram_block->host + addr) = (uint16_t)data;
|
||||
break;
|
||||
case 4:
|
||||
*(uint32_t *)(mr->ram_block->host + addr) = (uint32_t)data;
|
||||
break;
|
||||
case 8:
|
||||
*(uint64_t *)(mr->ram_block->host + addr) = data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const MemoryRegionOps ram_device_mem_ops = {
|
||||
.read = memory_region_ram_device_read,
|
||||
.write = memory_region_ram_device_write,
|
||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
.valid = {
|
||||
.min_access_size = 1,
|
||||
.max_access_size = 8,
|
||||
.unaligned = true,
|
||||
},
|
||||
.impl = {
|
||||
.min_access_size = 1,
|
||||
.max_access_size = 8,
|
||||
.unaligned = true,
|
||||
},
|
||||
};
|
||||
|
||||
bool memory_region_access_valid(MemoryRegion *mr,
|
||||
hwaddr addr,
|
||||
unsigned size,
|
||||
@@ -1359,9 +1424,16 @@ void memory_region_init_ram_ptr(MemoryRegion *mr,
|
||||
mr->ram_block = qemu_ram_alloc_from_ptr(size, ptr, mr, &error_fatal);
|
||||
}
|
||||
|
||||
void memory_region_set_skip_dump(MemoryRegion *mr)
|
||||
void memory_region_init_ram_device_ptr(MemoryRegion *mr,
|
||||
Object *owner,
|
||||
const char *name,
|
||||
uint64_t size,
|
||||
void *ptr)
|
||||
{
|
||||
mr->skip_dump = true;
|
||||
memory_region_init_ram_ptr(mr, owner, name, size, ptr);
|
||||
mr->ram_device = true;
|
||||
mr->ops = &ram_device_mem_ops;
|
||||
mr->opaque = mr;
|
||||
}
|
||||
|
||||
void memory_region_init_alias(MemoryRegion *mr,
|
||||
@@ -1494,9 +1566,9 @@ const char *memory_region_name(const MemoryRegion *mr)
|
||||
return mr->name;
|
||||
}
|
||||
|
||||
bool memory_region_is_skip_dump(MemoryRegion *mr)
|
||||
bool memory_region_is_ram_device(MemoryRegion *mr)
|
||||
{
|
||||
return mr->skip_dump;
|
||||
return mr->ram_device;
|
||||
}
|
||||
|
||||
uint8_t memory_region_get_dirty_log_mask(MemoryRegion *mr)
|
||||
|
||||
+1
-1
@@ -206,7 +206,7 @@ static void guest_phys_blocks_region_add(MemoryListener *listener,
|
||||
|
||||
/* we only care about RAM */
|
||||
if (!memory_region_is_ram(section->mr) ||
|
||||
memory_region_is_skip_dump(section->mr)) {
|
||||
memory_region_is_ram_device(section->mr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1602,9 +1602,8 @@ void net_socket_rs_init(SocketReadState *rs,
|
||||
|
||||
/*
|
||||
* Returns
|
||||
* 0: SocketReadState is not ready
|
||||
* 1: SocketReadState is ready
|
||||
* otherwise error occurs
|
||||
* 0: success
|
||||
* -1: error occurs
|
||||
*/
|
||||
int net_fill_rstate(SocketReadState *rs, const uint8_t *buf, int size)
|
||||
{
|
||||
@@ -1649,13 +1648,13 @@ int net_fill_rstate(SocketReadState *rs, const uint8_t *buf, int size)
|
||||
if (rs->index >= rs->packet_len) {
|
||||
rs->index = 0;
|
||||
rs->state = 0;
|
||||
if (rs->finalize) {
|
||||
rs->finalize(rs);
|
||||
}
|
||||
return 1;
|
||||
assert(rs->finalize);
|
||||
rs->finalize(rs);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(size == 0);
|
||||
return 0;
|
||||
}
|
||||
+3
-1
@@ -131,7 +131,9 @@ static void net_slirp_cleanup(NetClientState *nc)
|
||||
SlirpState *s = DO_UPCAST(SlirpState, nc, nc);
|
||||
|
||||
slirp_cleanup(s->slirp);
|
||||
qemu_remove_exit_notifier(&s->exit_notifier);
|
||||
if (s->exit_notifier.notify) {
|
||||
qemu_remove_exit_notifier(&s->exit_notifier);
|
||||
}
|
||||
slirp_smb_cleanup(s);
|
||||
QTAILQ_REMOVE(&slirp_stacks, s, entry);
|
||||
}
|
||||
|
||||
+29
-27
@@ -489,30 +489,42 @@ static int net_socket_listen_init(NetClientState *peer,
|
||||
{
|
||||
NetClientState *nc;
|
||||
NetSocketState *s;
|
||||
SocketAddress *saddr;
|
||||
int ret;
|
||||
Error *local_error = NULL;
|
||||
struct sockaddr_in saddr;
|
||||
int fd, ret;
|
||||
|
||||
saddr = socket_parse(host_str, &local_error);
|
||||
if (saddr == NULL) {
|
||||
error_report_err(local_error);
|
||||
if (parse_host_port(&saddr, host_str) < 0)
|
||||
return -1;
|
||||
|
||||
fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
|
||||
if (fd < 0) {
|
||||
perror("socket");
|
||||
return -1;
|
||||
}
|
||||
qemu_set_nonblock(fd);
|
||||
|
||||
ret = socket_listen(saddr, &local_error);
|
||||
socket_set_fast_reuse(fd);
|
||||
|
||||
ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
|
||||
if (ret < 0) {
|
||||
error_report_err(local_error);
|
||||
perror("bind");
|
||||
closesocket(fd);
|
||||
return -1;
|
||||
}
|
||||
ret = listen(fd, 0);
|
||||
if (ret < 0) {
|
||||
perror("listen");
|
||||
closesocket(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
nc = qemu_new_net_client(&net_socket_info, peer, model, name);
|
||||
s = DO_UPCAST(NetSocketState, nc, nc);
|
||||
s->fd = -1;
|
||||
s->listen_fd = ret;
|
||||
s->listen_fd = fd;
|
||||
s->nc.link_down = true;
|
||||
net_socket_rs_init(&s->rs, net_socket_rs_finalize);
|
||||
|
||||
qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s);
|
||||
qapi_free_SocketAddress(saddr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -523,15 +535,10 @@ static int net_socket_connect_init(NetClientState *peer,
|
||||
{
|
||||
NetSocketState *s;
|
||||
int fd, connected, ret;
|
||||
char *addr_str;
|
||||
SocketAddress *saddr;
|
||||
Error *local_error = NULL;
|
||||
struct sockaddr_in saddr;
|
||||
|
||||
saddr = socket_parse(host_str, &local_error);
|
||||
if (saddr == NULL) {
|
||||
error_report_err(local_error);
|
||||
if (parse_host_port(&saddr, host_str) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
|
||||
if (fd < 0) {
|
||||
@@ -539,9 +546,10 @@ static int net_socket_connect_init(NetClientState *peer,
|
||||
return -1;
|
||||
}
|
||||
qemu_set_nonblock(fd);
|
||||
|
||||
connected = 0;
|
||||
for(;;) {
|
||||
ret = socket_connect(saddr, &local_error, NULL, NULL);
|
||||
ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr));
|
||||
if (ret < 0) {
|
||||
if (errno == EINTR || errno == EWOULDBLOCK) {
|
||||
/* continue */
|
||||
@@ -550,7 +558,7 @@ static int net_socket_connect_init(NetClientState *peer,
|
||||
errno == EINVAL) {
|
||||
break;
|
||||
} else {
|
||||
error_report_err(local_error);
|
||||
perror("connect");
|
||||
closesocket(fd);
|
||||
return -1;
|
||||
}
|
||||
@@ -562,15 +570,9 @@ static int net_socket_connect_init(NetClientState *peer,
|
||||
s = net_socket_fd_init(peer, model, name, fd, connected);
|
||||
if (!s)
|
||||
return -1;
|
||||
|
||||
addr_str = socket_address_to_string(saddr, &local_error);
|
||||
if (addr_str == NULL)
|
||||
return -1;
|
||||
|
||||
snprintf(s->nc.info_str, sizeof(s->nc.info_str),
|
||||
"socket: connect to %s", addr_str);
|
||||
qapi_free_SocketAddress(saddr);
|
||||
g_free(addr_str);
|
||||
"socket: connect to %s:%d",
|
||||
inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,10 +10,7 @@ $(call set-vpath, $(SRC_PATH)/pc-bios/optionrom)
|
||||
.PHONY : all clean build-all
|
||||
|
||||
# Compiling with no optimization creates ROMs that are too large
|
||||
ifeq ($(filter -O%, $(CFLAGS)),)
|
||||
override CFLAGS += -O2
|
||||
endif
|
||||
ifeq ($(filter -O%, $(CFLAGS)),-O0)
|
||||
ifeq ($(lastword $(filter -O%, -O0 $(CFLAGS))),-O0)
|
||||
override CFLAGS += -O2
|
||||
endif
|
||||
|
||||
|
||||
@@ -338,6 +338,12 @@ static void qmp_input_type_any(Visitor *v, const char *name, QObject **obj,
|
||||
QmpInputVisitor *qiv = to_qiv(v);
|
||||
QObject *qobj = qmp_input_get_object(qiv, name, true);
|
||||
|
||||
if (!qobj) {
|
||||
error_setg(errp, QERR_MISSING_PARAMETER, name ? name : "null");
|
||||
*obj = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
qobject_incref(qobj);
|
||||
*obj = qobj;
|
||||
}
|
||||
@@ -347,6 +353,11 @@ static void qmp_input_type_null(Visitor *v, const char *name, Error **errp)
|
||||
QmpInputVisitor *qiv = to_qiv(v);
|
||||
QObject *qobj = qmp_input_get_object(qiv, name, true);
|
||||
|
||||
if (!qobj) {
|
||||
error_setg(errp, QERR_MISSING_PARAMETER, name ? name : "null");
|
||||
return;
|
||||
}
|
||||
|
||||
if (qobject_type(qobj) != QTYPE_QNULL) {
|
||||
error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
|
||||
"null");
|
||||
|
||||
@@ -1223,6 +1223,9 @@ static CharDriverState *qemu_chr_open_stdio(const char *id,
|
||||
sigaction(SIGCONT, &act, NULL);
|
||||
|
||||
chr = qemu_chr_open_fd(0, 1, common, errp);
|
||||
if (!chr) {
|
||||
return NULL;
|
||||
}
|
||||
chr->chr_close = qemu_chr_close_stdio;
|
||||
chr->chr_set_echo = qemu_chr_set_echo_stdio;
|
||||
if (opts->has_signal) {
|
||||
@@ -1679,6 +1682,9 @@ static CharDriverState *qemu_chr_open_tty_fd(int fd,
|
||||
|
||||
tty_serial_init(fd, 115200, 'N', 8, 1);
|
||||
chr = qemu_chr_open_fd(fd, fd, backend, errp);
|
||||
if (!chr) {
|
||||
return NULL;
|
||||
}
|
||||
chr->chr_ioctl = tty_serial_ioctl;
|
||||
chr->chr_close = qemu_chr_close_tty;
|
||||
return chr;
|
||||
@@ -3090,6 +3096,7 @@ static void tcp_chr_tls_init(CharDriverState *chr)
|
||||
if (tioc == NULL) {
|
||||
error_free(err);
|
||||
tcp_chr_disconnect(chr);
|
||||
return;
|
||||
}
|
||||
object_unref(OBJECT(s->ioc));
|
||||
s->ioc = QIO_CHANNEL(tioc);
|
||||
|
||||
@@ -654,7 +654,7 @@ void qmp_add_client(const char *protocol, const char *fdname,
|
||||
void qmp_object_add(const char *type, const char *id,
|
||||
bool has_props, QObject *props, Error **errp)
|
||||
{
|
||||
const QDict *pdict = NULL;
|
||||
QDict *pdict;
|
||||
Visitor *v;
|
||||
Object *obj;
|
||||
|
||||
@@ -664,14 +664,18 @@ void qmp_object_add(const char *type, const char *id,
|
||||
error_setg(errp, QERR_INVALID_PARAMETER_TYPE, "props", "dict");
|
||||
return;
|
||||
}
|
||||
QINCREF(pdict);
|
||||
} else {
|
||||
pdict = qdict_new();
|
||||
}
|
||||
|
||||
v = qmp_input_visitor_new(props, true);
|
||||
v = qmp_input_visitor_new(QOBJECT(pdict), true);
|
||||
obj = user_creatable_add_type(type, id, pdict, v, errp);
|
||||
visit_free(v);
|
||||
if (obj) {
|
||||
object_unref(obj);
|
||||
}
|
||||
QDECREF(pdict);
|
||||
}
|
||||
|
||||
void qmp_object_del(const char *id, Error **errp)
|
||||
|
||||
@@ -92,7 +92,7 @@ module-common.o: CFLAGS += $(DSO_OBJ_CFLAGS)
|
||||
$(if $(findstring /,$@),$(call quiet-command,cp $@ $(subst /,-,$@), " CP $(subst /,-,$@)"))
|
||||
|
||||
|
||||
LD_REL := $(CC) -nostdlib -Wl,-r $(LD_REL_FLAGS)
|
||||
LD_REL := $(CC) -nostdlib -r $(LD_REL_FLAGS)
|
||||
|
||||
%.mo:
|
||||
$(call quiet-command,$(LD_REL) -o $@ $^," LD -r $(TARGET_DIR)$@")
|
||||
|
||||
@@ -66,6 +66,23 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
if (so->so_emu==EMU_RSH && so->extra) {
|
||||
sofree(so->extra);
|
||||
|
||||
@@ -1164,6 +1164,12 @@ struct PowerPCCPU {
|
||||
int cpu_dt_id;
|
||||
uint32_t max_compat;
|
||||
uint32_t cpu_version;
|
||||
|
||||
/* fields used only during migration for compatibility hacks */
|
||||
target_ulong mig_msr_mask;
|
||||
uint64_t mig_insns_flags;
|
||||
uint64_t mig_insns_flags2;
|
||||
uint32_t mig_nb_BATs;
|
||||
};
|
||||
|
||||
static inline PowerPCCPU *ppc_env_get_cpu(CPUPPCState *env)
|
||||
|
||||
@@ -79,6 +79,7 @@ static int cap_ppc_watchdog;
|
||||
static int cap_papr;
|
||||
static int cap_htab_fd;
|
||||
static int cap_fixup_hcalls;
|
||||
static int cap_htm; /* Hardware transactional memory support */
|
||||
|
||||
static uint32_t debug_inst_opcode;
|
||||
|
||||
@@ -121,6 +122,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
|
||||
* only activated after this by kvmppc_set_papr() */
|
||||
cap_htab_fd = kvm_check_extension(s, KVM_CAP_PPC_HTAB_FD);
|
||||
cap_fixup_hcalls = kvm_check_extension(s, KVM_CAP_PPC_FIXUP_HCALL);
|
||||
cap_htm = kvm_vm_check_extension(s, KVM_CAP_PPC_HTM);
|
||||
|
||||
if (!cap_interrupt_level) {
|
||||
fprintf(stderr, "KVM: Couldn't find level irq capability. Expect the "
|
||||
@@ -427,6 +429,7 @@ static void kvm_fixup_page_sizes(PowerPCCPU *cpu)
|
||||
CPUPPCState *env = &cpu->env;
|
||||
long rampagesize;
|
||||
int iq, ik, jq, jk;
|
||||
bool has_64k_pages = false;
|
||||
|
||||
/* We only handle page sizes for 64-bit server guests for now */
|
||||
if (!(env->mmu_model & POWERPC_MMU_64)) {
|
||||
@@ -470,6 +473,9 @@ static void kvm_fixup_page_sizes(PowerPCCPU *cpu)
|
||||
ksps->enc[jk].page_shift)) {
|
||||
continue;
|
||||
}
|
||||
if (ksps->enc[jk].page_shift == 16) {
|
||||
has_64k_pages = true;
|
||||
}
|
||||
qsps->enc[jq].page_shift = ksps->enc[jk].page_shift;
|
||||
qsps->enc[jq].pte_enc = ksps->enc[jk].pte_enc;
|
||||
if (++jq >= PPC_PAGE_SIZES_MAX_SZ) {
|
||||
@@ -484,6 +490,9 @@ static void kvm_fixup_page_sizes(PowerPCCPU *cpu)
|
||||
if (!(smmu_info.flags & KVM_PPC_1T_SEGMENTS)) {
|
||||
env->mmu_model &= ~POWERPC_MMU_1TSEG;
|
||||
}
|
||||
if (!has_64k_pages) {
|
||||
env->mmu_model &= ~POWERPC_MMU_64K;
|
||||
}
|
||||
}
|
||||
#else /* defined (TARGET_PPC64) */
|
||||
|
||||
@@ -2339,6 +2348,11 @@ bool kvmppc_has_cap_fixup_hcalls(void)
|
||||
return cap_fixup_hcalls;
|
||||
}
|
||||
|
||||
bool kvmppc_has_cap_htm(void)
|
||||
{
|
||||
return cap_htm;
|
||||
}
|
||||
|
||||
static PowerPCCPUClass *ppc_cpu_get_family_class(PowerPCCPUClass *pcc)
|
||||
{
|
||||
ObjectClass *oc = OBJECT_CLASS(pcc);
|
||||
|
||||
@@ -54,6 +54,7 @@ void kvmppc_hash64_free_pteg(uint64_t token);
|
||||
void kvmppc_hash64_write_pte(CPUPPCState *env, target_ulong pte_index,
|
||||
target_ulong pte0, target_ulong pte1);
|
||||
bool kvmppc_has_cap_fixup_hcalls(void);
|
||||
bool kvmppc_has_cap_htm(void);
|
||||
int kvmppc_enable_hwrng(void);
|
||||
int kvmppc_put_books_sregs(PowerPCCPU *cpu);
|
||||
PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void);
|
||||
@@ -244,6 +245,11 @@ static inline bool kvmppc_has_cap_fixup_hcalls(void)
|
||||
abort();
|
||||
}
|
||||
|
||||
static inline bool kvmppc_has_cap_htm(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline int kvmppc_enable_hwrng(void)
|
||||
{
|
||||
return -1;
|
||||
|
||||
+25
-4
@@ -141,6 +141,21 @@ static void cpu_pre_save(void *opaque)
|
||||
PowerPCCPU *cpu = opaque;
|
||||
CPUPPCState *env = &cpu->env;
|
||||
int i;
|
||||
uint64_t insns_compat_mask =
|
||||
PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB
|
||||
| PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES
|
||||
| PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | PPC_FLOAT_FRSQRTES
|
||||
| PPC_FLOAT_STFIWX | PPC_FLOAT_EXT
|
||||
| PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ
|
||||
| PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_MEM_TLBSYNC
|
||||
| PPC_64B | PPC_64BX | PPC_ALTIVEC
|
||||
| PPC_SEGMENT_64B | PPC_SLBI | PPC_POPCNTB | PPC_POPCNTWD;
|
||||
uint64_t insns_compat_mask2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX
|
||||
| PPC2_PERM_ISA206 | PPC2_DIVE_ISA206
|
||||
| PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206
|
||||
| PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207
|
||||
| PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207
|
||||
| PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 | PPC2_TM;
|
||||
|
||||
env->spr[SPR_LR] = env->lr;
|
||||
env->spr[SPR_CTR] = env->ctr;
|
||||
@@ -162,6 +177,12 @@ static void cpu_pre_save(void *opaque)
|
||||
env->spr[SPR_IBAT4U + 2*i] = env->IBAT[0][i+4];
|
||||
env->spr[SPR_IBAT4U + 2*i + 1] = env->IBAT[1][i+4];
|
||||
}
|
||||
|
||||
/* Hacks for migration compatibility between 2.6, 2.7 & 2.8 */
|
||||
cpu->mig_msr_mask = env->msr_mask;
|
||||
cpu->mig_insns_flags = env->insns_flags & insns_compat_mask;
|
||||
cpu->mig_insns_flags2 = env->insns_flags2 & insns_compat_mask2;
|
||||
cpu->mig_nb_BATs = env->nb_BATs;
|
||||
}
|
||||
|
||||
static int cpu_post_load(void *opaque, int version_id)
|
||||
@@ -562,10 +583,10 @@ const VMStateDescription vmstate_ppc_cpu = {
|
||||
/* FIXME: access_type? */
|
||||
|
||||
/* Sanity checking */
|
||||
VMSTATE_UINTTL_EQUAL(env.msr_mask, PowerPCCPU),
|
||||
VMSTATE_UINT64_EQUAL(env.insns_flags, PowerPCCPU),
|
||||
VMSTATE_UINT64_EQUAL(env.insns_flags2, PowerPCCPU),
|
||||
VMSTATE_UINT32_EQUAL(env.nb_BATs, PowerPCCPU),
|
||||
VMSTATE_UINTTL(mig_msr_mask, PowerPCCPU),
|
||||
VMSTATE_UINT64(mig_insns_flags, PowerPCCPU),
|
||||
VMSTATE_UINT64(mig_insns_flags2, PowerPCCPU),
|
||||
VMSTATE_UINT32(mig_nb_BATs, PowerPCCPU),
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
.subsections = (const VMStateDescription*[]) {
|
||||
|
||||
Loaded 100 of 119 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user