diff options
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | MAINTAINERS | 6 | ||||
-rw-r--r-- | Makefile | 10 | ||||
-rwxr-xr-x | configure | 7 | ||||
-rw-r--r-- | cpu-all.h | 4 | ||||
-rw-r--r-- | cpus.c | 14 | ||||
-rw-r--r-- | cpus.h | 1 | ||||
-rw-r--r-- | darwin-user/main.c | 2 | ||||
-rw-r--r-- | exec.c | 13 | ||||
-rw-r--r-- | hw/fw_cfg.c | 102 | ||||
-rw-r--r-- | hw/opencores_eth.c | 29 | ||||
-rw-r--r-- | ia64-dis.c | 3 | ||||
-rw-r--r-- | migration-fd.c | 23 | ||||
-rw-r--r-- | migration.c | 2 | ||||
-rw-r--r-- | oslib-posix.c | 22 | ||||
-rw-r--r-- | qemu-barrier.h | 2 | ||||
-rw-r--r-- | qemu-tls.h | 52 |
17 files changed, 197 insertions, 99 deletions
@@ -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 4535eeb..bccdd4f 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 @@ -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 @@ -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 @@ -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. @@ -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) @@ -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 1a881a0..c0f14f8 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; @@ -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 8df265c..dbcb888 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 64b616e..2c1e475 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) { @@ -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 d0aec89..6211124 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 3b4abbd..4b17566 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/oslib-posix.c b/oslib-posix.c index dbc8ee8..6f29762 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 735eea6..c11bb2b 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 0000000..5b70f10 --- /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 |