mirror of https://gitee.com/openkylin/qemu.git
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. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQEcBAABAgAGBQJUtjlCAAoJEL/70l94x66Dy5gH/0QIHoXVH/2wuA9apNK2/gBj 2U7g08QGKlc2wQGF4a48sQf523lSt5eirVxrwta0wmvFeznrdR84d4YGpolHM67A Q9Y5J2i+v1H6cfQH6ylq61QQ7rEC3+isa65wblLeMSCAb2W1CcV7avSKu4BSPZw2 jGr3jd2Ve7pOsULpPhiNsmmltYSeZc7sQBYc9C7fQEoxOGsNnRoKOUKPnIk1mJTc iYH480L1MnOL3enIz13K34lQofNRhJxJBLYKhYsBydQbOh0/Ls1eifOY4xEegXZ0 IUODy6c2pk+s/IUPARpBucKGKzDxdv0DLXDV60uGn5EsYT0CjCl9/sRs3bZvaQE= =eT8u -----END PGP SIGNATURE----- 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>
This commit is contained in:
commit
b629a38a13
2
cpus.c
2
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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];
|
||||
event_notifier_init(&p->e, 0);
|
||||
|
||||
fcntl(p->rfd, F_SETFL, O_NONBLOCK);
|
||||
fcntl(p->wfd, F_SETFL, O_NONBLOCK);
|
||||
|
||||
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;
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
#include <glib.h>
|
||||
|
||||
typedef struct V9fsThPool {
|
||||
int rfd;
|
||||
int wfd;
|
||||
EventNotifier e;
|
||||
|
||||
GThreadPool *pool;
|
||||
GAsyncQueue *completed;
|
||||
} V9fsThPool;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
15
qemu-char.c
15
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;
|
||||
|
|
|
@ -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;
|
||||
|
|
23
rules.mak
23
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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)));
|
||||
|
|
214
vl.c
214
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);
|
||||
|
|
Loading…
Reference in New Issue