aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--MAINTAINERS6
-rw-r--r--Makefile10
-rw-r--r--acl.c4
-rwxr-xr-xconfigure7
-rw-r--r--cpu-all.h4
-rw-r--r--cpus.c14
-rw-r--r--cpus.h1
-rw-r--r--darwin-user/main.c2
-rw-r--r--docs/qapi-code-gen.txt4
-rw-r--r--exec.c13
-rw-r--r--hw/fw_cfg.c102
-rw-r--r--hw/opencores_eth.c29
-rw-r--r--hw/qxl-render.c36
-rw-r--r--hw/qxl.c26
-rw-r--r--hw/qxl.h3
-rw-r--r--hw/sysbus.c2
-rw-r--r--ia64-dis.c3
-rw-r--r--migration-fd.c23
-rw-r--r--migration.c2
-rw-r--r--net/tap-linux.c6
-rw-r--r--oslib-posix.c22
-rw-r--r--qemu-barrier.h2
-rw-r--r--qemu-tls.h52
24 files changed, 253 insertions, 124 deletions
diff --git a/.gitignore b/.gitignore
index 6d2acab09a..406f75f2b6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,6 +17,10 @@ libhw64
libuser
linux-headers/asm
qapi-generated
+qapi-types.[ch]
+qapi-visit.[ch]
+qmp-commands.h
+qmp-marshal.c
qemu-doc.html
qemu-tech.html
qemu-doc.info
diff --git a/MAINTAINERS b/MAINTAINERS
index 4535eeb61f..bccdd4f78f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -303,9 +303,9 @@ M: Alexander Graf <agraf@suse.de>
S: Maintained
F: hw/ppc_oldworld.c
-Prep
-M: qemu-devel@nongnu.org
-S: Orphan
+PReP
+M: Andreas Färber <andreas.faerber@web.de>
+S: Odd Fixes
F: hw/ppc_prep.c
SH4 Machines
diff --git a/Makefile b/Makefile
index ba8d738d9b..4f6eaa4ba6 100644
--- a/Makefile
+++ b/Makefile
@@ -75,7 +75,7 @@ defconfig:
-include config-all-devices.mak
-build-all: $(DOCS) $(TOOLS) recurse-all
+build-all: $(DOCS) $(TOOLS) $(CHECKS) recurse-all
config-host.h: config-host.h-timestamp
config-host.h-timestamp: config-host.mak
@@ -219,7 +219,7 @@ clean:
# avoid old build problems by removing potentially incorrect old files
rm -f config.mak op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h
rm -f qemu-options.def
- rm -f *.o *.d *.a *.lo $(TOOLS) qemu-ga TAGS cscope.* *.pod *~ */*~
+ rm -f *.o *.d *.a *.lo $(TOOLS) $(CHECKS) qemu-ga TAGS cscope.* *.pod *~ */*~
rm -Rf .libs
rm -f slirp/*.o slirp/*.d audio/*.o audio/*.d block/*.o block/*.d net/*.o net/*.d fsdev/*.o fsdev/*.d ui/*.o ui/*.d qapi/*.o qapi/*.d qga/*.o qga/*.d
rm -f qemu-img-cmds.h
@@ -305,6 +305,12 @@ endif
test speed: all
$(MAKE) -C tests $@
+.PHONY: check
+check: $(patsubst %,run-check-%,$(CHECKS))
+
+run-check-%: %
+ ./$<
+
.PHONY: TAGS
TAGS:
find "$(SRC_PATH)" -name '*.[hc]' -print0 | xargs -0 etags
diff --git a/acl.c b/acl.c
index 0654f38f72..e840b9b633 100644
--- a/acl.c
+++ b/acl.c
@@ -95,13 +95,13 @@ int qemu_acl_party_is_allowed(qemu_acl *acl,
void qemu_acl_reset(qemu_acl *acl)
{
- qemu_acl_entry *entry;
+ qemu_acl_entry *entry, *next_entry;
/* Put back to deny by default, so there is no window
* of "open access" while the user re-initializes the
* access control list */
acl->defaultDeny = 1;
- QTAILQ_FOREACH(entry, &acl->entries, next) {
+ QTAILQ_FOREACH_SAFE(entry, &acl->entries, next, next_entry) {
QTAILQ_REMOVE(&acl->entries, entry, next);
free(entry->match);
free(entry);
diff --git a/configure b/configure
index a6cf6d680d..28667fe35b 100755
--- a/configure
+++ b/configure
@@ -169,7 +169,7 @@ mixemu="no"
aix="no"
blobs="yes"
pkgversion=""
-check_utests="no"
+check_utests=""
user_pie="no"
zero_malloc=""
trace_backend="nop"
@@ -2668,8 +2668,8 @@ if test "$softmmu" = yes ; then
tools="qemu-ga\$(EXESUF) $tools"
fi
if [ "$check_utests" = "yes" ]; then
- tools="check-qint check-qstring check-qdict check-qlist $tools"
- tools="check-qfloat check-qjson $tools"
+ checks="check-qint check-qstring check-qdict check-qlist"
+ checks="check-qfloat check-qjson test-coroutine $checks"
fi
fi
fi
@@ -3143,6 +3143,7 @@ if test "$trace_default" = "yes"; then
fi
echo "TOOLS=$tools" >> $config_host_mak
+echo "CHECKS=$checks" >> $config_host_mak
echo "ROMS=$roms" >> $config_host_mak
echo "MAKE=$make" >> $config_host_mak
echo "INSTALL=$install" >> $config_host_mak
diff --git a/cpu-all.h b/cpu-all.h
index 42a5fa0a7c..5f47ab8df9 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -20,6 +20,7 @@
#define CPU_ALL_H
#include "qemu-common.h"
+#include "qemu-tls.h"
#include "cpu-common.h"
/* some important defines:
@@ -334,7 +335,8 @@ void cpu_dump_statistics(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
void QEMU_NORETURN cpu_abort(CPUState *env, const char *fmt, ...)
GCC_FMT_ATTR(2, 3);
extern CPUState *first_cpu;
-extern CPUState *cpu_single_env;
+DECLARE_TLS(CPUState *,cpu_single_env);
+#define cpu_single_env get_tls(cpu_single_env)
/* Flags for use in ENV->INTERRUPT_PENDING.
diff --git a/cpus.c b/cpus.c
index f768683ad6..6aff425235 100644
--- a/cpus.c
+++ b/cpus.c
@@ -748,6 +748,8 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
return NULL;
}
+static void tcg_exec_all(void);
+
static void *qemu_tcg_cpu_thread_fn(void *arg)
{
CPUState *env = arg;
@@ -769,7 +771,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
}
while (1) {
- cpu_exec_all();
+ tcg_exec_all();
if (use_icount && qemu_clock_deadline(vm_clock) <= 0) {
qemu_notify_event();
}
@@ -1016,7 +1018,7 @@ static int tcg_cpu_exec(CPUState *env)
return ret;
}
-bool cpu_exec_all(void)
+static void tcg_exec_all(void)
{
int r;
@@ -1033,12 +1035,7 @@ bool cpu_exec_all(void)
(env->singlestep_enabled & SSTEP_NOTIMER) == 0);
if (cpu_can_run(env)) {
- if (kvm_enabled()) {
- r = kvm_cpu_exec(env);
- qemu_kvm_eat_signals(env);
- } else {
- r = tcg_cpu_exec(env);
- }
+ r = tcg_cpu_exec(env);
if (r == EXCP_DEBUG) {
cpu_handle_guest_debug(env);
break;
@@ -1048,7 +1045,6 @@ bool cpu_exec_all(void)
}
}
exit_request = 0;
- return !all_cpu_threads_idle();
}
void set_numa_modes(void)
diff --git a/cpus.h b/cpus.h
index 3525375756..4ea2fe2c22 100644
--- a/cpus.h
+++ b/cpus.h
@@ -14,7 +14,6 @@ void cpu_synchronize_all_post_init(void);
/* vl.c */
extern int smp_cores;
extern int smp_threads;
-bool cpu_exec_all(void);
void set_numa_modes(void);
void set_cpu_log(const char *optarg);
void set_cpu_log_filename(const char *optarg);
diff --git a/darwin-user/main.c b/darwin-user/main.c
index 1a881a0a60..c0f14f8260 100644
--- a/darwin-user/main.c
+++ b/darwin-user/main.c
@@ -729,8 +729,6 @@ static void usage(void)
/* XXX: currently only used for async signals (see signal.c) */
CPUState *global_env;
-/* used only if single thread */
-CPUState *cpu_single_env = NULL;
/* used to free thread contexts */
TaskState *first_task_state;
diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
index f345866f57..c0a9325db8 100644
--- a/docs/qapi-code-gen.txt
+++ b/docs/qapi-code-gen.txt
@@ -41,7 +41,7 @@ dictionary. This corresponds to a struct in C or an Object in JSON. An
example of a complex type is:
{ 'type': 'MyType',
- 'data' { 'member1': 'str', 'member2': 'int', '*member3': 'str } }
+ 'data': { 'member1': 'str', 'member2': 'int', '*member3': 'str' } }
The use of '*' as a prefix to the name means the member is optional. Optional
members should always be added to the end of the dictionary to preserve
@@ -63,7 +63,7 @@ An example command is:
{ 'command': 'my-command',
'data': { 'arg1': 'str', '*arg2': 'str' },
- 'returns': 'str' ]
+ 'returns': 'str' }
Command names should be all lower case with words separated by a hyphen.
diff --git a/exec.c b/exec.c
index 2f3c6a0ce3..6b92198e62 100644
--- a/exec.c
+++ b/exec.c
@@ -120,7 +120,7 @@ static MemoryRegion *system_io;
CPUState *first_cpu;
/* current CPU in the current thread. It is only valid inside
cpu_exec() */
-CPUState *cpu_single_env;
+DEFINE_TLS(CPUState *,cpu_single_env);
/* 0 = Do not count executed instructions.
1 = Precise instruction counting.
2 = Adaptive rate instruction counting. */
@@ -2873,7 +2873,7 @@ static void *file_ram_alloc(RAMBlock *block,
static ram_addr_t find_ram_offset(ram_addr_t size)
{
RAMBlock *block, *next_block;
- ram_addr_t offset = 0, mingap = RAM_ADDR_MAX;
+ ram_addr_t offset = RAM_ADDR_MAX, mingap = RAM_ADDR_MAX;
if (QLIST_EMPTY(&ram_list.blocks))
return 0;
@@ -2889,10 +2889,17 @@ static ram_addr_t find_ram_offset(ram_addr_t size)
}
}
if (next - end >= size && next - end < mingap) {
- offset = end;
+ offset = end;
mingap = next - end;
}
}
+
+ if (offset == RAM_ADDR_MAX) {
+ fprintf(stderr, "Failed to find gap of requested size: %" PRIu64 "\n",
+ (uint64_t)size);
+ abort();
+ }
+
return offset;
}
diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c
index 8df265c61d..dbcb888bbd 100644
--- a/hw/fw_cfg.c
+++ b/hw/fw_cfg.c
@@ -60,71 +60,55 @@ struct FWCfgState {
#define JPG_FILE 0
#define BMP_FILE 1
-static FILE *probe_splashfile(char *filename, int *file_sizep, int *file_typep)
+static char *read_splashfile(char *filename, int *file_sizep, int *file_typep)
{
- FILE *fp = NULL;
- int fop_ret;
- int file_size;
+ GError *err = NULL;
+ gboolean res;
+ gchar *content;
int file_type = -1;
- unsigned char buf[2] = {0, 0};
- unsigned int filehead_value = 0;
+ unsigned int filehead = 0;
int bmp_bpp;
- fp = fopen(filename, "rb");
- if (fp == NULL) {
- error_report("failed to open file '%s'.", filename);
- return fp;
+ res = g_file_get_contents(filename, &content, (gsize *)file_sizep, &err);
+ if (res == FALSE) {
+ error_report("failed to read splash file '%s'", filename);
+ g_error_free(err);
+ return NULL;
}
+
/* check file size */
- fseek(fp, 0L, SEEK_END);
- file_size = ftell(fp);
- if (file_size < 2) {
- error_report("file size is less than 2 bytes '%s'.", filename);
- fclose(fp);
- fp = NULL;
- return fp;
+ if (*file_sizep < 30) {
+ goto error;
}
+
/* check magic ID */
- fseek(fp, 0L, SEEK_SET);
- fop_ret = fread(buf, 1, 2, fp);
- if (fop_ret != 2) {
- error_report("Could not read header from '%s': %s",
- filename, strerror(errno));
- fclose(fp);
- fp = NULL;
- return fp;
- }
- filehead_value = (buf[0] + (buf[1] << 8)) & 0xffff;
- if (filehead_value == 0xd8ff) {
+ filehead = ((content[0] & 0xff) + (content[1] << 8)) & 0xffff;
+ if (filehead == 0xd8ff) {
file_type = JPG_FILE;
+ } else if (filehead == 0x4d42) {
+ file_type = BMP_FILE;
} else {
- if (filehead_value == 0x4d42) {
- file_type = BMP_FILE;
- }
- }
- if (file_type < 0) {
- error_report("'%s' not jpg/bmp file,head:0x%x.",
- filename, filehead_value);
- fclose(fp);
- fp = NULL;
- return fp;
+ goto error;
}
+
/* check BMP bpp */
if (file_type == BMP_FILE) {
- fseek(fp, 28, SEEK_SET);
- fop_ret = fread(buf, 1, 2, fp);
- bmp_bpp = (buf[0] + (buf[1] << 8)) & 0xffff;
+ bmp_bpp = (content[28] + (content[29] << 8)) & 0xffff;
if (bmp_bpp != 24) {
- error_report("only 24bpp bmp file is supported.");
- fclose(fp);
- fp = NULL;
- return fp;
+ goto error;
}
}
+
/* return values */
- *file_sizep = file_size;
*file_typep = file_type;
- return fp;
+
+ return content;
+
+error:
+ error_report("splash file '%s' format not recognized; must be JPEG "
+ "or 24 bit BMP", filename);
+ g_free(content);
+ return NULL;
}
static void fw_cfg_bootsplash(FWCfgState *s)
@@ -132,9 +116,7 @@ static void fw_cfg_bootsplash(FWCfgState *s)
int boot_splash_time = -1;
const char *boot_splash_filename = NULL;
char *p;
- char *filename;
- FILE *fp;
- int fop_ret;
+ char *filename, *file_data;
int file_size;
int file_type = -1;
const char *temp;
@@ -174,27 +156,19 @@ static void fw_cfg_bootsplash(FWCfgState *s)
error_report("failed to find file '%s'.", boot_splash_filename);
return;
}
- /* probing the file */
- fp = probe_splashfile(filename, &file_size, &file_type);
- if (fp == NULL) {
+
+ /* loading file data */
+ file_data = read_splashfile(filename, &file_size, &file_type);
+ if (file_data == NULL) {
g_free(filename);
return;
}
- /* loading file data */
if (boot_splash_filedata != NULL) {
g_free(boot_splash_filedata);
}
- boot_splash_filedata = g_malloc(file_size);
+ boot_splash_filedata = (uint8_t *)file_data;
boot_splash_filedata_size = file_size;
- fseek(fp, 0L, SEEK_SET);
- fop_ret = fread(boot_splash_filedata, 1, file_size, fp);
- if (fop_ret != file_size) {
- error_report("failed to read data from '%s'.",
- boot_splash_filename);
- fclose(fp);
- return;
- }
- fclose(fp);
+
/* insert data */
if (file_type == JPG_FILE) {
fw_cfg_add_file(s, "bootsplash.jpg",
diff --git a/hw/opencores_eth.c b/hw/opencores_eth.c
index 64b616ec1c..2c1e475395 100644
--- a/hw/opencores_eth.c
+++ b/hw/opencores_eth.c
@@ -382,6 +382,7 @@ static ssize_t open_eth_receive(VLANClientState *nc,
OpenEthState *s = DO_UPCAST(NICState, nc, nc)->opaque;
size_t maxfl = GET_REGFIELD(s, PACKETLEN, MAXFL);
size_t minfl = GET_REGFIELD(s, PACKETLEN, MINFL);
+ size_t fcsl = 4;
bool miss = true;
trace_open_eth_receive((unsigned)size);
@@ -418,6 +419,7 @@ static ssize_t open_eth_receive(VLANClientState *nc,
#else
{
#endif
+ static const uint8_t zero[64] = {0};
desc *desc = rx_desc(s);
size_t copy_size = GET_REGBIT(s, MODER, HUGEN) ? 65536 : maxfl;
@@ -426,11 +428,13 @@ static ssize_t open_eth_receive(VLANClientState *nc,
if (copy_size > size) {
copy_size = size;
+ } else {
+ fcsl = 0;
}
if (miss) {
desc->len_flags |= RXD_M;
}
- if (size > maxfl) {
+ if (GET_REGBIT(s, MODER, HUGEN) && size > maxfl) {
desc->len_flags |= RXD_TL;
}
#ifdef USE_RECSMALL
@@ -442,13 +446,28 @@ static ssize_t open_eth_receive(VLANClientState *nc,
cpu_physical_memory_write(desc->buf_ptr, buf, copy_size);
if (GET_REGBIT(s, MODER, PAD) && copy_size < minfl) {
- static const uint8_t zero[65536] = {0};
+ if (minfl - copy_size > fcsl) {
+ fcsl = 0;
+ } else {
+ fcsl -= minfl - copy_size;
+ }
+ while (copy_size < minfl) {
+ size_t zero_sz = minfl - copy_size < sizeof(zero) ?
+ minfl - copy_size : sizeof(zero);
- cpu_physical_memory_write(desc->buf_ptr + copy_size,
- zero, minfl - copy_size);
- copy_size = minfl;
+ cpu_physical_memory_write(desc->buf_ptr + copy_size,
+ zero, zero_sz);
+ copy_size += zero_sz;
+ }
}
+ /* There's no FCS in the frames handed to us by the QEMU, zero fill it.
+ * Don't do it if the frame is cut at the MAXFL or padded with 4 or
+ * more bytes to the MINFL.
+ */
+ cpu_physical_memory_write(desc->buf_ptr + copy_size, zero, fcsl);
+ copy_size += fcsl;
+
SET_FIELD(desc->len_flags, RXD_LEN, copy_size);
if ((desc->len_flags & RXD_WRAP) || s->rx_desc == 0x7f) {
diff --git a/hw/qxl-render.c b/hw/qxl-render.c
index c290739de0..2c51ba9806 100644
--- a/hw/qxl-render.c
+++ b/hw/qxl-render.c
@@ -28,16 +28,16 @@ static void qxl_flip(PCIQXLDevice *qxl, QXLRect *rect)
int len, i;
src += (qxl->guest_primary.surface.height - rect->top - 1) *
- qxl->guest_primary.stride;
- dst += rect->top * qxl->guest_primary.stride;
+ qxl->guest_primary.abs_stride;
+ dst += rect->top * qxl->guest_primary.abs_stride;
src += rect->left * qxl->guest_primary.bytes_pp;
dst += rect->left * qxl->guest_primary.bytes_pp;
len = (rect->right - rect->left) * qxl->guest_primary.bytes_pp;
for (i = rect->top; i < rect->bottom; i++) {
memcpy(dst, src, len);
- dst += qxl->guest_primary.stride;
- src -= qxl->guest_primary.stride;
+ dst += qxl->guest_primary.abs_stride;
+ src -= qxl->guest_primary.abs_stride;
}
}
@@ -45,7 +45,8 @@ void qxl_render_resize(PCIQXLDevice *qxl)
{
QXLSurfaceCreate *sc = &qxl->guest_primary.surface;
- qxl->guest_primary.stride = sc->stride;
+ qxl->guest_primary.qxl_stride = sc->stride;
+ qxl->guest_primary.abs_stride = abs(sc->stride);
qxl->guest_primary.resized++;
switch (sc->format) {
case SPICE_SURFACE_FMT_16_555:
@@ -75,7 +76,14 @@ void qxl_render_update(PCIQXLDevice *qxl)
VGACommonState *vga = &qxl->vga;
QXLRect dirty[32], update;
void *ptr;
- int i;
+ int i, redraw = 0;
+
+ if (!is_buffer_shared(vga->ds->surface)) {
+ dprint(qxl, 1, "%s: restoring shared displaysurface\n", __func__);
+ qxl->guest_primary.resized++;
+ qxl->guest_primary.commands++;
+ redraw = 1;
+ }
if (qxl->guest_primary.resized) {
qxl->guest_primary.resized = 0;
@@ -87,11 +95,11 @@ void qxl_render_update(PCIQXLDevice *qxl)
qemu_free_displaysurface(vga->ds);
qxl->guest_primary.data = memory_region_get_ram_ptr(&qxl->vga.vram);
- if (qxl->guest_primary.stride < 0) {
+ if (qxl->guest_primary.qxl_stride < 0) {
/* spice surface is upside down -> need extra buffer to flip */
- qxl->guest_primary.stride = -qxl->guest_primary.stride;
- qxl->guest_primary.flipped = g_malloc(qxl->guest_primary.surface.width *
- qxl->guest_primary.stride);
+ qxl->guest_primary.flipped =
+ g_malloc(qxl->guest_primary.surface.width *
+ qxl->guest_primary.abs_stride);
ptr = qxl->guest_primary.flipped;
} else {
ptr = qxl->guest_primary.data;
@@ -100,7 +108,7 @@ void qxl_render_update(PCIQXLDevice *qxl)
__FUNCTION__,
qxl->guest_primary.surface.width,
qxl->guest_primary.surface.height,
- qxl->guest_primary.stride,
+ qxl->guest_primary.qxl_stride,
qxl->guest_primary.bytes_pp,
qxl->guest_primary.bits_pp,
qxl->guest_primary.flipped ? "yes" : "no");
@@ -108,7 +116,7 @@ void qxl_render_update(PCIQXLDevice *qxl)
qemu_create_displaysurface_from(qxl->guest_primary.surface.width,
qxl->guest_primary.surface.height,
qxl->guest_primary.bits_pp,
- qxl->guest_primary.stride,
+ qxl->guest_primary.abs_stride,
ptr);
dpy_resize(vga->ds);
}
@@ -126,6 +134,10 @@ void qxl_render_update(PCIQXLDevice *qxl)
memset(dirty, 0, sizeof(dirty));
qxl_spice_update_area(qxl, 0, &update,
dirty, ARRAY_SIZE(dirty), 1, QXL_SYNC);
+ if (redraw) {
+ memset(dirty, 0, sizeof(dirty));
+ dirty[0] = update;
+ }
for (i = 0; i < ARRAY_SIZE(dirty); i++) {
if (qemu_spice_rect_is_empty(dirty+i)) {
diff --git a/hw/qxl.c b/hw/qxl.c
index 12f71aa56c..84ffd45c0c 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1663,12 +1663,25 @@ static int qxl_pre_load(void *opaque)
return 0;
}
+static void qxl_create_memslots(PCIQXLDevice *d)
+{
+ int i;
+
+ for (i = 0; i < NUM_MEMSLOTS; i++) {
+ if (!d->guest_slots[i].active) {
+ continue;
+ }
+ dprint(d, 1, "%s: restoring guest slot %d\n", __func__, i);
+ qxl_add_memslot(d, i, 0, QXL_SYNC);
+ }
+}
+
static int qxl_post_load(void *opaque, int version)
{
PCIQXLDevice* d = opaque;
uint8_t *ram_start = d->vga.vram_ptr;
QXLCommandExt *cmds;
- int in, out, i, newmode;
+ int in, out, newmode;
dprint(d, 1, "%s: start\n", __FUNCTION__);
@@ -1685,19 +1698,16 @@ static int qxl_post_load(void *opaque, int version)
qxl_mode_to_string(d->mode));
newmode = d->mode;
d->mode = QXL_MODE_UNDEFINED;
+
switch (newmode) {
case QXL_MODE_UNDEFINED:
break;
case QXL_MODE_VGA:
+ qxl_create_memslots(d);
qxl_enter_vga_mode(d);
break;
case QXL_MODE_NATIVE:
- for (i = 0; i < NUM_MEMSLOTS; i++) {
- if (!d->guest_slots[i].active) {
- continue;
- }
- qxl_add_memslot(d, i, 0, QXL_SYNC);
- }
+ qxl_create_memslots(d);
qxl_create_guest_primary(d, 1, QXL_SYNC);
/* replay surface-create and cursor-set commands */
@@ -1722,6 +1732,8 @@ static int qxl_post_load(void *opaque, int version)
break;
case QXL_MODE_COMPAT:
+ /* note: no need to call qxl_create_memslots, qxl_set_mode
+ * creates the mem slot. */
qxl_set_mode(d, d->shadow_rom.mode, 1);
break;
}
diff --git a/hw/qxl.h b/hw/qxl.h
index 37b2619e55..766aa6d68e 100644
--- a/hw/qxl.h
+++ b/hw/qxl.h
@@ -48,7 +48,8 @@ typedef struct PCIQXLDevice {
QXLSurfaceCreate surface;
uint32_t commands;
uint32_t resized;
- int32_t stride;
+ int32_t qxl_stride;
+ uint32_t abs_stride;
uint32_t bits_pp;
uint32_t bytes_pp;
uint8_t *data, *flipped;
diff --git a/hw/sysbus.c b/hw/sysbus.c
index 4fab5a41b2..fd2fc6a51d 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -198,6 +198,7 @@ DeviceState *sysbus_create_varargs(const char *name,
sysbus_connect_irq(s, n, irq);
n++;
}
+ va_end(va);
return dev;
}
@@ -229,6 +230,7 @@ DeviceState *sysbus_try_create_varargs(const char *name,
sysbus_connect_irq(s, n, irq);
n++;
}
+ va_end(va);
return dev;
}
diff --git a/ia64-dis.c b/ia64-dis.c
index 2886df3614..2a103e6b5c 100644
--- a/ia64-dis.c
+++ b/ia64-dis.c
@@ -781,6 +781,9 @@ ext_inc3 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
return 0;
}
+/* glib.h defines ABS so we must undefine it to avoid a clash */
+#undef ABS
+
#define CST IA64_OPND_CLASS_CST
#define REG IA64_OPND_CLASS_REG
#define IND IA64_OPND_CLASS_IND
diff --git a/migration-fd.c b/migration-fd.c
index d0aec89e8d..6211124a05 100644
--- a/migration-fd.c
+++ b/migration-fd.c
@@ -42,10 +42,31 @@ static int fd_write(MigrationState *s, const void * buf, size_t size)
static int fd_close(MigrationState *s)
{
+ struct stat st;
+ int ret;
+
DPRINTF("fd_close\n");
if (s->fd != -1) {
- close(s->fd);
+ ret = fstat(s->fd, &st);
+ if (ret == 0 && S_ISREG(st.st_mode)) {
+ /*
+ * If the file handle is a regular file make sure the
+ * data is flushed to disk before signaling success.
+ */
+ ret = fsync(s->fd);
+ if (ret != 0) {
+ ret = -errno;
+ perror("migration-fd: fsync");
+ return ret;
+ }
+ }
+ ret = close(s->fd);
s->fd = -1;
+ if (ret != 0) {
+ ret = -errno;
+ perror("migration-fd: close");
+ return ret;
+ }
}
return 0;
}
diff --git a/migration.c b/migration.c
index 3b4abbde64..4b17566857 100644
--- a/migration.c
+++ b/migration.c
@@ -216,7 +216,7 @@ static void migrate_fd_put_notify(void *opaque)
qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
qemu_file_put_notify(s->file);
- if (qemu_file_get_error(s->file)) {
+ if (s->file && qemu_file_get_error(s->file)) {
migrate_fd_error(s);
}
}
diff --git a/net/tap-linux.c b/net/tap-linux.c
index ff8cad0ea0..41d581b734 100644
--- a/net/tap-linux.c
+++ b/net/tap-linux.c
@@ -73,7 +73,11 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required
pstrcpy(ifr.ifr_name, IFNAMSIZ, "tap%d");
ret = ioctl(fd, TUNSETIFF, (void *) &ifr);
if (ret != 0) {
- error_report("could not configure %s (%s): %m", PATH_NET_TUN, ifr.ifr_name);
+ if (ifname[0] != '\0') {
+ error_report("could not configure %s (%s): %m", PATH_NET_TUN, ifr.ifr_name);
+ } else {
+ error_report("could not configure %s: %m", PATH_NET_TUN);
+ }
close(fd);
return -1;
}
diff --git a/oslib-posix.c b/oslib-posix.c
index dbc8ee8960..6f297626c7 100644
--- a/oslib-posix.c
+++ b/oslib-posix.c
@@ -36,8 +36,11 @@ extern int daemon(int, int);
#endif
#if defined(__linux__) && defined(__x86_64__)
- /* Use 2MB alignment so transparent hugepages can be used by KVM */
+ /* Use 2 MiB alignment so transparent hugepages can be used by KVM.
+ Valgrind does not support alignments larger than 1 MiB,
+ therefore we need special code which handles running on Valgrind. */
# define QEMU_VMALLOC_ALIGN (512 * 4096)
+# define CONFIG_VALGRIND
#else
# define QEMU_VMALLOC_ALIGN getpagesize()
#endif
@@ -47,7 +50,11 @@ extern int daemon(int, int);
#include "trace.h"
#include "qemu_socket.h"
-
+#if defined(CONFIG_VALGRIND)
+static int running_on_valgrind = -1;
+#else
+# define running_on_valgrind 0
+#endif
int qemu_daemon(int nochdir, int noclose)
{
@@ -89,7 +96,16 @@ void *qemu_vmalloc(size_t size)
void *ptr;
size_t align = QEMU_VMALLOC_ALIGN;
- if (size < align) {
+#if defined(CONFIG_VALGRIND)
+ if (running_on_valgrind < 0) {
+ /* First call, test whether we are running on Valgrind.
+ This is a substitute for RUNNING_ON_VALGRIND from valgrind.h. */
+ const char *ld = getenv("LD_PRELOAD");
+ running_on_valgrind = (ld != NULL && strstr(ld, "vgpreload"));
+ }
+#endif
+
+ if (size < align || running_on_valgrind) {
align = getpagesize();
}
ptr = qemu_memalign(align, size);
diff --git a/qemu-barrier.h b/qemu-barrier.h
index 735eea6cf9..c11bb2b59f 100644
--- a/qemu-barrier.h
+++ b/qemu-barrier.h
@@ -14,7 +14,7 @@
*/
#define smp_wmb() barrier()
-#elif defined(__powerpc__)
+#elif defined(_ARCH_PPC)
/*
* We use an eieio() for a wmb() on powerpc. This assumes we don't
diff --git a/qemu-tls.h b/qemu-tls.h
new file mode 100644
index 0000000000..5b70f10f8f
--- /dev/null
+++ b/qemu-tls.h
@@ -0,0 +1,52 @@
+/*
+ * Abstraction layer for defining and using TLS variables
+ *
+ * Copyright (c) 2011 Red Hat, Inc
+ * Copyright (c) 2011 Linaro Limited
+ *
+ * Authors:
+ * Paolo Bonzini <pbonzini@redhat.com>
+ * Peter Maydell <peter.maydell@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef QEMU_TLS_H
+#define QEMU_TLS_H
+
+/* Per-thread variables. Note that we only have implementations
+ * which are really thread-local on Linux; the dummy implementations
+ * define plain global variables.
+ *
+ * This means that for the moment use should be restricted to
+ * per-VCPU variables, which are OK because:
+ * - the only -user mode supporting multiple VCPU threads is linux-user
+ * - TCG system mode is single-threaded regarding VCPUs
+ * - KVM system mode is multi-threaded but limited to Linux
+ *
+ * TODO: proper implementations via Win32 .tls sections and
+ * POSIX pthread_getspecific.
+ */
+#ifdef __linux__
+#define DECLARE_TLS(type, x) extern DEFINE_TLS(type, x)
+#define DEFINE_TLS(type, x) __thread __typeof__(type) tls__##x
+#define get_tls(x) tls__##x
+#else
+/* Dummy implementations which define plain global variables */
+#define DECLARE_TLS(type, x) extern DEFINE_TLS(type, x)
+#define DEFINE_TLS(type, x) __typeof__(type) tls__##x
+#define get_tls(x) tls__##x
+#endif
+
+#endif