diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2015-01-14 18:02:47 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2015-01-14 18:02:47 +0000 |
commit | b629a38a13745d62d44de8ebb00f4e38ec6d8f7e (patch) | |
tree | 2318cf294ffd0390d5078593fdcfdb1ce830a274 | |
parent | 3a7f560fa612610822727f7647ed6bc10bccd6ec (diff) | |
parent | 1979b908b6e99cc24c1c0746060422f8778aa9d9 (diff) | |
download | hqemu-b629a38a13745d62d44de8ebb00f4e38ec6d8f7e.zip hqemu-b629a38a13745d62d44de8ebb00f4e38ec6d8f7e.tar.gz |
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
Mostly bugfixes and cleanups from qemu-devel. Yet another small patch from
the record/replay series, and a few SCSI and i386 patches as well.
# gpg: Signature made Wed 14 Jan 2015 09:39:14 GMT using RSA key ID 78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>"
# gpg: aka "Paolo Bonzini <pbonzini@redhat.com>"
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg: It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1
# Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83
* remotes/bonzini/tags/for-upstream:
cpus: consistently use QEMU_CLOCK_VIRTUAL_RT for icount_warp_rt timer
qemu-timer: rename timer_init to timer_init_tl
scsi: fix cancellation when I/O was completed but DMA was not.
rules.mak: Fix module build
hw/scsi/lsi53c895a: add support for additional diag / debug registers
qemu-common.h: optimise muldiv64 if int128 is available
target-i386: do not memcpy in and out of xmm_regs
target-i386: fix movntsd on big-endian hosts
vl.c: fix regression when reading memory size from config file
vl: Don't silently change topology when all -smp options were set
vl: fix max_cpus check
vl: Avoid unnecessary 'if' nesting
9pfs: changed to use event_notifier instead of qemu_pipe
vl.c: fix regression when reading machine type from config file
char: restore stdio echo on resume from suspend.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | cpus.c | 2 | ||||
-rw-r--r-- | hw/9pfs/virtio-9p-coth.c | 29 | ||||
-rw-r--r-- | hw/9pfs/virtio-9p-coth.h | 4 | ||||
-rw-r--r-- | hw/scsi/lsi53c895a.c | 6 | ||||
-rw-r--r-- | hw/scsi/scsi-bus.c | 2 | ||||
-rw-r--r-- | include/block/aio.h | 2 | ||||
-rw-r--r-- | include/qemu-common.h | 7 | ||||
-rw-r--r-- | include/qemu/timer.h | 10 | ||||
-rw-r--r-- | qemu-char.c | 15 | ||||
-rw-r--r-- | qemu-timer.c | 6 | ||||
-rw-r--r-- | rules.mak | 23 | ||||
-rw-r--r-- | target-i386/kvm.c | 30 | ||||
-rw-r--r-- | target-i386/translate.c | 11 | ||||
-rw-r--r-- | vl.c | 214 |
14 files changed, 202 insertions, 159 deletions
@@ -324,7 +324,7 @@ static void icount_adjust(void) static void icount_adjust_rt(void *opaque) { timer_mod(icount_rt_timer, - qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1000); + qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL_RT) + 1000); icount_adjust(); } diff --git a/hw/9pfs/virtio-9p-coth.c b/hw/9pfs/virtio-9p-coth.c index ae6cde8..8185c53 100644 --- a/hw/9pfs/virtio-9p-coth.c +++ b/hw/9pfs/virtio-9p-coth.c @@ -14,6 +14,7 @@ #include "fsdev/qemu-fsdev.h" #include "qemu/thread.h" +#include "qemu/event_notifier.h" #include "block/coroutine.h" #include "virtio-9p-coth.h" @@ -26,15 +27,11 @@ void co_run_in_worker_bh(void *opaque) g_thread_pool_push(v9fs_pool.pool, co, NULL); } -static void v9fs_qemu_process_req_done(void *arg) +static void v9fs_qemu_process_req_done(EventNotifier *e) { - char byte; - ssize_t len; Coroutine *co; - do { - len = read(v9fs_pool.rfd, &byte, sizeof(byte)); - } while (len == -1 && errno == EINTR); + event_notifier_test_and_clear(e); while ((co = g_async_queue_try_pop(v9fs_pool.completed)) != NULL) { qemu_coroutine_enter(co, NULL); @@ -43,22 +40,18 @@ static void v9fs_qemu_process_req_done(void *arg) static void v9fs_thread_routine(gpointer data, gpointer user_data) { - ssize_t len; - char byte = 0; Coroutine *co = data; qemu_coroutine_enter(co, NULL); g_async_queue_push(v9fs_pool.completed, co); - do { - len = write(v9fs_pool.wfd, &byte, sizeof(byte)); - } while (len == -1 && errno == EINTR); + + event_notifier_set(&v9fs_pool.e); } int v9fs_init_worker_threads(void) { int ret = 0; - int notifier_fds[2]; V9fsThPool *p = &v9fs_pool; sigset_t set, oldset; @@ -66,10 +59,6 @@ int v9fs_init_worker_threads(void) /* Leave signal handling to the iothread. */ pthread_sigmask(SIG_SETMASK, &set, &oldset); - if (qemu_pipe(notifier_fds) == -1) { - ret = -1; - goto err_out; - } p->pool = g_thread_pool_new(v9fs_thread_routine, p, -1, FALSE, NULL); if (!p->pool) { ret = -1; @@ -84,13 +73,9 @@ int v9fs_init_worker_threads(void) ret = -1; goto err_out; } - p->rfd = notifier_fds[0]; - p->wfd = notifier_fds[1]; - - fcntl(p->rfd, F_SETFL, O_NONBLOCK); - fcntl(p->wfd, F_SETFL, O_NONBLOCK); + event_notifier_init(&p->e, 0); - qemu_set_fd_handler(p->rfd, v9fs_qemu_process_req_done, NULL, NULL); + event_notifier_set_handler(&p->e, v9fs_qemu_process_req_done); err_out: pthread_sigmask(SIG_SETMASK, &oldset, NULL); return ret; diff --git a/hw/9pfs/virtio-9p-coth.h b/hw/9pfs/virtio-9p-coth.h index 86d5ed4..4f51b25 100644 --- a/hw/9pfs/virtio-9p-coth.h +++ b/hw/9pfs/virtio-9p-coth.h @@ -21,8 +21,8 @@ #include <glib.h> typedef struct V9fsThPool { - int rfd; - int wfd; + EventNotifier e; + GThreadPool *pool; GAsyncQueue *completed; } V9fsThPool; diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c index ec92048..db7d4b8 100644 --- a/hw/scsi/lsi53c895a.c +++ b/hw/scsi/lsi53c895a.c @@ -277,6 +277,7 @@ typedef struct { uint32_t csbc; uint32_t scratch[18]; /* SCRATCHA-SCRATCHR */ uint8_t sbr; + uint32_t adder; /* Script ram is stored as 32-bit words in host byteorder. */ uint32_t script_ram[2048]; @@ -1389,6 +1390,7 @@ again: switch ((insn >> 27) & 7) { case 0: /* Jump */ DPRINTF("Jump to 0x%08x\n", addr); + s->adder = addr; s->dsp = addr; break; case 1: /* Call */ @@ -1513,6 +1515,8 @@ static uint8_t lsi_reg_readb(LSIState *s, int offset) return 0x7f; case 0x08: /* Revision ID */ return 0x00; + case 0x09: /* SOCL */ + return s->socl; case 0xa: /* SSID */ return s->ssid; case 0xb: /* SBCL */ @@ -1577,6 +1581,8 @@ static uint8_t lsi_reg_readb(LSIState *s, int offset) return s->sbr; case 0x3b: /* DCNTL */ return s->dcntl; + /* ADDER Output (Debug of relative jump address) */ + CASE_GET_REG32(adder, 0x3c) case 0x40: /* SIEN0 */ return s->sien0; case 0x41: /* SIEN1 */ diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c index 24f7b74..9b740a3 100644 --- a/hw/scsi/scsi-bus.c +++ b/hw/scsi/scsi-bus.c @@ -1770,6 +1770,8 @@ void scsi_req_cancel(SCSIRequest *req) req->io_canceled = true; if (req->aiocb) { blk_aio_cancel(req->aiocb); + } else { + scsi_req_cancel_complete(req); } } diff --git a/include/block/aio.h b/include/block/aio.h index 6bf0e04..7d1e26b 100644 --- a/include/block/aio.h +++ b/include/block/aio.h @@ -314,7 +314,7 @@ static inline void aio_timer_init(AioContext *ctx, int scale, QEMUTimerCB *cb, void *opaque) { - timer_init(ts, ctx->tlg.tl[type], scale, cb, opaque); + timer_init_tl(ts, ctx->tlg.tl[type], scale, cb, opaque); } /** diff --git a/include/qemu-common.h b/include/qemu-common.h index f862214..644b46d 100644 --- a/include/qemu-common.h +++ b/include/qemu-common.h @@ -370,6 +370,12 @@ static inline uint8_t from_bcd(uint8_t val) } /* compute with 96 bit intermediate result: (a*b)/c */ +#ifdef CONFIG_INT128 +static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c) +{ + return (__int128_t)a * b / c; +} +#else static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c) { union { @@ -392,6 +398,7 @@ static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c) res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c; return res.ll; } +#endif /* Round number down to multiple */ #define QEMU_ALIGN_DOWN(n, m) ((n) / (m) * (m)) diff --git a/include/qemu/timer.h b/include/qemu/timer.h index d9df094..0666920 100644 --- a/include/qemu/timer.h +++ b/include/qemu/timer.h @@ -410,7 +410,7 @@ int64_t timerlistgroup_deadline_ns(QEMUTimerListGroup *tlg); */ /** - * timer_init: + * timer_init_tl: * @ts: the timer to be initialised * @timer_list: the timer list to attach the timer to * @scale: the scale value for the timer @@ -423,9 +423,9 @@ int64_t timerlistgroup_deadline_ns(QEMUTimerListGroup *tlg); * You need not call an explicit deinit call. Simply make * sure it is not on a list with timer_del. */ -void timer_init(QEMUTimer *ts, - QEMUTimerList *timer_list, int scale, - QEMUTimerCB *cb, void *opaque); +void timer_init_tl(QEMUTimer *ts, + QEMUTimerList *timer_list, int scale, + QEMUTimerCB *cb, void *opaque); /** * timer_new_tl: @@ -448,7 +448,7 @@ static inline QEMUTimer *timer_new_tl(QEMUTimerList *timer_list, void *opaque) { QEMUTimer *ts = g_malloc0(sizeof(QEMUTimer)); - timer_init(ts, timer_list, scale, cb, opaque); + timer_init_tl(ts, timer_list, scale, cb, opaque); return ts; } diff --git a/qemu-char.c b/qemu-char.c index ef84b53..5430b87 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -1112,6 +1112,9 @@ static struct termios oldtty; static int old_fd0_flags; static bool stdio_in_use; static bool stdio_allow_signal; +static bool stdio_echo_state; + +static void qemu_chr_set_echo_stdio(CharDriverState *chr, bool echo); static void term_exit(void) { @@ -1119,10 +1122,17 @@ static void term_exit(void) fcntl(0, F_SETFL, old_fd0_flags); } +static void term_stdio_handler(int sig) +{ + /* restore echo after resume from suspend. */ + qemu_chr_set_echo_stdio(NULL, stdio_echo_state); +} + static void qemu_chr_set_echo_stdio(CharDriverState *chr, bool echo) { struct termios tty; + stdio_echo_state = echo; tty = oldtty; if (!echo) { tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP @@ -1149,6 +1159,7 @@ static void qemu_chr_close_stdio(struct CharDriverState *chr) static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts) { CharDriverState *chr; + struct sigaction act; if (is_daemonized()) { error_report("cannot use stdio with -daemonize"); @@ -1166,6 +1177,10 @@ static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts) qemu_set_nonblock(0); atexit(term_exit); + memset(&act, 0, sizeof(act)); + act.sa_handler = term_stdio_handler; + sigaction(SIGCONT, &act, NULL); + chr = qemu_chr_open_fd(0, 1); chr->chr_close = qemu_chr_close_stdio; chr->chr_set_echo = qemu_chr_set_echo_stdio; diff --git a/qemu-timer.c b/qemu-timer.c index cb7d988..98d9d1b 100644 --- a/qemu-timer.c +++ b/qemu-timer.c @@ -331,9 +331,9 @@ int qemu_poll_ns(GPollFD *fds, guint nfds, int64_t timeout) } -void timer_init(QEMUTimer *ts, - QEMUTimerList *timer_list, int scale, - QEMUTimerCB *cb, void *opaque) +void timer_init_tl(QEMUTimer *ts, + QEMUTimerList *timer_list, int scale, + QEMUTimerCB *cb, void *opaque) { ts->timer_list = timer_list; ts->cb = cb; @@ -326,7 +326,17 @@ define unnest-vars $(if $1,$(call fix-paths,$1/,,$2)) # Descend and include every subdir Makefile.objs - $(foreach v, $2, $(call unnest-var-recursive,$1,$2,$v)) + $(foreach v, $2, + $(call unnest-var-recursive,$1,$2,$v) + # Pass the .mo-cflags and .mo-libs along to its member objects + $(foreach o, $(filter %.mo,$($v)), + $(foreach p,$($o-objs), + $(if $($o-cflags), $(eval $p-cflags += $($o-cflags))) + $(if $($o-libs), $(eval $p-libs += $($o-libs)))))) + + # For all %.mo objects that are directly added into -y, just expand them + $(foreach v,$(filter %-y,$2), + $(eval $v := $(foreach o,$($v),$(if $($o-objs),$($o-objs),$o)))) $(foreach v,$(filter %-m,$2), # All .o found in *-m variables are single object modules, create .mo @@ -353,18 +363,9 @@ define unnest-vars # according to .mo-objs. Report error if not set $(if $($o-objs), $(eval $(o:%.mo=%$(DSOSUF)): module-common.o $($o-objs)), - $(error $o added in $v but $o-objs is not set)) - # Pass the .mo-cflags and .mo-libs along to member objects - $(foreach p,$($o-objs), - $(if $($o-cflags), $(eval $p-cflags += $($o-cflags))) - $(if $($o-libs), $(eval $p-libs += $($o-libs))))) + $(error $o added in $v but $o-objs is not set))) $(shell mkdir -p ./ $(sort $(dir $($v)))) # Include all the .d files $(eval -include $(addsuffix *.d, $(sort $(dir $($v))))) $(eval $v := $(filter-out %/,$($v)))) - - # For all %.mo objects that are directly added into -y, expand them to %.mo-objs - $(foreach v,$2, - $(eval $v := $(foreach o,$($v),$(if $($o-objs),$($o-objs),$o)))) - endef diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 54ccb89..36b1519 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -1019,7 +1019,10 @@ static int kvm_put_fpu(X86CPU *cpu) fpu.ftwx |= (!env->fptags[i]) << i; } memcpy(fpu.fpr, env->fpregs, sizeof env->fpregs); - memcpy(fpu.xmm, env->xmm_regs, sizeof env->xmm_regs); + for (i = 0; i < CPU_NB_REGS; i++) { + stq_p(&fpu.xmm[i][0], env->xmm_regs[i].XMM_Q(0)); + stq_p(&fpu.xmm[i][8], env->xmm_regs[i].XMM_Q(1)); + } fpu.mxcsr = env->mxcsr; return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_FPU, &fpu); @@ -1045,6 +1048,7 @@ static int kvm_put_xsave(X86CPU *cpu) CPUX86State *env = &cpu->env; struct kvm_xsave* xsave = env->kvm_xsave_buf; uint16_t cwd, swd, twd; + uint8_t *xmm; int i, r; if (!kvm_has_xsave()) { @@ -1065,8 +1069,6 @@ static int kvm_put_xsave(X86CPU *cpu) memcpy(&xsave->region[XSAVE_CWD_RDP], &env->fpdp, sizeof(env->fpdp)); memcpy(&xsave->region[XSAVE_ST_SPACE], env->fpregs, sizeof env->fpregs); - memcpy(&xsave->region[XSAVE_XMM_SPACE], env->xmm_regs, - sizeof env->xmm_regs); xsave->region[XSAVE_MXCSR] = env->mxcsr; *(uint64_t *)&xsave->region[XSAVE_XSTATE_BV] = env->xstate_bv; memcpy(&xsave->region[XSAVE_YMMH_SPACE], env->ymmh_regs, @@ -1079,6 +1081,13 @@ static int kvm_put_xsave(X86CPU *cpu) sizeof env->opmask_regs); memcpy(&xsave->region[XSAVE_ZMM_Hi256], env->zmmh_regs, sizeof env->zmmh_regs); + + xmm = (uint8_t *)&xsave->region[XSAVE_XMM_SPACE]; + for (i = 0; i < CPU_NB_REGS; i++, xmm += 16) { + stq_p(xmm, env->xmm_regs[i].XMM_Q(0)); + stq_p(xmm+8, env->xmm_regs[i].XMM_Q(1)); + } + #ifdef TARGET_X86_64 memcpy(&xsave->region[XSAVE_Hi16_ZMM], env->hi16_zmm_regs, sizeof env->hi16_zmm_regs); @@ -1384,7 +1393,10 @@ static int kvm_get_fpu(X86CPU *cpu) env->fptags[i] = !((fpu.ftwx >> i) & 1); } memcpy(env->fpregs, fpu.fpr, sizeof env->fpregs); - memcpy(env->xmm_regs, fpu.xmm, sizeof env->xmm_regs); + for (i = 0; i < CPU_NB_REGS; i++) { + env->xmm_regs[i].XMM_Q(0) = ldq_p(&fpu.xmm[i][0]); + env->xmm_regs[i].XMM_Q(1) = ldq_p(&fpu.xmm[i][8]); + } env->mxcsr = fpu.mxcsr; return 0; @@ -1395,6 +1407,7 @@ static int kvm_get_xsave(X86CPU *cpu) CPUX86State *env = &cpu->env; struct kvm_xsave* xsave = env->kvm_xsave_buf; int ret, i; + const uint8_t *xmm; uint16_t cwd, swd, twd; if (!kvm_has_xsave()) { @@ -1421,8 +1434,6 @@ static int kvm_get_xsave(X86CPU *cpu) env->mxcsr = xsave->region[XSAVE_MXCSR]; memcpy(env->fpregs, &xsave->region[XSAVE_ST_SPACE], sizeof env->fpregs); - memcpy(env->xmm_regs, &xsave->region[XSAVE_XMM_SPACE], - sizeof env->xmm_regs); env->xstate_bv = *(uint64_t *)&xsave->region[XSAVE_XSTATE_BV]; memcpy(env->ymmh_regs, &xsave->region[XSAVE_YMMH_SPACE], sizeof env->ymmh_regs); @@ -1434,6 +1445,13 @@ static int kvm_get_xsave(X86CPU *cpu) sizeof env->opmask_regs); memcpy(env->zmmh_regs, &xsave->region[XSAVE_ZMM_Hi256], sizeof env->zmmh_regs); + + xmm = (const uint8_t *)&xsave->region[XSAVE_XMM_SPACE]; + for (i = 0; i < CPU_NB_REGS; i++, xmm += 16) { + env->xmm_regs[i].XMM_Q(0) = ldq_p(xmm); + env->xmm_regs[i].XMM_Q(1) = ldq_p(xmm+8); + } + #ifdef TARGET_X86_64 memcpy(env->hi16_zmm_regs, &xsave->region[XSAVE_Hi16_ZMM], sizeof env->hi16_zmm_regs); diff --git a/target-i386/translate.c b/target-i386/translate.c index ebdc350..9ebdf4b 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -2621,10 +2621,10 @@ static inline void gen_sto_env_A0(DisasContext *s, int offset) static inline void gen_op_movo(int d_offset, int s_offset) { - tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset); - tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset); - tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset + 8); - tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset + 8); + tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset + offsetof(XMMReg, XMM_Q(0))); + tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset + offsetof(XMMReg, XMM_Q(0))); + tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset + offsetof(XMMReg, XMM_Q(1))); + tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset + offsetof(XMMReg, XMM_Q(1))); } static inline void gen_op_movq(int d_offset, int s_offset) @@ -3074,7 +3074,8 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, goto illegal_op; gen_lea_modrm(env, s, modrm); if (b1 & 1) { - gen_stq_env_A0(s, offsetof(CPUX86State, xmm_regs[reg])); + gen_stq_env_A0(s, offsetof(CPUX86State, + xmm_regs[reg].XMM_Q(0))); } else { tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, xmm_regs[reg].XMM_L(0))); @@ -1170,13 +1170,17 @@ static void smp_parse(QemuOpts *opts) if (cpus == 0) { cpus = cores * threads * sockets; } - } else { - if (cores == 0) { - threads = threads > 0 ? threads : 1; - cores = cpus / (sockets * threads); - } else { - threads = cpus / (cores * sockets); - } + } else if (cores == 0) { + threads = threads > 0 ? threads : 1; + cores = cpus / (sockets * threads); + } else if (threads == 0) { + threads = cpus / (cores * sockets); + } else if (sockets * cores * threads < cpus) { + fprintf(stderr, "cpu topology: error: " + "sockets (%u) * cores (%u) * threads (%u) < " + "smp_cpus (%u)\n", + sockets, cores, threads, cpus); + exit(1); } max_cpus = qemu_opt_get_number(opts, "maxcpus", 0); @@ -2644,6 +2648,92 @@ out: return 0; } +static void set_memory_options(uint64_t *ram_slots, ram_addr_t *maxram_size) +{ + uint64_t sz; + const char *mem_str; + const char *maxmem_str, *slots_str; + const ram_addr_t default_ram_size = (ram_addr_t)DEFAULT_RAM_SIZE * + 1024 * 1024; + QemuOpts *opts = qemu_find_opts_singleton("memory"); + + sz = 0; + mem_str = qemu_opt_get(opts, "size"); + if (mem_str) { + if (!*mem_str) { + error_report("missing 'size' option value"); + exit(EXIT_FAILURE); + } + + sz = qemu_opt_get_size(opts, "size", ram_size); + + /* Fix up legacy suffix-less format */ + if (g_ascii_isdigit(mem_str[strlen(mem_str) - 1])) { + uint64_t overflow_check = sz; + + sz <<= 20; + if ((sz >> 20) != overflow_check) { + error_report("too large 'size' option value"); + exit(EXIT_FAILURE); + } + } + } + + /* backward compatibility behaviour for case "-m 0" */ + if (sz == 0) { + sz = default_ram_size; + } + + sz = QEMU_ALIGN_UP(sz, 8192); + ram_size = sz; + if (ram_size != sz) { + error_report("ram size too large"); + exit(EXIT_FAILURE); + } + + /* store value for the future use */ + qemu_opt_set_number(opts, "size", ram_size); + *maxram_size = ram_size; + + maxmem_str = qemu_opt_get(opts, "maxmem"); + slots_str = qemu_opt_get(opts, "slots"); + if (maxmem_str && slots_str) { + uint64_t slots; + + sz = qemu_opt_get_size(opts, "maxmem", 0); + if (sz < ram_size) { + error_report("invalid -m option value: maxmem " + "(0x%" PRIx64 ") <= initial memory (0x" + RAM_ADDR_FMT ")", sz, ram_size); + exit(EXIT_FAILURE); + } + + slots = qemu_opt_get_number(opts, "slots", 0); + if ((sz > ram_size) && !slots) { + error_report("invalid -m option value: maxmem " + "(0x%" PRIx64 ") more than initial memory (0x" + RAM_ADDR_FMT ") but no hotplug slots where " + "specified", sz, ram_size); + exit(EXIT_FAILURE); + } + + if ((sz <= ram_size) && slots) { + error_report("invalid -m option value: %" + PRIu64 " hotplug slots where specified but " + "maxmem (0x%" PRIx64 ") <= initial memory (0x" + RAM_ADDR_FMT ")", slots, sz, ram_size); + exit(EXIT_FAILURE); + } + *maxram_size = sz; + *ram_slots = slots; + } else if ((!maxmem_str && slots_str) || + (maxmem_str && !slots_str)) { + error_report("invalid -m option value: missing " + "'%s' option", slots_str ? "maxmem" : "slots"); + exit(EXIT_FAILURE); + } +} + int main(int argc, char **argv, char **envp) { int i; @@ -2679,9 +2769,7 @@ int main(int argc, char **argv, char **envp) }; const char *trace_events = NULL; const char *trace_file = NULL; - const ram_addr_t default_ram_size = (ram_addr_t)DEFAULT_RAM_SIZE * - 1024 * 1024; - ram_addr_t maxram_size = default_ram_size; + ram_addr_t maxram_size; uint64_t ram_slots = 0; FILE *vmstate_dump_file = NULL; Error *main_loop_err = NULL; @@ -2732,7 +2820,6 @@ int main(int argc, char **argv, char **envp) module_call_init(MODULE_INIT_MACHINE); machine_class = find_default_machine(); cpu_model = NULL; - ram_size = default_ram_size; snapshot = 0; cyls = heads = secs = 0; translation = BIOS_ATA_TRANSLATION_AUTO; @@ -2796,9 +2883,6 @@ int main(int argc, char **argv, char **envp) exit(1); } switch(popt->index) { - case QEMU_OPTION_M: - machine_class = machine_parse(optarg); - break; case QEMU_OPTION_no_kvm_irqchip: { olist = qemu_find_opts("machine"); qemu_opts_parse(olist, "kernel_irqchip=off", 0); @@ -3022,92 +3106,13 @@ int main(int argc, char **argv, char **envp) version(); exit(0); break; - case QEMU_OPTION_m: { - uint64_t sz; - const char *mem_str; - const char *maxmem_str, *slots_str; - + case QEMU_OPTION_m: opts = qemu_opts_parse(qemu_find_opts("memory"), optarg, 1); if (!opts) { exit(EXIT_FAILURE); } - - mem_str = qemu_opt_get(opts, "size"); - if (!mem_str) { - error_report("invalid -m option, missing 'size' option"); - exit(EXIT_FAILURE); - } - if (!*mem_str) { - error_report("missing 'size' option value"); - exit(EXIT_FAILURE); - } - - sz = qemu_opt_get_size(opts, "size", ram_size); - - /* Fix up legacy suffix-less format */ - if (g_ascii_isdigit(mem_str[strlen(mem_str) - 1])) { - uint64_t overflow_check = sz; - - sz <<= 20; - if ((sz >> 20) != overflow_check) { - error_report("too large 'size' option value"); - exit(EXIT_FAILURE); - } - } - - /* backward compatibility behaviour for case "-m 0" */ - if (sz == 0) { - sz = default_ram_size; - } - - sz = QEMU_ALIGN_UP(sz, 8192); - ram_size = sz; - if (ram_size != sz) { - error_report("ram size too large"); - exit(EXIT_FAILURE); - } - maxram_size = ram_size; - - maxmem_str = qemu_opt_get(opts, "maxmem"); - slots_str = qemu_opt_get(opts, "slots"); - if (maxmem_str && slots_str) { - uint64_t slots; - - sz = qemu_opt_get_size(opts, "maxmem", 0); - if (sz < ram_size) { - error_report("invalid -m option value: maxmem " - "(0x%" PRIx64 ") <= initial memory (0x" - RAM_ADDR_FMT ")", sz, ram_size); - exit(EXIT_FAILURE); - } - - slots = qemu_opt_get_number(opts, "slots", 0); - if ((sz > ram_size) && !slots) { - error_report("invalid -m option value: maxmem " - "(0x%" PRIx64 ") more than initial memory (0x" - RAM_ADDR_FMT ") but no hotplug slots where " - "specified", sz, ram_size); - exit(EXIT_FAILURE); - } - - if ((sz <= ram_size) && slots) { - error_report("invalid -m option value: %" - PRIu64 " hotplug slots where specified but " - "maxmem (0x%" PRIx64 ") <= initial memory (0x" - RAM_ADDR_FMT ")", slots, sz, ram_size); - exit(EXIT_FAILURE); - } - maxram_size = sz; - ram_slots = slots; - } else if ((!maxmem_str && slots_str) || - (maxmem_str && !slots_str)) { - error_report("invalid -m option value: missing " - "'%s' option", slots_str ? "maxmem" : "slots"); - exit(EXIT_FAILURE); - } break; - } #ifdef CONFIG_TPM case QEMU_OPTION_tpmdev: if (tpm_config_parse(qemu_find_opts("tpmdev"), optarg) < 0) { @@ -3420,16 +3425,13 @@ int main(int argc, char **argv, char **envp) olist = qemu_find_opts("machine"); qemu_opts_parse(olist, "accel=kvm", 0); break; + case QEMU_OPTION_M: case QEMU_OPTION_machine: olist = qemu_find_opts("machine"); opts = qemu_opts_parse(olist, optarg, 1); if (!opts) { exit(1); } - optarg = qemu_opt_get(opts, "type"); - if (optarg) { - machine_class = machine_parse(optarg); - } break; case QEMU_OPTION_no_kvm: olist = qemu_find_opts("machine"); @@ -3752,6 +3754,15 @@ int main(int argc, char **argv, char **envp) } } } + + opts = qemu_get_machine_opts(); + optarg = qemu_opt_get(opts, "type"); + if (optarg) { + machine_class = machine_parse(optarg); + } + + set_memory_options(&ram_slots, &maxram_size); + loc_set_none(); os_daemonize(); @@ -3851,9 +3862,9 @@ int main(int argc, char **argv, char **envp) smp_parse(qemu_opts_find(qemu_find_opts("smp-opts"), NULL)); machine_class->max_cpus = machine_class->max_cpus ?: 1; /* Default to UP */ - if (smp_cpus > machine_class->max_cpus) { + if (max_cpus > machine_class->max_cpus) { fprintf(stderr, "Number of SMP cpus requested (%d), exceeds max cpus " - "supported by machine `%s' (%d)\n", smp_cpus, + "supported by machine `%s' (%d)\n", max_cpus, machine_class->name, machine_class->max_cpus); exit(1); } @@ -4001,9 +4012,6 @@ int main(int argc, char **argv, char **envp) exit(1); } - /* store value for the future use */ - qemu_opt_set_number(qemu_find_opts_singleton("memory"), "size", ram_size); - if (qemu_opts_foreach(qemu_find_opts("device"), device_help_func, NULL, 0) != 0) { exit(0); |