Compare commits
25 Commits
v0.15.0-rc
...
v0.15.0-rc
Author | SHA1 | Date | |
---|---|---|---|
|
9dc9f2b820 | ||
|
ef942b795a | ||
|
868aa386b8 | ||
|
7e10be8c74 | ||
|
9843621e3b | ||
|
ab640dbfc0 | ||
|
eaa8b2778c | ||
|
7ec7f28019 | ||
|
31b1308046 | ||
|
4ec648dd6e | ||
|
e961d129e1 | ||
|
8959459386 | ||
|
e2b40e003a | ||
|
1a39b0fcff | ||
|
4a97e18b87 | ||
|
f1ee0a0ebd | ||
|
3583bc031e | ||
|
2798b5e174 | ||
|
c886edfb85 | ||
|
0caf448b80 | ||
|
00aa0040e8 | ||
|
aad04cd024 | ||
|
1fc7bd4a86 | ||
|
4eb36d40da | ||
|
1167bfd63d |
12
Makefile
12
Makefile
@@ -168,22 +168,22 @@ test-visitor.o test-qmp-commands.o qemu-ga$(EXESUF): QEMU_CFLAGS += -I $(qapi-di
|
||||
|
||||
$(qapi-dir)/test-qapi-types.c: $(qapi-dir)/test-qapi-types.h
|
||||
$(qapi-dir)/test-qapi-types.h: $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-types.py
|
||||
$(call quiet-command,python $(SRC_PATH)/scripts/qapi-types.py -o "$(qapi-dir)" -p "test-" < $<, " GEN $@")
|
||||
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py -o "$(qapi-dir)" -p "test-" < $<, " GEN $@")
|
||||
$(qapi-dir)/test-qapi-visit.c: $(qapi-dir)/test-qapi-visit.h
|
||||
$(qapi-dir)/test-qapi-visit.h: $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-visit.py
|
||||
$(call quiet-command,python $(SRC_PATH)/scripts/qapi-visit.py -o "$(qapi-dir)" -p "test-" < $<, " GEN $@")
|
||||
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py -o "$(qapi-dir)" -p "test-" < $<, " GEN $@")
|
||||
$(qapi-dir)/test-qmp-commands.h: $(qapi-dir)/test-qmp-marshal.c
|
||||
$(qapi-dir)/test-qmp-marshal.c: $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-commands.py
|
||||
$(call quiet-command,python $(SRC_PATH)/scripts/qapi-commands.py -o "$(qapi-dir)" -p "test-" < $<, " GEN $@")
|
||||
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py -o "$(qapi-dir)" -p "test-" < $<, " GEN $@")
|
||||
|
||||
$(qapi-dir)/qga-qapi-types.c: $(qapi-dir)/qga-qapi-types.h
|
||||
$(qapi-dir)/qga-qapi-types.h: $(SRC_PATH)/qapi-schema-guest.json $(SRC_PATH)/scripts/qapi-types.py
|
||||
$(call quiet-command,python $(SRC_PATH)/scripts/qapi-types.py -o "$(qapi-dir)" -p "qga-" < $<, " GEN $@")
|
||||
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py -o "$(qapi-dir)" -p "qga-" < $<, " GEN $@")
|
||||
$(qapi-dir)/qga-qapi-visit.c: $(qapi-dir)/qga-qapi-visit.h
|
||||
$(qapi-dir)/qga-qapi-visit.h: $(SRC_PATH)/qapi-schema-guest.json $(SRC_PATH)/scripts/qapi-visit.py
|
||||
$(call quiet-command,python $(SRC_PATH)/scripts/qapi-visit.py -o "$(qapi-dir)" -p "qga-" < $<, " GEN $@")
|
||||
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py -o "$(qapi-dir)" -p "qga-" < $<, " GEN $@")
|
||||
$(qapi-dir)/qga-qmp-marshal.c: $(SRC_PATH)/qapi-schema-guest.json $(SRC_PATH)/scripts/qapi-commands.py
|
||||
$(call quiet-command,python $(SRC_PATH)/scripts/qapi-commands.py -o "$(qapi-dir)" -p "qga-" < $<, " GEN $@")
|
||||
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py -o "$(qapi-dir)" -p "qga-" < $<, " GEN $@")
|
||||
|
||||
test-visitor.o: $(addprefix $(qapi-dir)/, test-qapi-types.c test-qapi-types.h test-qapi-visit.c test-qapi-visit.h) $(qapi-obj-y)
|
||||
test-visitor: test-visitor.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o $(qapi-obj-y) error.o osdep.o qemu-malloc.o $(oslib-obj-y) qjson.o json-streamer.o json-lexer.o json-parser.o qerror.o qemu-error.o qemu-tool.o $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o
|
||||
|
61
balloon.c
61
balloon.c
@@ -1,7 +1,9 @@
|
||||
/*
|
||||
* QEMU System Emulator
|
||||
* Generic Balloon handlers and management
|
||||
*
|
||||
* Copyright (c) 2003-2008 Fabrice Bellard
|
||||
* Copyright (C) 2011 Red Hat, Inc.
|
||||
* Copyright (C) 2011 Amit Shah <amit.shah@redhat.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -30,44 +32,53 @@
|
||||
#include "balloon.h"
|
||||
#include "trace.h"
|
||||
|
||||
static QEMUBalloonEvent *balloon_event_fn;
|
||||
static QEMUBalloonStatus *balloon_stat_fn;
|
||||
static void *balloon_opaque;
|
||||
|
||||
static QEMUBalloonEvent *qemu_balloon_event;
|
||||
void *qemu_balloon_event_opaque;
|
||||
|
||||
void qemu_add_balloon_handler(QEMUBalloonEvent *func, void *opaque)
|
||||
int qemu_add_balloon_handler(QEMUBalloonEvent *event_func,
|
||||
QEMUBalloonStatus *stat_func, void *opaque)
|
||||
{
|
||||
qemu_balloon_event = func;
|
||||
qemu_balloon_event_opaque = opaque;
|
||||
if (balloon_event_fn || balloon_stat_fn || balloon_opaque) {
|
||||
/* We're already registered one balloon handler. How many can
|
||||
* a guest really have?
|
||||
*/
|
||||
error_report("Another balloon device already registered");
|
||||
return -1;
|
||||
}
|
||||
balloon_event_fn = event_func;
|
||||
balloon_stat_fn = stat_func;
|
||||
balloon_opaque = opaque;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int qemu_balloon(ram_addr_t target, MonitorCompletion cb, void *opaque)
|
||||
static int qemu_balloon(ram_addr_t target)
|
||||
{
|
||||
if (qemu_balloon_event) {
|
||||
trace_balloon_event(qemu_balloon_event_opaque, target);
|
||||
qemu_balloon_event(qemu_balloon_event_opaque, target, cb, opaque);
|
||||
return 1;
|
||||
} else {
|
||||
if (!balloon_event_fn) {
|
||||
return 0;
|
||||
}
|
||||
trace_balloon_event(balloon_opaque, target);
|
||||
balloon_event_fn(balloon_opaque, target);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int qemu_balloon_status(MonitorCompletion cb, void *opaque)
|
||||
static int qemu_balloon_status(MonitorCompletion cb, void *opaque)
|
||||
{
|
||||
if (qemu_balloon_event) {
|
||||
qemu_balloon_event(qemu_balloon_event_opaque, 0, cb, opaque);
|
||||
return 1;
|
||||
} else {
|
||||
if (!balloon_stat_fn) {
|
||||
return 0;
|
||||
}
|
||||
balloon_stat_fn(balloon_opaque, cb, opaque);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void print_balloon_stat(const char *key, QObject *obj, void *opaque)
|
||||
{
|
||||
Monitor *mon = opaque;
|
||||
|
||||
if (strcmp(key, "actual"))
|
||||
if (strcmp(key, "actual")) {
|
||||
monitor_printf(mon, ",%s=%" PRId64, key,
|
||||
qint_get_int(qobject_to_qint(obj)));
|
||||
}
|
||||
}
|
||||
|
||||
void monitor_print_balloon(Monitor *mon, const QObject *data)
|
||||
@@ -75,9 +86,9 @@ void monitor_print_balloon(Monitor *mon, const QObject *data)
|
||||
QDict *qdict;
|
||||
|
||||
qdict = qobject_to_qdict(data);
|
||||
if (!qdict_haskey(qdict, "actual"))
|
||||
if (!qdict_haskey(qdict, "actual")) {
|
||||
return;
|
||||
|
||||
}
|
||||
monitor_printf(mon, "balloon: actual=%" PRId64,
|
||||
qdict_get_int(qdict, "actual") >> 20);
|
||||
qdict_iter(qdict, print_balloon_stat, mon);
|
||||
@@ -129,6 +140,7 @@ int do_info_balloon(Monitor *mon, MonitorCompletion cb, void *opaque)
|
||||
int do_balloon(Monitor *mon, const QDict *params,
|
||||
MonitorCompletion cb, void *opaque)
|
||||
{
|
||||
int64_t target;
|
||||
int ret;
|
||||
|
||||
if (kvm_enabled() && !kvm_has_sync_mmu()) {
|
||||
@@ -136,7 +148,12 @@ int do_balloon(Monitor *mon, const QDict *params,
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = qemu_balloon(qdict_get_int(params, "value"), cb, opaque);
|
||||
target = qdict_get_int(params, "value");
|
||||
if (target <= 0) {
|
||||
qerror_report(QERR_INVALID_PARAMETER_VALUE, "target", "a size");
|
||||
return -1;
|
||||
}
|
||||
ret = qemu_balloon(target);
|
||||
if (ret == 0) {
|
||||
qerror_report(QERR_DEVICE_NOT_ACTIVE, "balloon");
|
||||
return -1;
|
||||
|
12
balloon.h
12
balloon.h
@@ -16,14 +16,12 @@
|
||||
|
||||
#include "monitor.h"
|
||||
|
||||
typedef void (QEMUBalloonEvent)(void *opaque, ram_addr_t target,
|
||||
MonitorCompletion cb, void *cb_data);
|
||||
typedef void (QEMUBalloonEvent)(void *opaque, ram_addr_t target);
|
||||
typedef void (QEMUBalloonStatus)(void *opaque, MonitorCompletion cb,
|
||||
void *cb_data);
|
||||
|
||||
void qemu_add_balloon_handler(QEMUBalloonEvent *func, void *opaque);
|
||||
|
||||
int qemu_balloon(ram_addr_t target, MonitorCompletion cb, void *opaque);
|
||||
|
||||
int qemu_balloon_status(MonitorCompletion cb, void *opaque);
|
||||
int qemu_add_balloon_handler(QEMUBalloonEvent *event_func,
|
||||
QEMUBalloonStatus *stat_func, void *opaque);
|
||||
|
||||
void monitor_print_balloon(Monitor *mon, const QObject *data);
|
||||
int do_info_balloon(Monitor *mon, MonitorCompletion cb, void *opaque);
|
||||
|
@@ -496,7 +496,7 @@ static ssize_t recvmsg(int s, struct msghdr *msg, int flags)
|
||||
}
|
||||
buf = qemu_malloc(size);
|
||||
|
||||
ret = recv(s, buf, size, flags);
|
||||
ret = qemu_recv(s, buf, size, flags);
|
||||
if (ret < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
19
configure
vendored
19
configure
vendored
@@ -475,6 +475,7 @@ fi
|
||||
|
||||
: ${make=${MAKE-make}}
|
||||
: ${install=${INSTALL-install}}
|
||||
: ${python=${PYTHON-python}}
|
||||
|
||||
if test "$mingw32" = "yes" ; then
|
||||
EXESUF=".exe"
|
||||
@@ -516,6 +517,8 @@ for opt do
|
||||
;;
|
||||
--install=*) install="$optarg"
|
||||
;;
|
||||
--python=*) python="$optarg"
|
||||
;;
|
||||
--extra-cflags=*)
|
||||
;;
|
||||
--extra-ldflags=*)
|
||||
@@ -924,6 +927,7 @@ echo " --extra-cflags=CFLAGS append extra C compiler flags QEMU_CFLAGS"
|
||||
echo " --extra-ldflags=LDFLAGS append extra linker flags LDFLAGS"
|
||||
echo " --make=MAKE use specified make [$make]"
|
||||
echo " --install=INSTALL use specified install [$install]"
|
||||
echo " --python=PYTHON use specified python [$python]"
|
||||
echo " --static enable static build [$static]"
|
||||
echo " --mandir=PATH install man pages in PATH"
|
||||
echo " --datadir=PATH install firmware in PATH"
|
||||
@@ -1084,6 +1088,13 @@ if test "$solaris" = "yes" ; then
|
||||
fi
|
||||
fi
|
||||
|
||||
if has $python; then
|
||||
:
|
||||
else
|
||||
echo "Python not found. Use --python=/path/to/python"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$target_list" ; then
|
||||
target_list="$default_target_list"
|
||||
else
|
||||
@@ -1811,9 +1822,9 @@ fi
|
||||
|
||||
##########################################
|
||||
# glib support probe
|
||||
if $pkg_config --modversion gthread-2.0 gio-2.0 > /dev/null 2>&1 ; then
|
||||
glib_cflags=`$pkg_config --cflags gthread-2.0 gio-2.0 2>/dev/null`
|
||||
glib_libs=`$pkg_config --libs gthread-2.0 gio-2.0 2>/dev/null`
|
||||
if $pkg_config --modversion glib-2.0 > /dev/null 2>&1 ; then
|
||||
glib_cflags=`$pkg_config --cflags glib-2.0 2>/dev/null`
|
||||
glib_libs=`$pkg_config --libs glib-2.0 2>/dev/null`
|
||||
libs_softmmu="$glib_libs $libs_softmmu"
|
||||
libs_tools="$glib_libs $libs_tools"
|
||||
else
|
||||
@@ -2591,6 +2602,7 @@ echo "QEMU_CFLAGS $QEMU_CFLAGS"
|
||||
echo "LDFLAGS $LDFLAGS"
|
||||
echo "make $make"
|
||||
echo "install $install"
|
||||
echo "python $python"
|
||||
echo "host CPU $cpu"
|
||||
echo "host big endian $bigendian"
|
||||
echo "target list $target_list"
|
||||
@@ -3003,6 +3015,7 @@ echo "INSTALL=$install" >> $config_host_mak
|
||||
echo "INSTALL_DIR=$install -d -m0755 -p" >> $config_host_mak
|
||||
echo "INSTALL_DATA=$install -m0644 -p" >> $config_host_mak
|
||||
echo "INSTALL_PROG=$install -m0755 -p" >> $config_host_mak
|
||||
echo "PYTHON=$python" >> $config_host_mak
|
||||
echo "CC=$cc" >> $config_host_mak
|
||||
echo "CC_I386=$cc_i386" >> $config_host_mak
|
||||
echo "HOST_CC=$host_cc" >> $config_host_mak
|
||||
|
@@ -319,7 +319,7 @@ static int get_char(GDBState *s)
|
||||
int ret;
|
||||
|
||||
for(;;) {
|
||||
ret = recv(s->fd, &ch, 1, 0);
|
||||
ret = qemu_recv(s->fd, &ch, 1, 0);
|
||||
if (ret < 0) {
|
||||
if (errno == ECONNRESET)
|
||||
s->fd = -1;
|
||||
|
@@ -23,4 +23,4 @@
|
||||
*/
|
||||
|
||||
/* char device */
|
||||
CharDriverState *chr_baum_init(QemuOpts *opts);
|
||||
int chr_baum_init(QemuOpts *opts, CharDriverState **_chr);
|
||||
|
@@ -1,7 +1,9 @@
|
||||
/*
|
||||
* Virtio Block Device
|
||||
* Virtio Balloon Device
|
||||
*
|
||||
* Copyright IBM, Corp. 2008
|
||||
* Copyright (C) 2011 Red Hat, Inc.
|
||||
* Copyright (C) 2011 Amit Shah <amit.shah@redhat.com>
|
||||
*
|
||||
* Authors:
|
||||
* Anthony Liguori <aliguori@us.ibm.com>
|
||||
@@ -43,6 +45,7 @@ typedef struct VirtIOBalloon
|
||||
size_t stats_vq_offset;
|
||||
MonitorCompletion *stats_callback;
|
||||
void *stats_opaque_callback_data;
|
||||
DeviceState *qdev;
|
||||
} VirtIOBalloon;
|
||||
|
||||
static VirtIOBalloon *to_virtio_balloon(VirtIODevice *vdev)
|
||||
@@ -199,36 +202,44 @@ static uint32_t virtio_balloon_get_features(VirtIODevice *vdev, uint32_t f)
|
||||
return f;
|
||||
}
|
||||
|
||||
static void virtio_balloon_to_target(void *opaque, ram_addr_t target,
|
||||
MonitorCompletion cb, void *cb_data)
|
||||
static void virtio_balloon_stat(void *opaque, MonitorCompletion cb,
|
||||
void *cb_data)
|
||||
{
|
||||
VirtIOBalloon *dev = opaque;
|
||||
|
||||
if (target > ram_size)
|
||||
target = ram_size;
|
||||
/* For now, only allow one request at a time. This restriction can be
|
||||
* removed later by queueing callback and data pairs.
|
||||
*/
|
||||
if (dev->stats_callback != NULL) {
|
||||
return;
|
||||
}
|
||||
dev->stats_callback = cb;
|
||||
dev->stats_opaque_callback_data = cb_data;
|
||||
|
||||
if (ENABLE_GUEST_STATS
|
||||
&& (dev->vdev.guest_features & (1 << VIRTIO_BALLOON_F_STATS_VQ))) {
|
||||
virtqueue_push(dev->svq, &dev->stats_vq_elem, dev->stats_vq_offset);
|
||||
virtio_notify(&dev->vdev, dev->svq);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Stats are not supported. Clear out any stale values that might
|
||||
* have been set by a more featureful guest kernel.
|
||||
*/
|
||||
reset_stats(dev);
|
||||
complete_stats_request(dev);
|
||||
}
|
||||
|
||||
static void virtio_balloon_to_target(void *opaque, ram_addr_t target)
|
||||
{
|
||||
VirtIOBalloon *dev = opaque;
|
||||
|
||||
if (target > ram_size) {
|
||||
target = ram_size;
|
||||
}
|
||||
if (target) {
|
||||
dev->num_pages = (ram_size - target) >> VIRTIO_BALLOON_PFN_SHIFT;
|
||||
virtio_notify_config(&dev->vdev);
|
||||
} else {
|
||||
/* For now, only allow one request at a time. This restriction can be
|
||||
* removed later by queueing callback and data pairs.
|
||||
*/
|
||||
if (dev->stats_callback != NULL) {
|
||||
return;
|
||||
}
|
||||
dev->stats_callback = cb;
|
||||
dev->stats_opaque_callback_data = cb_data;
|
||||
if (ENABLE_GUEST_STATS && (dev->vdev.guest_features & (1 << VIRTIO_BALLOON_F_STATS_VQ))) {
|
||||
virtqueue_push(dev->svq, &dev->stats_vq_elem, dev->stats_vq_offset);
|
||||
virtio_notify(&dev->vdev, dev->svq);
|
||||
} else {
|
||||
/* Stats are not supported. Clear out any stale values that might
|
||||
* have been set by a more featureful guest kernel.
|
||||
*/
|
||||
reset_stats(dev);
|
||||
complete_stats_request(dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,6 +270,7 @@ static int virtio_balloon_load(QEMUFile *f, void *opaque, int version_id)
|
||||
VirtIODevice *virtio_balloon_init(DeviceState *dev)
|
||||
{
|
||||
VirtIOBalloon *s;
|
||||
int ret;
|
||||
|
||||
s = (VirtIOBalloon *)virtio_common_init("virtio-balloon",
|
||||
VIRTIO_ID_BALLOON,
|
||||
@@ -268,15 +280,29 @@ VirtIODevice *virtio_balloon_init(DeviceState *dev)
|
||||
s->vdev.set_config = virtio_balloon_set_config;
|
||||
s->vdev.get_features = virtio_balloon_get_features;
|
||||
|
||||
ret = qemu_add_balloon_handler(virtio_balloon_to_target,
|
||||
virtio_balloon_stat, s);
|
||||
if (ret < 0) {
|
||||
virtio_cleanup(&s->vdev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
s->ivq = virtio_add_queue(&s->vdev, 128, virtio_balloon_handle_output);
|
||||
s->dvq = virtio_add_queue(&s->vdev, 128, virtio_balloon_handle_output);
|
||||
s->svq = virtio_add_queue(&s->vdev, 128, virtio_balloon_receive_stats);
|
||||
|
||||
reset_stats(s);
|
||||
qemu_add_balloon_handler(virtio_balloon_to_target, s);
|
||||
|
||||
s->qdev = dev;
|
||||
register_savevm(dev, "virtio-balloon", -1, 1,
|
||||
virtio_balloon_save, virtio_balloon_load, s);
|
||||
|
||||
return &s->vdev;
|
||||
}
|
||||
|
||||
void virtio_balloon_exit(VirtIODevice *vdev)
|
||||
{
|
||||
VirtIOBalloon *s = DO_UPCAST(VirtIOBalloon, vdev, vdev);
|
||||
unregister_savevm(s->qdev, "virtio-balloon", s);
|
||||
virtio_cleanup(vdev);
|
||||
}
|
||||
|
@@ -788,10 +788,22 @@ static int virtio_balloon_init_pci(PCIDevice *pci_dev)
|
||||
VirtIODevice *vdev;
|
||||
|
||||
vdev = virtio_balloon_init(&pci_dev->qdev);
|
||||
if (!vdev) {
|
||||
return -1;
|
||||
}
|
||||
virtio_init_pci(proxy, vdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int virtio_balloon_exit_pci(PCIDevice *pci_dev)
|
||||
{
|
||||
VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
|
||||
|
||||
virtio_pci_stop_ioeventfd(proxy);
|
||||
virtio_balloon_exit(proxy->vdev);
|
||||
return virtio_exit_pci(pci_dev);
|
||||
}
|
||||
|
||||
static PCIDeviceInfo virtio_info[] = {
|
||||
{
|
||||
.qdev.name = "virtio-blk-pci",
|
||||
@@ -866,7 +878,7 @@ static PCIDeviceInfo virtio_info[] = {
|
||||
.qdev.alias = "virtio-balloon",
|
||||
.qdev.size = sizeof(VirtIOPCIProxy),
|
||||
.init = virtio_balloon_init_pci,
|
||||
.exit = virtio_exit_pci,
|
||||
.exit = virtio_balloon_exit_pci,
|
||||
.vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
|
||||
.device_id = PCI_DEVICE_ID_VIRTIO_BALLOON,
|
||||
.revision = VIRTIO_PCI_ABI_VERSION,
|
||||
|
@@ -213,6 +213,7 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf);
|
||||
void virtio_net_exit(VirtIODevice *vdev);
|
||||
void virtio_blk_exit(VirtIODevice *vdev);
|
||||
void virtio_serial_exit(VirtIODevice *vdev);
|
||||
void virtio_balloon_exit(VirtIODevice *vdev);
|
||||
|
||||
#define DEFINE_VIRTIO_COMMON_FEATURES(_state, _field) \
|
||||
DEFINE_PROP_BIT("indirect_desc", _state, _field, \
|
||||
|
@@ -2004,7 +2004,7 @@ static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
|
||||
ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
|
||||
} else {
|
||||
addr = NULL; /* To keep compiler quiet. */
|
||||
ret = get_errno(recv(fd, host_msg, len, flags));
|
||||
ret = get_errno(qemu_recv(fd, host_msg, len, flags));
|
||||
}
|
||||
if (!is_error(ret)) {
|
||||
if (target_addr) {
|
||||
|
2
nbd.c
2
nbd.c
@@ -78,7 +78,7 @@ size_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read)
|
||||
ssize_t len;
|
||||
|
||||
if (do_read) {
|
||||
len = recv(fd, buffer + offset, size - offset, 0);
|
||||
len = qemu_recv(fd, buffer + offset, size - offset, 0);
|
||||
} else {
|
||||
len = send(fd, buffer + offset, size - offset, 0);
|
||||
}
|
||||
|
@@ -76,7 +76,7 @@ static void net_socket_send(void *opaque)
|
||||
uint8_t buf1[4096];
|
||||
const uint8_t *buf;
|
||||
|
||||
size = recv(s->fd, (void *)buf1, sizeof(buf1), 0);
|
||||
size = qemu_recv(s->fd, buf1, sizeof(buf1), 0);
|
||||
if (size < 0) {
|
||||
err = socket_error();
|
||||
if (err != EWOULDBLOCK)
|
||||
@@ -138,7 +138,7 @@ static void net_socket_send_dgram(void *opaque)
|
||||
NetSocketState *s = opaque;
|
||||
int size;
|
||||
|
||||
size = recv(s->fd, (void *)s->buf, sizeof(s->buf), 0);
|
||||
size = qemu_recv(s->fd, s->buf, sizeof(s->buf), 0);
|
||||
if (size < 0)
|
||||
return;
|
||||
if (size == 0) {
|
||||
|
11
qemu-char.c
11
qemu-char.c
@@ -1782,7 +1782,7 @@ static int qemu_chr_open_win_pipe(QemuOpts *opts, CharDriverState **_chr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static CharDriverState *qemu_chr_open_win_file(HANDLE fd_out)
|
||||
static int qemu_chr_open_win_file(HANDLE fd_out, CharDriverState **pchr)
|
||||
{
|
||||
CharDriverState *chr;
|
||||
WinCharState *s;
|
||||
@@ -1793,10 +1793,11 @@ static CharDriverState *qemu_chr_open_win_file(HANDLE fd_out)
|
||||
chr->opaque = s;
|
||||
chr->chr_write = win_chr_write;
|
||||
qemu_chr_generic_open(chr);
|
||||
return chr;
|
||||
*pchr = chr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qemu_chr_open_win_con(QemuOpts *opts, CharDriverState **_chr)
|
||||
static int qemu_chr_open_win_con(QemuOpts *opts, CharDriverState **chr)
|
||||
{
|
||||
return qemu_chr_open_win_file(GetStdHandle(STD_OUTPUT_HANDLE), chr);
|
||||
}
|
||||
@@ -1859,7 +1860,7 @@ static void udp_chr_read(void *opaque)
|
||||
|
||||
if (s->max_size == 0)
|
||||
return;
|
||||
s->bufcnt = recv(s->fd, (void *)s->buf, sizeof(s->buf), 0);
|
||||
s->bufcnt = qemu_recv(s->fd, s->buf, sizeof(s->buf), 0);
|
||||
s->bufptr = s->bufcnt;
|
||||
if (s->bufcnt <= 0)
|
||||
return;
|
||||
@@ -2077,7 +2078,7 @@ static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len)
|
||||
static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len)
|
||||
{
|
||||
TCPCharDriver *s = chr->opaque;
|
||||
return recv(s->fd, buf, len, 0);
|
||||
return qemu_recv(s->fd, buf, len, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@@ -200,6 +200,12 @@ int qemu_eventfd(int pipefd[2]);
|
||||
int qemu_pipe(int pipefd[2]);
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define qemu_recv(sockfd, buf, len, flags) recv(sockfd, (void *)buf, len, flags)
|
||||
#else
|
||||
#define qemu_recv(sockfd, buf, len, flags) recv(sockfd, buf, len, flags)
|
||||
#endif
|
||||
|
||||
/* Error handling. */
|
||||
|
||||
void QEMU_NORETURN hw_error(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
|
||||
|
35
qemu-ga.c
35
qemu-ga.c
@@ -14,7 +14,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <glib.h>
|
||||
#include <gio/gio.h>
|
||||
#include <getopt.h>
|
||||
#include <termios.h>
|
||||
#include <syslog.h>
|
||||
@@ -37,9 +36,7 @@
|
||||
struct GAState {
|
||||
JSONMessageParser parser;
|
||||
GMainLoop *main_loop;
|
||||
GSocket *conn_sock;
|
||||
GIOChannel *conn_channel;
|
||||
GSocket *listen_sock;
|
||||
GIOChannel *listen_channel;
|
||||
const char *path;
|
||||
const char *method;
|
||||
@@ -412,18 +409,20 @@ static gboolean listen_channel_accept(GIOChannel *channel,
|
||||
GIOCondition condition, gpointer data)
|
||||
{
|
||||
GAState *s = data;
|
||||
GError *err = NULL;
|
||||
g_assert(channel != NULL);
|
||||
int ret;
|
||||
int ret, conn_fd;
|
||||
bool accepted = false;
|
||||
struct sockaddr_un addr;
|
||||
socklen_t addrlen = sizeof(addr);
|
||||
|
||||
s->conn_sock = g_socket_accept(s->listen_sock, NULL, &err);
|
||||
if (err != NULL) {
|
||||
g_warning("error converting fd to gsocket: %s", err->message);
|
||||
g_error_free(err);
|
||||
conn_fd = qemu_accept(g_io_channel_unix_get_fd(s->listen_channel),
|
||||
(struct sockaddr *)&addr, &addrlen);
|
||||
if (conn_fd == -1) {
|
||||
g_warning("error converting fd to gsocket: %s", strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
ret = conn_channel_add(s, g_socket_get_fd(s->conn_sock));
|
||||
fcntl(conn_fd, F_SETFL, O_NONBLOCK);
|
||||
ret = conn_channel_add(s, conn_fd);
|
||||
if (ret) {
|
||||
g_warning("error setting up connection");
|
||||
goto out;
|
||||
@@ -440,19 +439,8 @@ out:
|
||||
*/
|
||||
static int listen_channel_add(GAState *s, int listen_fd, bool new)
|
||||
{
|
||||
GError *err = NULL;
|
||||
|
||||
if (new) {
|
||||
s->listen_channel = g_io_channel_unix_new(listen_fd);
|
||||
if (s->listen_sock) {
|
||||
g_object_unref(s->listen_sock);
|
||||
}
|
||||
s->listen_sock = g_socket_new_from_fd(listen_fd, &err);
|
||||
if (err != NULL) {
|
||||
g_warning("error converting fd to gsocket: %s", err->message);
|
||||
g_error_free(err);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
g_io_add_watch(s->listen_channel, G_IO_IN,
|
||||
listen_channel_accept, s);
|
||||
@@ -466,8 +454,6 @@ static void conn_channel_close(GAState *s)
|
||||
{
|
||||
if (strcmp(s->method, "unix-listen") == 0) {
|
||||
g_io_channel_shutdown(s->conn_channel, true, NULL);
|
||||
g_object_unref(s->conn_sock);
|
||||
s->conn_sock = NULL;
|
||||
listen_channel_add(s, 0, false);
|
||||
} else if (strcmp(s->method, "virtio-serial") == 0) {
|
||||
/* we spin on EOF for virtio-serial, so back off a bit. also,
|
||||
@@ -624,9 +610,6 @@ int main(int argc, char **argv)
|
||||
become_daemon(pidfile);
|
||||
}
|
||||
|
||||
g_type_init();
|
||||
g_thread_init(NULL);
|
||||
|
||||
s = qemu_mallocz(sizeof(GAState));
|
||||
s->conn_channel = NULL;
|
||||
s->path = path;
|
||||
|
@@ -10,15 +10,17 @@
|
||||
* See the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
#if defined(__linux__)
|
||||
#define CONFIG_FSFREEZE
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
#if defined(CONFIG_FSFREEZE)
|
||||
|
||||
#if defined(__linux__)
|
||||
#include <mntent.h>
|
||||
#include <linux/fs.h>
|
||||
|
||||
#if defined(__linux__) && defined(FIFREEZE)
|
||||
#define CONFIG_FSFREEZE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include "qga/guest-agent-core.h"
|
||||
|
2
savevm.c
2
savevm.c
@@ -194,7 +194,7 @@ static int socket_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
|
||||
ssize_t len;
|
||||
|
||||
do {
|
||||
len = recv(s->fd, (void *)buf, size, 0);
|
||||
len = qemu_recv(s->fd, buf, size, 0);
|
||||
} while (len == -1 && socket_error() == EINTR);
|
||||
|
||||
if (len == -1)
|
||||
|
@@ -119,7 +119,7 @@ static void *writeout_thread(void *opaque)
|
||||
TraceRecord record;
|
||||
unsigned int writeout_idx = 0;
|
||||
unsigned int num_available, idx;
|
||||
size_t unused;
|
||||
size_t unused __attribute__ ((unused));
|
||||
|
||||
for (;;) {
|
||||
wait_for_trace_records_available();
|
||||
|
@@ -415,7 +415,7 @@ void icmp_receive(struct socket *so)
|
||||
icp = mtod(m, struct icmp *);
|
||||
|
||||
id = icp->icmp_id;
|
||||
len = recv(so->s, icp, m->m_len, 0);
|
||||
len = qemu_recv(so->s, icp, m->m_len, 0);
|
||||
icp->icmp_id = id;
|
||||
|
||||
m->m_data -= hlen;
|
||||
|
@@ -522,7 +522,7 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds,
|
||||
*/
|
||||
#ifdef PROBE_CONN
|
||||
if (so->so_state & SS_ISFCONNECTING) {
|
||||
ret = recv(so->s, (char *)&ret, 0,0);
|
||||
ret = qemu_recv(so->s, &ret, 0,0);
|
||||
|
||||
if (ret < 0) {
|
||||
/* XXX */
|
||||
|
@@ -166,7 +166,7 @@ soread(struct socket *so)
|
||||
nn = readv(so->s, (struct iovec *)iov, n);
|
||||
DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn));
|
||||
#else
|
||||
nn = recv(so->s, iov[0].iov_base, iov[0].iov_len,0);
|
||||
nn = qemu_recv(so->s, iov[0].iov_base, iov[0].iov_len,0);
|
||||
#endif
|
||||
if (nn <= 0) {
|
||||
if (nn < 0 && (errno == EINTR || errno == EAGAIN))
|
||||
@@ -191,7 +191,7 @@ soread(struct socket *so)
|
||||
*/
|
||||
if (n == 2 && nn == iov[0].iov_len) {
|
||||
int ret;
|
||||
ret = recv(so->s, iov[1].iov_base, iov[1].iov_len,0);
|
||||
ret = qemu_recv(so->s, iov[1].iov_base, iov[1].iov_len,0);
|
||||
if (ret > 0)
|
||||
nn += ret;
|
||||
}
|
||||
|
@@ -374,6 +374,7 @@ enum arm_features {
|
||||
ARM_FEATURE_V4T,
|
||||
ARM_FEATURE_V5,
|
||||
ARM_FEATURE_STRONGARM,
|
||||
ARM_FEATURE_VAPA, /* cp15 VA to PA lookups */
|
||||
};
|
||||
|
||||
static inline int arm_feature(CPUARMState *env, int feature)
|
||||
|
@@ -70,13 +70,24 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
|
||||
env->cp15.c0_cachetype = 0x1dd20d2;
|
||||
env->cp15.c1_sys = 0x00090078;
|
||||
break;
|
||||
case ARM_CPUID_ARM1136_R2:
|
||||
case ARM_CPUID_ARM1136:
|
||||
/* This is the 1136 r1, which is a v6K core */
|
||||
set_feature(env, ARM_FEATURE_V6K);
|
||||
/* Fall through */
|
||||
case ARM_CPUID_ARM1136_R2:
|
||||
/* What qemu calls "arm1136_r2" is actually the 1136 r0p2, ie an
|
||||
* older core than plain "arm1136". In particular this does not
|
||||
* have the v6K features.
|
||||
*/
|
||||
set_feature(env, ARM_FEATURE_V4T);
|
||||
set_feature(env, ARM_FEATURE_V5);
|
||||
set_feature(env, ARM_FEATURE_V6);
|
||||
set_feature(env, ARM_FEATURE_VFP);
|
||||
set_feature(env, ARM_FEATURE_AUXCR);
|
||||
/* These ID register values are correct for 1136 but may be wrong
|
||||
* for 1136_r2 (in particular r0p2 does not actually implement most
|
||||
* of the ID registers).
|
||||
*/
|
||||
env->vfp.xregs[ARM_VFP_FPSID] = 0x410120b4;
|
||||
env->vfp.xregs[ARM_VFP_MVFR0] = 0x11111111;
|
||||
env->vfp.xregs[ARM_VFP_MVFR1] = 0x00000000;
|
||||
@@ -92,6 +103,7 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
|
||||
set_feature(env, ARM_FEATURE_V6K);
|
||||
set_feature(env, ARM_FEATURE_VFP);
|
||||
set_feature(env, ARM_FEATURE_AUXCR);
|
||||
set_feature(env, ARM_FEATURE_VAPA);
|
||||
env->vfp.xregs[ARM_VFP_FPSID] = 0x410120b4;
|
||||
env->vfp.xregs[ARM_VFP_MVFR0] = 0x11111111;
|
||||
env->vfp.xregs[ARM_VFP_MVFR1] = 0x00000000;
|
||||
@@ -222,6 +234,11 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
|
||||
cpu_abort(env, "Bad CPU ID: %x\n", id);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Some features automatically imply others: */
|
||||
if (arm_feature(env, ARM_FEATURE_V7)) {
|
||||
set_feature(env, ARM_FEATURE_VAPA);
|
||||
}
|
||||
}
|
||||
|
||||
void cpu_reset(CPUARMState *env)
|
||||
@@ -1502,7 +1519,7 @@ void HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val)
|
||||
goto bad_reg;
|
||||
}
|
||||
/* No cache, so nothing to do except VA->PA translations. */
|
||||
if (arm_feature(env, ARM_FEATURE_V6K)) {
|
||||
if (arm_feature(env, ARM_FEATURE_VAPA)) {
|
||||
switch (crm) {
|
||||
case 4:
|
||||
if (arm_feature(env, ARM_FEATURE_V7)) {
|
||||
|
@@ -2498,12 +2498,6 @@ static int cp15_user_ok(CPUState *env, uint32_t insn)
|
||||
if (op == 2 || (op == 3 && (insn & ARM_CP_RW_BIT)))
|
||||
return 1;
|
||||
}
|
||||
if (cpn == 7) {
|
||||
/* ISB, DSB, DMB. */
|
||||
if ((cpm == 5 && op == 4)
|
||||
|| (cpm == 10 && (op == 4 || op == 5)))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2579,39 +2573,60 @@ static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
|
||||
/* cdp */
|
||||
return 1;
|
||||
}
|
||||
if (IS_USER(s) && !cp15_user_ok(env, insn)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Pre-v7 versions of the architecture implemented WFI via coprocessor
|
||||
* instructions rather than a separate instruction.
|
||||
/* We special case a number of cp15 instructions which were used
|
||||
* for things which are real instructions in ARMv7. This allows
|
||||
* them to work in linux-user mode which doesn't provide functional
|
||||
* get_cp15/set_cp15 helpers, and is more efficient anyway.
|
||||
*/
|
||||
if ((insn & 0x0fff0fff) == 0x0e070f90) {
|
||||
switch ((insn & 0x0fff0fff)) {
|
||||
case 0x0e070f90:
|
||||
/* 0,c7,c0,4: Standard v6 WFI (also used in some pre-v6 cores).
|
||||
* In v7, this must NOP.
|
||||
*/
|
||||
if (IS_USER(s)) {
|
||||
return 1;
|
||||
}
|
||||
if (!arm_feature(env, ARM_FEATURE_V7)) {
|
||||
/* Wait for interrupt. */
|
||||
gen_set_pc_im(s->pc);
|
||||
s->is_jmp = DISAS_WFI;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((insn & 0x0fff0fff) == 0x0e070f58) {
|
||||
case 0x0e070f58:
|
||||
/* 0,c7,c8,2: Not all pre-v6 cores implemented this WFI,
|
||||
* so this is slightly over-broad.
|
||||
*/
|
||||
if (!arm_feature(env, ARM_FEATURE_V6)) {
|
||||
if (!IS_USER(s) && !arm_feature(env, ARM_FEATURE_V6)) {
|
||||
/* Wait for interrupt. */
|
||||
gen_set_pc_im(s->pc);
|
||||
s->is_jmp = DISAS_WFI;
|
||||
return 0;
|
||||
}
|
||||
/* Otherwise fall through to handle via helper function.
|
||||
/* Otherwise continue to handle via helper function.
|
||||
* In particular, on v7 and some v6 cores this is one of
|
||||
* the VA-PA registers.
|
||||
*/
|
||||
break;
|
||||
case 0x0e070f3d:
|
||||
/* 0,c7,c13,1: prefetch-by-MVA in v6, NOP in v7 */
|
||||
if (arm_feature(env, ARM_FEATURE_V6)) {
|
||||
return IS_USER(s) ? 1 : 0;
|
||||
}
|
||||
break;
|
||||
case 0x0e070f95: /* 0,c7,c5,4 : ISB */
|
||||
case 0x0e070f9a: /* 0,c7,c10,4: DSB */
|
||||
case 0x0e070fba: /* 0,c7,c10,5: DMB */
|
||||
/* Barriers in both v6 and v7 */
|
||||
if (arm_feature(env, ARM_FEATURE_V6)) {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (IS_USER(s) && !cp15_user_ok(env, insn)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
rd = (insn >> 12) & 0xf;
|
||||
@@ -3056,6 +3071,17 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
|
||||
/* Source and destination the same. */
|
||||
gen_mov_F0_vreg(dp, rd);
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
/* VCVTB, VCVTT: only present with the halfprec extension,
|
||||
* UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
|
||||
*/
|
||||
if (dp || !arm_feature(env, ARM_FEATURE_VFP_FP16)) {
|
||||
return 1;
|
||||
}
|
||||
/* Otherwise fall through */
|
||||
default:
|
||||
/* One source operand. */
|
||||
gen_mov_F0_vreg(dp, rm);
|
||||
@@ -3152,24 +3178,18 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
|
||||
gen_vfp_sqrt(dp);
|
||||
break;
|
||||
case 4: /* vcvtb.f32.f16 */
|
||||
if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
|
||||
return 1;
|
||||
tmp = gen_vfp_mrs();
|
||||
tcg_gen_ext16u_i32(tmp, tmp);
|
||||
gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
|
||||
tcg_temp_free_i32(tmp);
|
||||
break;
|
||||
case 5: /* vcvtt.f32.f16 */
|
||||
if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
|
||||
return 1;
|
||||
tmp = gen_vfp_mrs();
|
||||
tcg_gen_shri_i32(tmp, tmp, 16);
|
||||
gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
|
||||
tcg_temp_free_i32(tmp);
|
||||
break;
|
||||
case 6: /* vcvtb.f16.f32 */
|
||||
if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
|
||||
return 1;
|
||||
tmp = tcg_temp_new_i32();
|
||||
gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
|
||||
gen_mov_F0_vreg(0, rd);
|
||||
@@ -3180,8 +3200,6 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
|
||||
gen_vfp_msr(tmp);
|
||||
break;
|
||||
case 7: /* vcvtt.f16.f32 */
|
||||
if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
|
||||
return 1;
|
||||
tmp = tcg_temp_new_i32();
|
||||
gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
|
||||
tcg_gen_shli_i32(tmp, tmp, 16);
|
||||
@@ -3382,17 +3400,18 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
|
||||
VFP_DREG_D(rd, insn);
|
||||
else
|
||||
rd = VFP_SREG_D(insn);
|
||||
if (s->thumb && rn == 15) {
|
||||
addr = tcg_temp_new_i32();
|
||||
tcg_gen_movi_i32(addr, s->pc & ~2);
|
||||
} else {
|
||||
addr = load_reg(s, rn);
|
||||
}
|
||||
if ((insn & 0x01200000) == 0x01000000) {
|
||||
/* Single load/store */
|
||||
offset = (insn & 0xff) << 2;
|
||||
if ((insn & (1 << 23)) == 0)
|
||||
offset = -offset;
|
||||
if (s->thumb && rn == 15) {
|
||||
/* This is actually UNPREDICTABLE */
|
||||
addr = tcg_temp_new_i32();
|
||||
tcg_gen_movi_i32(addr, s->pc & ~2);
|
||||
} else {
|
||||
addr = load_reg(s, rn);
|
||||
}
|
||||
tcg_gen_addi_i32(addr, addr, offset);
|
||||
if (insn & (1 << 20)) {
|
||||
gen_vfp_ld(s, dp, addr);
|
||||
@@ -3404,11 +3423,34 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
|
||||
tcg_temp_free_i32(addr);
|
||||
} else {
|
||||
/* load/store multiple */
|
||||
int w = insn & (1 << 21);
|
||||
if (dp)
|
||||
n = (insn >> 1) & 0x7f;
|
||||
else
|
||||
n = insn & 0xff;
|
||||
|
||||
if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
|
||||
/* P == U , W == 1 => UNDEF */
|
||||
return 1;
|
||||
}
|
||||
if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
|
||||
/* UNPREDICTABLE cases for bad immediates: we choose to
|
||||
* UNDEF to avoid generating huge numbers of TCG ops
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
if (rn == 15 && w) {
|
||||
/* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (s->thumb && rn == 15) {
|
||||
/* This is actually UNPREDICTABLE */
|
||||
addr = tcg_temp_new_i32();
|
||||
tcg_gen_movi_i32(addr, s->pc & ~2);
|
||||
} else {
|
||||
addr = load_reg(s, rn);
|
||||
}
|
||||
if (insn & (1 << 24)) /* pre-decrement */
|
||||
tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
|
||||
|
||||
@@ -3428,7 +3470,7 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
|
||||
}
|
||||
tcg_gen_addi_i32(addr, addr, offset);
|
||||
}
|
||||
if (insn & (1 << 21)) {
|
||||
if (w) {
|
||||
/* writeback */
|
||||
if (insn & (1 << 24))
|
||||
offset = -offset * n;
|
||||
|
@@ -89,7 +89,7 @@ static ssize_t vnc_tls_pull(gnutls_transport_ptr_t transport,
|
||||
int ret;
|
||||
|
||||
retry:
|
||||
ret = recv(vs->csock, data, len, 0);
|
||||
ret = qemu_recv(vs->csock, data, len, 0);
|
||||
if (ret < 0) {
|
||||
if (errno == EINTR)
|
||||
goto retry;
|
||||
|
2
ui/vnc.c
2
ui/vnc.c
@@ -1199,7 +1199,7 @@ long vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
|
||||
}
|
||||
} else
|
||||
#endif /* CONFIG_VNC_TLS */
|
||||
ret = recv(vs->csock, (void *)data, datalen, 0);
|
||||
ret = qemu_recv(vs->csock, data, datalen, 0);
|
||||
VNC_DEBUG("Read wire %p %zd -> %ld\n", data, datalen, ret);
|
||||
return vnc_client_io_error(vs, ret, socket_error());
|
||||
}
|
||||
|
Reference in New Issue
Block a user