Compare commits
14 Commits
v2.7.0-rc4
...
v2.7.0
Author | SHA1 | Date | |
---|---|---|---|
|
1dc33ed90b | ||
|
12d2c4184c | ||
|
56f101ecce | ||
|
805b5d98c6 | ||
|
fff39a7ad0 | ||
|
2b294f6b65 | ||
|
336d5881a9 | ||
|
616018352c | ||
|
135a972b45 | ||
|
b69a553b4a | ||
|
e00da552a0 | ||
|
8c1c230a6e | ||
|
58a83c6149 | ||
|
bccdef6b1a |
@@ -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"
|
||||
|
147
hw/9pfs/9p.c
147
hw/9pfs/9p.c
@@ -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,6 +1319,12 @@ static void v9fs_walk(void *opaque)
|
||||
err = -ENOENT;
|
||||
goto out_nofid;
|
||||
}
|
||||
|
||||
err = fid_to_qid(pdu, fidp, &qid);
|
||||
if (err < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
v9fs_path_init(&dpath);
|
||||
v9fs_path_init(&path);
|
||||
/*
|
||||
@@ -1309,16 +1334,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 +1514,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 +2118,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 +2293,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 +2377,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 +2469,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 +2591,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 +2714,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 +2935,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 +3096,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 */
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
@@ -1648,6 +1649,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
55
net/socket.c
55
net/socket.c
@@ -489,30 +489,41 @@ 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;
|
||||
|
||||
qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s);
|
||||
qapi_free_SocketAddress(saddr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -523,15 +534,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 +545,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 +557,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 +569,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
|
||||
|
||||
|
@@ -834,6 +834,9 @@ static void page_flush_tb(void)
|
||||
/* XXX: tb_flush is currently not thread safe */
|
||||
void tb_flush(CPUState *cpu)
|
||||
{
|
||||
if (!tcg_enabled()) {
|
||||
return;
|
||||
}
|
||||
#if defined(DEBUG_FLUSH)
|
||||
printf("qemu: flush code_size=%ld nb_tbs=%d avg_tb_size=%ld\n",
|
||||
(unsigned long)(tcg_ctx.code_gen_ptr - tcg_ctx.code_gen_buffer),
|
||||
|
20
ui/vnc.c
20
ui/vnc.c
@@ -692,6 +692,8 @@ void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y)
|
||||
|
||||
static void vnc_update_server_surface(VncDisplay *vd)
|
||||
{
|
||||
int width, height;
|
||||
|
||||
qemu_pixman_image_unref(vd->server);
|
||||
vd->server = NULL;
|
||||
|
||||
@@ -699,10 +701,15 @@ static void vnc_update_server_surface(VncDisplay *vd)
|
||||
return;
|
||||
}
|
||||
|
||||
width = vnc_width(vd);
|
||||
height = vnc_height(vd);
|
||||
vd->server = pixman_image_create_bits(VNC_SERVER_FB_FORMAT,
|
||||
vnc_width(vd),
|
||||
vnc_height(vd),
|
||||
width, height,
|
||||
NULL, 0);
|
||||
|
||||
memset(vd->guest.dirty, 0x00, sizeof(vd->guest.dirty));
|
||||
vnc_set_area_dirty(vd->guest.dirty, vd, 0, 0,
|
||||
width, height);
|
||||
}
|
||||
|
||||
static void vnc_dpy_switch(DisplayChangeListener *dcl,
|
||||
@@ -710,7 +717,6 @@ static void vnc_dpy_switch(DisplayChangeListener *dcl,
|
||||
{
|
||||
VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
|
||||
VncState *vs;
|
||||
int width, height;
|
||||
|
||||
vnc_abort_display_jobs(vd);
|
||||
vd->ds = surface;
|
||||
@@ -722,11 +728,6 @@ static void vnc_dpy_switch(DisplayChangeListener *dcl,
|
||||
qemu_pixman_image_unref(vd->guest.fb);
|
||||
vd->guest.fb = pixman_image_ref(surface->image);
|
||||
vd->guest.format = surface->format;
|
||||
width = vnc_width(vd);
|
||||
height = vnc_height(vd);
|
||||
memset(vd->guest.dirty, 0x00, sizeof(vd->guest.dirty));
|
||||
vnc_set_area_dirty(vd->guest.dirty, vd, 0, 0,
|
||||
width, height);
|
||||
|
||||
QTAILQ_FOREACH(vs, &vd->clients, next) {
|
||||
vnc_colordepth(vs);
|
||||
@@ -736,7 +737,8 @@ static void vnc_dpy_switch(DisplayChangeListener *dcl,
|
||||
}
|
||||
memset(vs->dirty, 0x00, sizeof(vs->dirty));
|
||||
vnc_set_area_dirty(vs->dirty, vd, 0, 0,
|
||||
width, height);
|
||||
vnc_width(vd),
|
||||
vnc_height(vd));
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user