summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--Makefile.objs3
-rw-r--r--block/raw-posix.c12
-rwxr-xr-xconfigure5
-rw-r--r--cpu-all.h2
-rw-r--r--cris-dis.c4
-rw-r--r--disas.h3
-rw-r--r--dyngen-exec.h23
-rw-r--r--hw/mips_fulong2e.c2
-rw-r--r--hw/omap_clk.c1
-rw-r--r--pc-bios/bios.binbin131072 -> 131072 bytes
-rw-r--r--qemu-common.h9
-rw-r--r--qemu-timer-common.c62
-rw-r--r--qemu-timer.c73
-rw-r--r--qemu-timer.h74
-rw-r--r--qemu-tool.c7
m---------roms/seabios0
-rw-r--r--rules.mak9
-rw-r--r--simpletrace.c10
-rw-r--r--target-i386/kvm.c132
-rw-r--r--tests/Makefile123
-rw-r--r--tests/runcom.c11
-rw-r--r--tests/test-i386.c5
-rw-r--r--tests/test_path.c13
-rw-r--r--ui/spice-display.c3
-rw-r--r--vl.c24
26 files changed, 368 insertions, 248 deletions
diff --git a/Makefile b/Makefile
index 252c817d27..a1434b1bd9 100644
--- a/Makefile
+++ b/Makefile
@@ -129,11 +129,11 @@ version-obj-$(CONFIG_WIN32) += version.o
qemu-img.o: qemu-img-cmds.h
qemu-img.o qemu-tool.o qemu-nbd.o qemu-io.o: $(GENERATED_HEADERS)
-qemu-img$(EXESUF): qemu-img.o qemu-tool.o qemu-error.o $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y)
+qemu-img$(EXESUF): qemu-img.o qemu-tool.o qemu-error.o $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) qemu-timer-common.o
-qemu-nbd$(EXESUF): qemu-nbd.o qemu-tool.o qemu-error.o $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y)
+qemu-nbd$(EXESUF): qemu-nbd.o qemu-tool.o qemu-error.o $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) qemu-timer-common.o
-qemu-io$(EXESUF): qemu-io.o cmd.o qemu-tool.o qemu-error.o $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y)
+qemu-io$(EXESUF): qemu-io.o cmd.o qemu-tool.o qemu-error.o $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) qemu-timer-common.o
qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx
$(call quiet-command,sh $(SRC_PATH)/hxtool -h < $< > $@," GEN $@")
diff --git a/Makefile.objs b/Makefile.objs
index 6e6f60a3af..f07fb01bc3 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -127,7 +127,7 @@ common-obj-y += iov.o acl.o
common-obj-$(CONFIG_THREAD) += qemu-thread.o
common-obj-$(CONFIG_IOTHREAD) += compatfd.o
common-obj-y += notify.o event_notifier.o
-common-obj-y += qemu-timer.o
+common-obj-y += qemu-timer.o qemu-timer-common.o
slirp-obj-y = cksum.o if.o ip_icmp.o ip_input.o ip_output.o
slirp-obj-y += slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o tcp_output.o
@@ -278,6 +278,7 @@ libdis-$(CONFIG_SPARC_DIS) += sparc-dis.o
trace-obj-y = trace.o
ifeq ($(TRACE_BACKEND),simple)
trace-obj-y += simpletrace.o
+user-obj-y += qemu-timer-common.o
endif
vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
diff --git a/block/raw-posix.c b/block/raw-posix.c
index a5cbb7e929..d0393e0c44 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -97,9 +97,9 @@
#define FTYPE_CD 1
#define FTYPE_FD 2
-/* if the FD is not accessed during that time (in ms), we try to
+/* if the FD is not accessed during that time (in ns), we try to
reopen it to see if the disk has been changed */
-#define FD_OPEN_TIMEOUT 1000
+#define FD_OPEN_TIMEOUT (1000000000)
#define MAX_BLOCKSIZE 4096
@@ -908,7 +908,7 @@ static int fd_open(BlockDriverState *bs)
return 0;
last_media_present = (s->fd >= 0);
if (s->fd >= 0 &&
- (qemu_get_clock(rt_clock) - s->fd_open_time) >= FD_OPEN_TIMEOUT) {
+ (get_clock() - s->fd_open_time) >= FD_OPEN_TIMEOUT) {
close(s->fd);
s->fd = -1;
#ifdef DEBUG_FLOPPY
@@ -917,7 +917,7 @@ static int fd_open(BlockDriverState *bs)
}
if (s->fd < 0) {
if (s->fd_got_error &&
- (qemu_get_clock(rt_clock) - s->fd_error_time) < FD_OPEN_TIMEOUT) {
+ (get_clock() - s->fd_error_time) < FD_OPEN_TIMEOUT) {
#ifdef DEBUG_FLOPPY
printf("No floppy (open delayed)\n");
#endif
@@ -925,7 +925,7 @@ static int fd_open(BlockDriverState *bs)
}
s->fd = open(bs->filename, s->open_flags & ~O_NONBLOCK);
if (s->fd < 0) {
- s->fd_error_time = qemu_get_clock(rt_clock);
+ s->fd_error_time = get_clock();
s->fd_got_error = 1;
if (last_media_present)
s->fd_media_changed = 1;
@@ -940,7 +940,7 @@ static int fd_open(BlockDriverState *bs)
}
if (!last_media_present)
s->fd_media_changed = 1;
- s->fd_open_time = qemu_get_clock(rt_clock);
+ s->fd_open_time = get_clock();
s->fd_got_error = 0;
return 0;
}
diff --git a/configure b/configure
index 9ed05def8a..f62c1feb88 100755
--- a/configure
+++ b/configure
@@ -92,6 +92,7 @@ libs_softmmu=""
libs_tools=""
audio_pt_int=""
audio_win_int=""
+cc_i386=i386-pc-linux-gnu-gcc
# parse CC options first
for opt do
@@ -789,12 +790,14 @@ case "$cpu" in
i386)
QEMU_CFLAGS="-m32 $QEMU_CFLAGS"
LDFLAGS="-m32 $LDFLAGS"
+ cc_i386='$(CC) -m32'
helper_cflags="-fomit-frame-pointer"
host_guest_base="yes"
;;
x86_64)
QEMU_CFLAGS="-m64 $QEMU_CFLAGS"
LDFLAGS="-m64 $LDFLAGS"
+ cc_i386='$(CC) -m32'
host_guest_base="yes"
;;
arm*)
@@ -2348,6 +2351,7 @@ printf "# Configured with:" >> $config_host_mak
printf " '%s'" "$0" "$@" >> $config_host_mak
echo >> $config_host_mak
+echo all: >> $config_host_mak
echo "prefix=$prefix" >> $config_host_mak
echo "bindir=$bindir" >> $config_host_mak
echo "mandir=$mandir" >> $config_host_mak
@@ -2639,6 +2643,7 @@ 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 "CC=$cc" >> $config_host_mak
+echo "CC_I386=$cc_i386" >> $config_host_mak
echo "HOST_CC=$host_cc" >> $config_host_mak
if test "$sparse" = "yes" ; then
echo "CC := REAL_CC=\"\$(CC)\" cgcc" >> $config_host_mak
diff --git a/cpu-all.h b/cpu-all.h
index 67a32664d5..11edddc76c 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -773,7 +773,7 @@ void cpu_dump_statistics (CPUState *env, FILE *f,
int flags);
void QEMU_NORETURN cpu_abort(CPUState *env, const char *fmt, ...)
- __attribute__ ((__format__ (__printf__, 2, 3)));
+ GCC_FMT_ATTR(2, 3);
extern CPUState *first_cpu;
extern CPUState *cpu_single_env;
diff --git a/cris-dis.c b/cris-dis.c
index 455ba8af3f..afd775c29b 100644
--- a/cris-dis.c
+++ b/cris-dis.c
@@ -18,13 +18,11 @@
You should have received a copy of the GNU General Public License
along with this program; if not, see <http://www.gnu.org/licenses/>. */
+#include "qemu-common.h"
#include "dis-asm.h"
//#include "sysdep.h"
#include "target-cris/opcode-cris.h"
//#include "libiberty.h"
-
-
-void *qemu_malloc(size_t len); /* can't include qemu-common.h here */
#define CONST_STRNEQ(STR1,STR2) (strncmp ((STR1), (STR2), sizeof (STR2) - 1) == 0)
diff --git a/disas.h b/disas.h
index 6a9332d6cc..f9287f73e1 100644
--- a/disas.h
+++ b/disas.h
@@ -8,11 +8,8 @@
void disas(FILE *out, void *code, unsigned long size);
void target_disas(FILE *out, target_ulong code, target_ulong size, int flags);
-/* The usual mess... FIXME: Remove this condition once dyngen-exec.h is gone */
-#ifndef __DYNGEN_EXEC_H__
void monitor_disas(Monitor *mon, CPUState *env,
target_ulong pc, int nb_insn, int is_physical, int flags);
-#endif
/* Look up symbol for debugging purpose. Returns "" if unknown. */
const char *lookup_symbol(target_ulong orig_addr);
diff --git a/dyngen-exec.h b/dyngen-exec.h
index 5bfef3f6fe..db00fbae04 100644
--- a/dyngen-exec.h
+++ b/dyngen-exec.h
@@ -19,19 +19,7 @@
#if !defined(__DYNGEN_EXEC_H__)
#define __DYNGEN_EXEC_H__
-/* prevent Solaris from trying to typedef FILE in gcc's
- include/floatingpoint.h which will conflict with the
- definition down below */
-#ifdef __sun__
-#define _FILEDEFED
-#endif
-
-/* NOTE: standard headers should be used with special care at this
- point because host CPU registers are used as global variables. Some
- host headers do not allow that. */
-#include <stddef.h>
-#include <stdint.h>
-#include <stdbool.h>
+#include "qemu-common.h"
#ifdef __OpenBSD__
#include <sys/types.h>
@@ -40,15 +28,6 @@
/* XXX: This may be wrong for 64-bit ILP32 hosts. */
typedef void * host_reg_t;
-#ifdef CONFIG_BSD
-typedef struct __sFILE FILE;
-#else
-typedef struct FILE FILE;
-#endif
-extern int fprintf(FILE *, const char *, ...);
-extern int fputs(const char *, FILE *);
-extern int printf(const char *, ...);
-
#if defined(__i386__)
#define AREG0 "ebp"
#elif defined(__x86_64__)
diff --git a/hw/mips_fulong2e.c b/hw/mips_fulong2e.c
index f9723f559e..07eb9eeba1 100644
--- a/hw/mips_fulong2e.c
+++ b/hw/mips_fulong2e.c
@@ -295,7 +295,7 @@ static void mips_fulong2e_init(ram_addr_t ram_size, const char *boot_device,
ram_offset = qemu_ram_alloc(NULL, "fulong2e.ram", ram_size);
bios_offset = qemu_ram_alloc(NULL, "fulong2e.bios", bios_size);
- cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
+ cpu_register_physical_memory(0, ram_size, ram_offset);
cpu_register_physical_memory(0x1fc00000LL,
bios_size, bios_offset | IO_MEM_ROM);
diff --git a/hw/omap_clk.c b/hw/omap_clk.c
index 6bcabef8ac..10c9c4308c 100644
--- a/hw/omap_clk.c
+++ b/hw/omap_clk.c
@@ -20,6 +20,7 @@
*/
#include "hw.h"
#include "omap.h"
+#include "qemu-timer.h" /* for muldiv64() */
struct clk {
const char *name;
diff --git a/pc-bios/bios.bin b/pc-bios/bios.bin
index d0d4b6aa43..f79c342264 100644
--- a/pc-bios/bios.bin
+++ b/pc-bios/bios.bin
Binary files differ
diff --git a/qemu-common.h b/qemu-common.h
index 81aafa0a49..2fbc27f9f0 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -18,11 +18,6 @@ typedef struct QEMUFile QEMUFile;
typedef struct QEMUBH QEMUBH;
typedef struct DeviceState DeviceState;
-/* Hack around the mess dyngen-exec.h causes: We need QEMU_NORETURN in files that
- cannot include the following headers without conflicts. This condition has
- to be removed once dyngen is gone. */
-#ifndef __DYNGEN_EXEC_H__
-
/* we put basic includes here to avoid repeating them in device drivers */
#include <stdlib.h>
#include <stdio.h>
@@ -138,8 +133,6 @@ void qemu_bh_delete(QEMUBH *bh);
int qemu_bh_poll(void);
void qemu_bh_update_timeout(int *timeout);
-uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c);
-
void qemu_get_timedate(struct tm *tm, int offset);
int qemu_timedate_diff(struct tm *tm);
@@ -318,6 +311,4 @@ static inline uint8_t from_bcd(uint8_t val)
#include "module.h"
-#endif /* dyngen-exec.h hack */
-
#endif
diff --git a/qemu-timer-common.c b/qemu-timer-common.c
new file mode 100644
index 0000000000..fff43996d8
--- /dev/null
+++ b/qemu-timer-common.c
@@ -0,0 +1,62 @@
+/*
+ * QEMU System Emulator
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "qemu-timer.h"
+
+/***********************************************************/
+/* real time host monotonic timer */
+
+#ifdef _WIN32
+
+int64_t clock_freq;
+
+static void __attribute__((constructor)) init_get_clock(void)
+{
+ LARGE_INTEGER freq;
+ int ret;
+ ret = QueryPerformanceFrequency(&freq);
+ if (ret == 0) {
+ fprintf(stderr, "Could not calibrate ticks\n");
+ exit(1);
+ }
+ clock_freq = freq.QuadPart;
+}
+
+#else
+
+int use_rt_clock;
+
+static void __attribute__((constructor)) init_get_clock(void)
+{
+ use_rt_clock = 0;
+#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000) \
+ || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
+ {
+ struct timespec ts;
+ if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
+ use_rt_clock = 1;
+ }
+ }
+#endif
+}
+#endif
diff --git a/qemu-timer.c b/qemu-timer.c
index bc5f207bb6..95814af798 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -64,78 +64,6 @@ int64_t qemu_icount_bias;
static QEMUTimer *icount_rt_timer;
static QEMUTimer *icount_vm_timer;
-
-/***********************************************************/
-/* real time host monotonic timer */
-
-
-static int64_t get_clock_realtime(void)
-{
- struct timeval tv;
-
- gettimeofday(&tv, NULL);
- return tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000);
-}
-
-#ifdef WIN32
-
-static int64_t clock_freq;
-
-static void init_get_clock(void)
-{
- LARGE_INTEGER freq;
- int ret;
- ret = QueryPerformanceFrequency(&freq);
- if (ret == 0) {
- fprintf(stderr, "Could not calibrate ticks\n");
- exit(1);
- }
- clock_freq = freq.QuadPart;
-}
-
-static int64_t get_clock(void)
-{
- LARGE_INTEGER ti;
- QueryPerformanceCounter(&ti);
- return muldiv64(ti.QuadPart, get_ticks_per_sec(), clock_freq);
-}
-
-#else
-
-static int use_rt_clock;
-
-static void init_get_clock(void)
-{
- use_rt_clock = 0;
-#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000) \
- || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
- {
- struct timespec ts;
- if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
- use_rt_clock = 1;
- }
- }
-#endif
-}
-
-static int64_t get_clock(void)
-{
-#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000) \
- || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
- if (use_rt_clock) {
- struct timespec ts;
- clock_gettime(CLOCK_MONOTONIC, &ts);
- return ts.tv_sec * 1000000000LL + ts.tv_nsec;
- } else
-#endif
- {
- /* XXX: using gettimeofday leads to problems if the date
- changes, so it should be avoided. */
- return get_clock_realtime();
- }
-}
-#endif
-
/***********************************************************/
/* guest cycle counter */
@@ -614,7 +542,6 @@ int64_t qemu_get_clock_ns(QEMUClock *clock)
void init_clocks(void)
{
- init_get_clock();
rt_clock = qemu_new_clock(QEMU_CLOCK_REALTIME);
vm_clock = qemu_new_clock(QEMU_CLOCK_VIRTUAL);
host_clock = qemu_new_clock(QEMU_CLOCK_HOST);
diff --git a/qemu-timer.h b/qemu-timer.h
index 1494f79406..299e387768 100644
--- a/qemu-timer.h
+++ b/qemu-timer.h
@@ -2,6 +2,13 @@
#define QEMU_TIMER_H
#include "qemu-common.h"
+#include <time.h>
+#include <sys/time.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#include <mmsystem.h>
+#endif
/* timers */
@@ -52,6 +59,73 @@ static inline int64_t get_ticks_per_sec(void)
return 1000000000LL;
}
+/* compute with 96 bit intermediate result: (a*b)/c */
+static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
+{
+ union {
+ uint64_t ll;
+ struct {
+#ifdef HOST_WORDS_BIGENDIAN
+ uint32_t high, low;
+#else
+ uint32_t low, high;
+#endif
+ } l;
+ } u, res;
+ uint64_t rl, rh;
+
+ u.ll = a;
+ rl = (uint64_t)u.l.low * (uint64_t)b;
+ rh = (uint64_t)u.l.high * (uint64_t)b;
+ rh += (rl >> 32);
+ res.l.high = rh / c;
+ res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
+ return res.ll;
+}
+
+/* real time host monotonic timer */
+static inline int64_t get_clock_realtime(void)
+{
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+ return tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000);
+}
+
+/* Warning: don't insert tracepoints into these functions, they are
+ also used by simpletrace backend and tracepoints would cause
+ an infinite recursion! */
+#ifdef _WIN32
+extern int64_t clock_freq;
+
+static inline int64_t get_clock(void)
+{
+ LARGE_INTEGER ti;
+ QueryPerformanceCounter(&ti);
+ return muldiv64(ti.QuadPart, get_ticks_per_sec(), clock_freq);
+}
+
+#else
+
+extern int use_rt_clock;
+
+static inline int64_t get_clock(void)
+{
+#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000) \
+ || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
+ if (use_rt_clock) {
+ struct timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ return ts.tv_sec * 1000000000LL + ts.tv_nsec;
+ } else
+#endif
+ {
+ /* XXX: using gettimeofday leads to problems if the date
+ changes, so it should be avoided. */
+ return get_clock_realtime();
+ }
+}
+#endif
void qemu_get_timer(QEMUFile *f, QEMUTimer *ts);
void qemu_put_timer(QEMUFile *f, QEMUTimer *ts);
diff --git a/qemu-tool.c b/qemu-tool.c
index b39af86e01..9ccca655ef 100644
--- a/qemu-tool.c
+++ b/qemu-tool.c
@@ -110,10 +110,3 @@ int qemu_set_fd_handler2(int fd,
{
return 0;
}
-
-int64_t qemu_get_clock(QEMUClock *clock)
-{
- qemu_timeval tv;
- qemu_gettimeofday(&tv);
- return (tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000)) / 1000000;
-}
diff --git a/roms/seabios b/roms/seabios
-Subproject 17d3e46511aeedc9f09a8216d194d749187b80a
+Subproject 0ff9051f756ba739bc2edca77925191c3c6cbc2
diff --git a/rules.mak b/rules.mak
index c843a131e8..6dac7773d5 100644
--- a/rules.mak
+++ b/rules.mak
@@ -42,6 +42,15 @@ cc-option = $(if $(shell $(CC) $1 $2 -S -o /dev/null -xc /dev/null \
VPATH_SUFFIXES = %.c %.h %.S %.m %.mak %.texi
set-vpath = $(if $1,$(foreach PATTERN,$(VPATH_SUFFIXES),$(eval vpath $(PATTERN) $1)))
+# find-in-path
+# Usage: $(call find-in-path, prog)
+# Looks in the PATH if the argument contains no slash, else only considers one
+# specific directory. Returns an # empty string if the program doesn't exist
+# there.
+find-in-path = $(if $(find-string /, $1), \
+ $(wildcard $1), \
+ $(wildcard $(patsubst %, %/$1, $(subst :, ,$(PATH)))))
+
# Generate timestamp files for .h include files
%.h: %.h-timestamp
diff --git a/simpletrace.c b/simpletrace.c
index b488d51766..9ea0d1f984 100644
--- a/simpletrace.c
+++ b/simpletrace.c
@@ -12,6 +12,7 @@
#include <stdint.h>
#include <stdio.h>
#include <time.h>
+#include "qemu-timer.h"
#include "trace.h"
/** Trace file header event ID */
@@ -140,20 +141,13 @@ static void trace(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3,
uint64_t x4, uint64_t x5, uint64_t x6)
{
TraceRecord *rec = &trace_buf[trace_idx];
- struct timespec ts;
-
- /* TODO Windows? It would be good to use qemu-timer here but that isn't
- * linked into qemu-tools. Also we should avoid recursion in the tracing
- * code, therefore it is useful to be self-contained.
- */
- clock_gettime(CLOCK_MONOTONIC, &ts);
if (!trace_list[event].state) {
return;
}
rec->event = event;
- rec->timestamp_ns = ts.tv_sec * 1000000000LL + ts.tv_nsec;
+ rec->timestamp_ns = get_clock();
rec->x1 = x1;
rec->x2 = x2;
rec->x3 = x3;
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 512d533970..ae0a034ab0 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -15,6 +15,7 @@
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
+#include <sys/utsname.h>
#include <linux/kvm.h>
@@ -53,6 +54,8 @@
#define BUS_MCEERR_AO 5
#endif
+static int lm_capable_kernel;
+
#ifdef KVM_CAP_EXT_CPUID
static struct kvm_cpuid2 *try_get_cpuid(KVMState *s, int max)
@@ -239,12 +242,16 @@ static void kvm_do_inject_x86_mce(void *_data)
struct kvm_x86_mce_data *data = _data;
int r;
- /* If there is an MCE excpetion being processed, ignore this SRAO MCE */
- r = kvm_mce_in_exception(data->env);
- if (r == -1)
- fprintf(stderr, "Failed to get MCE status\n");
- else if (r && !(data->mce->status & MCI_STATUS_AR))
- return;
+ /* If there is an MCE exception being processed, ignore this SRAO MCE */
+ if ((data->env->mcg_cap & MCG_SER_P) &&
+ !(data->mce->status & MCI_STATUS_AR)) {
+ r = kvm_mce_in_exception(data->env);
+ if (r == -1) {
+ fprintf(stderr, "Failed to get MCE status\n");
+ } else if (r) {
+ return;
+ }
+ }
r = kvm_set_mce(data->env, data->mce);
if (r < 0) {
@@ -434,23 +441,26 @@ void kvm_arch_reset_vcpu(CPUState *env)
}
}
-static int kvm_has_msr_star(CPUState *env)
+int has_msr_star;
+int has_msr_hsave_pa;
+
+static void kvm_supported_msrs(CPUState *env)
{
- static int has_msr_star;
+ static int kvm_supported_msrs;
int ret;
/* first time */
- if (has_msr_star == 0) {
+ if (kvm_supported_msrs == 0) {
struct kvm_msr_list msr_list, *kvm_msr_list;
- has_msr_star = -1;
+ kvm_supported_msrs = -1;
/* Obtain MSR list from KVM. These are the MSRs that we must
* save/restore */
msr_list.nmsrs = 0;
ret = kvm_ioctl(env->kvm_state, KVM_GET_MSR_INDEX_LIST, &msr_list);
if (ret < 0 && ret != -E2BIG) {
- return 0;
+ return;
}
/* Old kernel modules had a bug and could write beyond the provided
memory. Allocate at least a safe amount of 1K. */
@@ -466,7 +476,11 @@ static int kvm_has_msr_star(CPUState *env)
for (i = 0; i < kvm_msr_list->nmsrs; i++) {
if (kvm_msr_list->indices[i] == MSR_STAR) {
has_msr_star = 1;
- break;
+ continue;
+ }
+ if (kvm_msr_list->indices[i] == MSR_VM_HSAVE_PA) {
+ has_msr_hsave_pa = 1;
+ continue;
}
}
}
@@ -474,9 +488,19 @@ static int kvm_has_msr_star(CPUState *env)
free(kvm_msr_list);
}
- if (has_msr_star == 1)
- return 1;
- return 0;
+ return;
+}
+
+static int kvm_has_msr_hsave_pa(CPUState *env)
+{
+ kvm_supported_msrs(env);
+ return has_msr_hsave_pa;
+}
+
+static int kvm_has_msr_star(CPUState *env)
+{
+ kvm_supported_msrs(env);
+ return has_msr_star;
}
static int kvm_init_identity_map_page(KVMState *s)
@@ -502,6 +526,11 @@ int kvm_arch_init(KVMState *s, int smp_cpus)
{
int ret;
+ struct utsname utsname;
+
+ uname(&utsname);
+ lm_capable_kernel = strcmp(utsname.machine, "x86_64") == 0;
+
/* create vm86 tss. KVM uses vm86 mode to emulate 16-bit code
* directly. In order to use vm86 mode, a TSS is needed. Since this
* must be part of guest physical memory, we need to allocate it. Older
@@ -779,28 +808,40 @@ static int kvm_put_msrs(CPUState *env, int level)
struct kvm_msr_entry entries[100];
} msr_data;
struct kvm_msr_entry *msrs = msr_data.entries;
- int i, n = 0;
+ int n = 0;
kvm_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_CS, env->sysenter_cs);
kvm_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_ESP, env->sysenter_esp);
kvm_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_EIP, env->sysenter_eip);
if (kvm_has_msr_star(env))
kvm_msr_entry_set(&msrs[n++], MSR_STAR, env->star);
+ if (kvm_has_msr_hsave_pa(env))
+ kvm_msr_entry_set(&msrs[n++], MSR_VM_HSAVE_PA, env->vm_hsave);
#ifdef TARGET_X86_64
- /* FIXME if lm capable */
- kvm_msr_entry_set(&msrs[n++], MSR_CSTAR, env->cstar);
- kvm_msr_entry_set(&msrs[n++], MSR_KERNELGSBASE, env->kernelgsbase);
- kvm_msr_entry_set(&msrs[n++], MSR_FMASK, env->fmask);
- kvm_msr_entry_set(&msrs[n++], MSR_LSTAR, env->lstar);
+ if (lm_capable_kernel) {
+ kvm_msr_entry_set(&msrs[n++], MSR_CSTAR, env->cstar);
+ kvm_msr_entry_set(&msrs[n++], MSR_KERNELGSBASE, env->kernelgsbase);
+ kvm_msr_entry_set(&msrs[n++], MSR_FMASK, env->fmask);
+ kvm_msr_entry_set(&msrs[n++], MSR_LSTAR, env->lstar);
+ }
#endif
if (level == KVM_PUT_FULL_STATE) {
- kvm_msr_entry_set(&msrs[n++], MSR_IA32_TSC, env->tsc);
+ /*
+ * KVM is yet unable to synchronize TSC values of multiple VCPUs on
+ * writeback. Until this is fixed, we only write the offset to SMP
+ * guests after migration, desynchronizing the VCPUs, but avoiding
+ * huge jump-backs that would occur without any writeback at all.
+ */
+ if (smp_cpus == 1 || env->tsc != 0) {
+ kvm_msr_entry_set(&msrs[n++], MSR_IA32_TSC, env->tsc);
+ }
kvm_msr_entry_set(&msrs[n++], MSR_KVM_SYSTEM_TIME,
env->system_time_msr);
kvm_msr_entry_set(&msrs[n++], MSR_KVM_WALL_CLOCK, env->wall_clock_msr);
}
#ifdef KVM_CAP_MCE
if (env->mcg_cap) {
+ int i;
if (level == KVM_PUT_RESET_STATE)
kvm_msr_entry_set(&msrs[n++], MSR_MCG_STATUS, env->mcg_status);
else if (level == KVM_PUT_FULL_STATE) {
@@ -1010,13 +1051,16 @@ static int kvm_get_msrs(CPUState *env)
msrs[n++].index = MSR_IA32_SYSENTER_EIP;
if (kvm_has_msr_star(env))
msrs[n++].index = MSR_STAR;
+ if (kvm_has_msr_hsave_pa(env))
+ msrs[n++].index = MSR_VM_HSAVE_PA;
msrs[n++].index = MSR_IA32_TSC;
#ifdef TARGET_X86_64
- /* FIXME lm_capable_kernel */
- msrs[n++].index = MSR_CSTAR;
- msrs[n++].index = MSR_KERNELGSBASE;
- msrs[n++].index = MSR_FMASK;
- msrs[n++].index = MSR_LSTAR;
+ if (lm_capable_kernel) {
+ msrs[n++].index = MSR_CSTAR;
+ msrs[n++].index = MSR_KERNELGSBASE;
+ msrs[n++].index = MSR_FMASK;
+ msrs[n++].index = MSR_LSTAR;
+ }
#endif
msrs[n++].index = MSR_KVM_SYSTEM_TIME;
msrs[n++].index = MSR_KVM_WALL_CLOCK;
@@ -1066,6 +1110,9 @@ static int kvm_get_msrs(CPUState *env)
case MSR_IA32_TSC:
env->tsc = msrs[i].data;
break;
+ case MSR_VM_HSAVE_PA:
+ env->vm_hsave = msrs[i].data;
+ break;
case MSR_KVM_SYSTEM_TIME:
env->system_time_msr = msrs[i].data;
break;
@@ -1085,9 +1132,9 @@ static int kvm_get_msrs(CPUState *env)
if (msrs[i].index >= MSR_MC0_CTL &&
msrs[i].index < MSR_MC0_CTL + (env->mcg_cap & 0xff) * 4) {
env->mce_banks[msrs[i].index - MSR_MC0_CTL] = msrs[i].data;
- break;
}
#endif
+ break;
}
}
@@ -1632,6 +1679,28 @@ static void hardware_memory_error(void)
exit(1);
}
+#ifdef KVM_CAP_MCE
+static void kvm_mce_broadcast_rest(CPUState *env)
+{
+ CPUState *cenv;
+ int family, model, cpuver = env->cpuid_version;
+
+ family = (cpuver >> 8) & 0xf;
+ model = ((cpuver >> 12) & 0xf0) + ((cpuver >> 4) & 0xf);
+
+ /* Broadcast MCA signal for processor version 06H_EH and above */
+ if ((family == 6 && model >= 14) || family > 6) {
+ for (cenv = first_cpu; cenv != NULL; cenv = cenv->next_cpu) {
+ if (cenv == env) {
+ continue;
+ }
+ kvm_inject_x86_mce(cenv, 1, MCI_STATUS_VAL | MCI_STATUS_UC,
+ MCG_STATUS_MCIP | MCG_STATUS_RIPV, 0, 0, 1);
+ }
+ }
+}
+#endif
+
int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr)
{
#if defined(KVM_CAP_MCE)
@@ -1689,6 +1758,7 @@ int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr)
fprintf(stderr, "kvm_set_mce: %s\n", strerror(errno));
abort();
}
+ kvm_mce_broadcast_rest(env);
} else
#endif
{
@@ -1711,7 +1781,6 @@ int kvm_on_sigbus(int code, void *addr)
void *vaddr;
ram_addr_t ram_addr;
target_phys_addr_t paddr;
- CPUState *cenv;
/* Hope we are lucky for AO MCE */
vaddr = addr;
@@ -1727,10 +1796,7 @@ int kvm_on_sigbus(int code, void *addr)
kvm_inject_x86_mce(first_cpu, 9, status,
MCG_STATUS_MCIP | MCG_STATUS_RIPV, paddr,
(MCM_ADDR_PHYS << 6) | 0xc, 1);
- for (cenv = first_cpu->next_cpu; cenv != NULL; cenv = cenv->next_cpu) {
- kvm_inject_x86_mce(cenv, 1, MCI_STATUS_VAL | MCI_STATUS_UC,
- MCG_STATUS_MCIP | MCG_STATUS_RIPV, 0, 0, 1);
- }
+ kvm_mce_broadcast_rest(first_cpu);
} else
#endif
{
diff --git a/tests/Makefile b/tests/Makefile
index ff7f787a9a..e43ec70b6d 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -1,83 +1,120 @@
-include ../config-host.mak
+-include $(SRC_PATH)/rules.mak
$(call set-vpath, $(SRC_PATH)/tests)
-CFLAGS=-Wall -O2 -g -fno-strict-aliasing
+QEMU=../i386-linux-user/qemu-i386
+QEMU_X86_64=../x86_64-linux-user/qemu-x86_64
+CC_X86_64=$(CC_I386) -m64
+
+CFLAGS=-Wall -O2 -g -fno-strict-aliasing -I..
#CFLAGS+=-msse2
LDFLAGS=
-ifeq ($(ARCH),i386)
-TESTS=linux-test testthread sha1-i386 test-i386
+# TODO: automatically detect ARM and MIPS compilers, and run those too
+
+# runcom maps page 0, so it requires root privileges
+# also, pi_10.com runs indefinitely
+
+I386_TESTS=hello-i386 \
+ linux-test \
+ testthread \
+ sha1-i386 \
+ test-i386 \
+ test-mmap \
+ # runcom
+
+# native i386 compilers sometimes are not biarch. assume cross-compilers are
+ifneq ($(ARCH),i386)
+I386_TESTS+=run-test-x86_64
endif
-ifeq ($(ARCH),x86_64)
-TESTS=test-x86_64
+
+TESTS = test_path
+ifneq ($(call find-in-path, $(CC_I386)),)
+TESTS += $(I386_TESTS)
endif
-TESTS+=sha1# test_path
-#TESTS+=test_path
-#TESTS+=runcom
-QEMU=../i386-linux-user/qemu-i386
+all: $(patsubst %,run-%,$(TESTS))
+
+# rules to run tests
+
+.PHONY: $(patsubst %,run-%,$(TESTS))
+
+run-%: %
+ -$(QEMU) ./$*
+
+run-hello-i386: hello-i386
+run-linux-test: linux-test
+run-testthread: testthread
+run-sha1-i386: sha1-i386
+
+run-test-i386: test-i386
+ ./test-i386 > test-i386.ref
+ -$(QEMU) test-i386 > test-i386.out
+ @if diff -u test-i386.ref test-i386.out ; then echo "Auto Test OK"; fi
+
+run-test-x86_64: test-x86_64
+ ./test-x86_64 > test-x86_64.ref
+ -$(QEMU_X86_64) test-x86_64 > test-x86_64.out
+ @if diff -u test-x86_64.ref test-x86_64.out ; then echo "Auto Test OK"; fi
+
+run-test-mmap: test-mmap
+ -$(QEMU) ./test-mmap
+ -$(QEMU) -p 8192 ./test-mmap 8192
+ -$(QEMU) -p 16384 ./test-mmap 16384
+ -$(QEMU) -p 32768 ./test-mmap 32768
+
+run-runcom: runcom
+ -$(QEMU) ./runcom $(SRC_PATH)/tests/pi_10.com
+
+run-test_path: test_path
+ ./test_path
+
+# rules to compile tests
-all: $(TESTS)
+test_path: test_path.o
+test_path.o: test_path.c
hello-i386: hello-i386.c
- $(CC) -nostdlib $(CFLAGS) -static $(LDFLAGS) -o $@ $<
+ $(CC_I386) -nostdlib $(CFLAGS) -static $(LDFLAGS) -o $@ $<
strip $@
testthread: testthread.c
- $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lpthread
-
-test_path: test_path.c
- $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
- ./$@ || { rm $@; exit 1; }
+ $(CC_I386) $(CFLAGS) $(LDFLAGS) -o $@ $< -lpthread
# i386/x86_64 emulation test (test various opcodes) */
test-i386: test-i386.c test-i386-code16.S test-i386-vm86.S \
test-i386.h test-i386-shift.h test-i386-muldiv.h
- $(CC) -m32 $(CFLAGS) $(LDFLAGS) -static -o $@ \
+ $(CC_I386) $(CFLAGS) $(LDFLAGS) -o $@ \
$(<D)/test-i386.c $(<D)/test-i386-code16.S $(<D)/test-i386-vm86.S -lm
test-x86_64: test-i386.c \
test-i386.h test-i386-shift.h test-i386-muldiv.h
- $(CC) -m64 $(CFLAGS) $(LDFLAGS) -static -o $@ $(<D)/test-i386.c -lm
-
-ifeq ($(ARCH),i386)
-test: test-i386
- ./test-i386 > test-i386.ref
-else
-test:
-endif
- $(QEMU) test-i386 > test-i386.out
- @if diff -u test-i386.ref test-i386.out ; then echo "Auto Test OK"; fi
-
-.PHONY: test-mmap
-test-mmap: test-mmap.c
- $(CC) $(CFLAGS) -Wall -static -O2 $(LDFLAGS) -o $@ $<
- -./test-mmap
- -$(QEMU) ./test-mmap
- -$(QEMU) -p 8192 ./test-mmap 8192
- -$(QEMU) -p 16384 ./test-mmap 16384
- -$(QEMU) -p 32768 ./test-mmap 32768
+ $(CC_X86_64) $(CFLAGS) $(LDFLAGS) -o $@ $(<D)/test-i386.c -lm
# generic Linux and CPU test
linux-test: linux-test.c
- $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lm
+ $(CC_I386) $(CFLAGS) $(LDFLAGS) -o $@ $< -lm
+
+# vm86 test
+runcom: runcom.c
+ $(CC_I386) $(CFLAGS) $(LDFLAGS) -o $@ $<
+
+test-mmap: test-mmap.c
+ $(CC_I386) -m32 $(CFLAGS) -Wall -O2 $(LDFLAGS) -o $@ $<
# speed test
sha1-i386: sha1.c
- $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
+ $(CC_I386) $(CFLAGS) $(LDFLAGS) -o $@ $<
sha1: sha1.c
- $(HOST_CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
speed: sha1 sha1-i386
time ./sha1
time $(QEMU) ./sha1-i386
-# vm86 test
-runcom: runcom.c
- $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
-
+# broken test
# NOTE: -fomit-frame-pointer is currently needed : this is a bug in libqemu
qruncom: qruncom.c ../ioport-user.c ../i386-user/libqemu.a
$(CC) $(CFLAGS) -fomit-frame-pointer $(LDFLAGS) -I../target-i386 -I.. -I../i386-user -I../fpu \
diff --git a/tests/runcom.c b/tests/runcom.c
index 6380566635..d60342bfc6 100644
--- a/tests/runcom.c
+++ b/tests/runcom.c
@@ -13,15 +13,12 @@
#include <linux/unistd.h>
#include <asm/vm86.h>
-//#define SIGTEST
+extern int vm86 (unsigned long int subfunction,
+ struct vm86plus_struct *info);
-#undef __syscall_return
-#define __syscall_return(type, res) \
-do { \
- return (type) (res); \
-} while (0)
+#define VIF_MASK 0x00080000
-_syscall2(int, vm86, int, func, struct vm86plus_struct *, v86)
+//#define SIGTEST
#define COM_BASE_ADDR 0x10100
diff --git a/tests/test-i386.c b/tests/test-i386.c
index b28b257f81..8f481c7f7a 100644
--- a/tests/test-i386.c
+++ b/tests/test-i386.c
@@ -2047,6 +2047,10 @@ long enter_stack[4096];
#define RBP "%%ebp"
#endif
+#if !defined(__x86_64__)
+/* causes an infinite loop, disable it for now. */
+#define TEST_ENTER(size, stack_type, level)
+#else
#define TEST_ENTER(size, stack_type, level)\
{\
long esp_save, esp_val, ebp_val, ebp_save, i;\
@@ -2078,6 +2082,7 @@ long enter_stack[4096];
for(ptr = (stack_type *)esp_val; ptr < stack_end; ptr++)\
printf(FMTLX "\n", (long)ptr[0]);\
}
+#endif
static void test_enter(void)
{
diff --git a/tests/test_path.c b/tests/test_path.c
index def7441c8c..234ed97088 100644
--- a/tests/test_path.c
+++ b/tests/test_path.c
@@ -1,12 +1,21 @@
/* Test path override code */
-#define _GNU_SOURCE
+#include "../config-host.h"
+#include "../qemu-malloc.c"
+#include "../cutils.c"
#include "../path.c"
+#include "../trace.c"
+#ifdef CONFIG_SIMPLE_TRACE
+#include "../simpletrace.c"
+#endif
+
#include <stdarg.h>
#include <sys/stat.h>
#include <fcntl.h>
+void qemu_log(const char *fmt, ...);
+
/* Any log message kills the test. */
-void gemu_log(const char *fmt, ...)
+void qemu_log(const char *fmt, ...)
{
va_list ap;
diff --git a/ui/spice-display.c b/ui/spice-display.c
index 6702dfd7ea..7b4f5c1bc9 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -29,8 +29,7 @@
static int debug = 0;
-static void __attribute__((format(printf,2,3)))
-dprint(int level, const char *fmt, ...)
+static void GCC_FMT_ATTR(2, 3) dprint(int level, const char *fmt, ...)
{
va_list args;
diff --git a/vl.c b/vl.c
index df414ef5ac..7038952dc6 100644
--- a/vl.c
+++ b/vl.c
@@ -289,30 +289,6 @@ static int default_driver_check(QemuOpts *opts, void *opaque)
/***********************************************************/
/* real time host monotonic timer */
-/* compute with 96 bit intermediate result: (a*b)/c */
-uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
-{
- union {
- uint64_t ll;
- struct {
-#ifdef HOST_WORDS_BIGENDIAN
- uint32_t high, low;
-#else
- uint32_t low, high;
-#endif
- } l;
- } u, res;
- uint64_t rl, rh;
-
- u.ll = a;
- rl = (uint64_t)u.l.low * (uint64_t)b;
- rh = (uint64_t)u.l.high * (uint64_t)b;
- rh += (rl >> 32);
- res.l.high = rh / c;
- res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
- return res.ll;
-}
-
/***********************************************************/
/* host time/date access */
void qemu_get_timedate(struct tm *tm, int offset)