]> Git Repo - qemu.git/commitdiff
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
authorPeter Maydell <[email protected]>
Wed, 14 Jan 2015 18:02:47 +0000 (18:02 +0000)
committerPeter Maydell <[email protected]>
Wed, 14 Jan 2015 18:02:47 +0000 (18:02 +0000)
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 <[email protected]>"
# gpg:                 aka "Paolo Bonzini <[email protected]>"
# 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 <[email protected]>
14 files changed:
cpus.c
hw/9pfs/virtio-9p-coth.c
hw/9pfs/virtio-9p-coth.h
hw/scsi/lsi53c895a.c
hw/scsi/scsi-bus.c
include/block/aio.h
include/qemu-common.h
include/qemu/timer.h
qemu-char.c
qemu-timer.c
rules.mak
target-i386/kvm.c
target-i386/translate.c
vl.c

diff --git a/cpus.c b/cpus.c
index 2edb5cd807c69ca507abb45d03579ce5c48063d0..3a5323b1fc584ddf4bb64b7b1ca13c8bb197d0b9 100644 (file)
--- a/cpus.c
+++ b/cpus.c
@@ -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();
 }
 
index ae6cde80053e5894aada975e1a0731a3d8d9ac4f..8185c533c013393e5ebc741de0d8e4b26b88c442 100644 (file)
@@ -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;
index 86d5ed416999677874864784078fd6759ab47c6b..4f51b250d1d44fa842b554ad8bf272165648cf5a 100644 (file)
@@ -21,8 +21,8 @@
 #include <glib.h>
 
 typedef struct V9fsThPool {
-    int rfd;
-    int wfd;
+    EventNotifier e;
+
     GThreadPool *pool;
     GAsyncQueue *completed;
 } V9fsThPool;
index ec920488d660520d32ea6a18b8c40d08522a58d9..db7d4b8c9c4099cc490f5b5b5c825a13cc6b47e8 100644 (file)
@@ -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 */
index 24f7b74ae8ba12e28fe29e48b0a5741029b48b1a..9b740a3cfa10250ae7014950415966464cdaecd4 100644 (file)
@@ -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);
     }
 }
 
index 6bf0e0456aae1f463cef0a6446f7c16ec4cd0a69..7d1e26b33b5d8a1f2a8c719bd61424a2cee8934e 100644 (file)
@@ -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);
 }
 
 /**
index f8622141a80b44bc9e00609d63b529d67addc0b4..644b46dcddf3137f54a4e3a283b6a5462b57d470 100644 (file)
@@ -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))
index d9df0940d95087cb7b3ec82dd8e7c65e78df182e..0666920652cb54d8786d73f78541bf7c14aadf9e 100644 (file)
@@ -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;
 }
 
index ef84b5368160edcb710a41ad0b3085597c057978..5430b870488edbd9e17fd1ddf7f28c67a7c73f11 100644 (file)
@@ -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;
index cb7d988b566b8389f4fec4d374565f3a0785815c..98d9d1bc0b84b9a7644e2ccab71fabf22824b06f 100644 (file)
@@ -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;
index f500fefdd15e99f227f4013df1ec5dc7a1949d15..3a056272e258087d814096b2f6126c8893930928 100644 (file)
--- a/rules.mak
+++ b/rules.mak
@@ -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
index 54ccb890b54b60d2ce8a1fdf2e0081ad6e2584b2..36b1519f34c89b56c037e49c9a9b82b2a54daa1c 100644 (file)
@@ -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);
index ebdc3500e545f2bdbd84fbc7a35305fea34a1661..9ebdf4b38467e9b32610d8120da47061bd253b4a 100644 (file)
@@ -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)));
diff --git a/vl.c b/vl.c
index 7786b2f9217472ce7c0b6dac2de36e3738560b9a..6adb36ecd45c61af8142a233999e5146cb2d7d63 100644 (file)
--- a/vl.c
+++ b/vl.c
@@ -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);
This page took 0.060837 seconds and 4 git commands to generate.