Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Xing Lin
qemu
Commits
31b7c261
Commit
31b7c261
authored
Mar 21, 2011
by
Anthony Liguori
Browse files
Merge remote branch 'qemu-kvm/uq/master' into staging
parents
8b06c62a
dc7a09cf
Changes
24
Expand all
Hide whitespace changes
Inline
Side-by-side
cpu-all.h
View file @
31b7c261
...
...
@@ -863,10 +863,14 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr);
extern
int
phys_ram_fd
;
extern
ram_addr_t
ram_size
;
/* RAM is pre-allocated and passed into qemu_ram_alloc_from_ptr */
#define RAM_PREALLOC_MASK (1 << 0)
typedef
struct
RAMBlock
{
uint8_t
*
host
;
ram_addr_t
offset
;
ram_addr_t
length
;
uint32_t
flags
;
char
idstr
[
256
];
QLIST_ENTRY
(
RAMBlock
)
next
;
#if defined(__linux__) && !defined(TARGET_S390X)
...
...
@@ -971,8 +975,4 @@ void dump_exec_info(FILE *f, fprintf_function cpu_fprintf);
int
cpu_memory_rw_debug
(
CPUState
*
env
,
target_ulong
addr
,
uint8_t
*
buf
,
int
len
,
int
is_write
);
void
cpu_inject_x86_mce
(
CPUState
*
cenv
,
int
bank
,
uint64_t
status
,
uint64_t
mcg_status
,
uint64_t
addr
,
uint64_t
misc
,
int
broadcast
);
#endif
/* CPU_ALL_H */
cpu-common.h
View file @
31b7c261
...
...
@@ -50,6 +50,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name,
ram_addr_t
size
,
void
*
host
);
ram_addr_t
qemu_ram_alloc
(
DeviceState
*
dev
,
const
char
*
name
,
ram_addr_t
size
);
void
qemu_ram_free
(
ram_addr_t
addr
);
void
qemu_ram_remap
(
ram_addr_t
addr
,
ram_addr_t
length
);
/* This should only be used for ram local to a device. */
void
*
qemu_get_ram_ptr
(
ram_addr_t
addr
);
/* Same but slower, to use for migration, where the order of
...
...
cpu-defs.h
View file @
31b7c261
...
...
@@ -203,6 +203,7 @@ typedef struct CPUWatchpoint {
int nr_cores;
/* number of cores within this CPU package */
\
int nr_threads;
/* number of threads within this CPU */
\
int running;
/* Nonzero if cpu is currently running(usermode). */
\
int thread_id; \
/* user data */
\
void *opaque; \
\
...
...
cpu-exec.c
View file @
31b7c261
...
...
@@ -196,6 +196,30 @@ static inline TranslationBlock *tb_find_fast(void)
return
tb
;
}
static
CPUDebugExcpHandler
*
debug_excp_handler
;
CPUDebugExcpHandler
*
cpu_set_debug_excp_handler
(
CPUDebugExcpHandler
*
handler
)
{
CPUDebugExcpHandler
*
old_handler
=
debug_excp_handler
;
debug_excp_handler
=
handler
;
return
old_handler
;
}
static
void
cpu_handle_debug_exception
(
CPUState
*
env
)
{
CPUWatchpoint
*
wp
;
if
(
!
env
->
watchpoint_hit
)
{
QTAILQ_FOREACH
(
wp
,
&
env
->
watchpoints
,
entry
)
{
wp
->
flags
&=
~
BP_WATCHPOINT_HIT
;
}
}
if
(
debug_excp_handler
)
{
debug_excp_handler
(
env
);
}
}
/* main execution loop */
volatile
sig_atomic_t
exit_request
;
...
...
@@ -269,6 +293,9 @@ int cpu_exec(CPUState *env1)
if
(
env
->
exception_index
>=
EXCP_INTERRUPT
)
{
/* exit request from the cpu execution loop */
ret
=
env
->
exception_index
;
if
(
ret
==
EXCP_DEBUG
)
{
cpu_handle_debug_exception
(
env
);
}
break
;
}
else
{
#if defined(CONFIG_USER_ONLY)
...
...
cpus.c
View file @
31b7c261
...
...
@@ -148,7 +148,8 @@ static bool cpu_thread_is_idle(CPUState *env)
if
(
env
->
stopped
||
!
vm_running
)
{
return
true
;
}
if
(
!
env
->
halted
||
qemu_cpu_has_work
(
env
))
{
if
(
!
env
->
halted
||
qemu_cpu_has_work
(
env
)
||
(
kvm_enabled
()
&&
kvm_irqchip_in_kernel
()))
{
return
false
;
}
return
true
;
...
...
@@ -166,29 +167,8 @@ static bool all_cpu_threads_idle(void)
return
true
;
}
static
CPUDebugExcpHandler
*
debug_excp_handler
;
CPUDebugExcpHandler
*
cpu_set_debug_excp_handler
(
CPUDebugExcpHandler
*
handler
)
static
void
cpu_handle_guest_debug
(
CPUState
*
env
)
{
CPUDebugExcpHandler
*
old_handler
=
debug_excp_handler
;
debug_excp_handler
=
handler
;
return
old_handler
;
}
static
void
cpu_handle_debug_exception
(
CPUState
*
env
)
{
CPUWatchpoint
*
wp
;
if
(
!
env
->
watchpoint_hit
)
{
QTAILQ_FOREACH
(
wp
,
&
env
->
watchpoints
,
entry
)
{
wp
->
flags
&=
~
BP_WATCHPOINT_HIT
;
}
}
if
(
debug_excp_handler
)
{
debug_excp_handler
(
env
);
}
gdb_set_stop_cpu
(
env
);
qemu_system_debug_request
();
#ifdef CONFIG_IOTHREAD
...
...
@@ -245,11 +225,58 @@ static void qemu_init_sigbus(void)
prctl
(
PR_MCE_KILL
,
PR_MCE_KILL_SET
,
PR_MCE_KILL_EARLY
,
0
,
0
);
}
static
void
qemu_kvm_eat_signals
(
CPUState
*
env
)
{
struct
timespec
ts
=
{
0
,
0
};
siginfo_t
siginfo
;
sigset_t
waitset
;
sigset_t
chkset
;
int
r
;
sigemptyset
(
&
waitset
);
sigaddset
(
&
waitset
,
SIG_IPI
);
sigaddset
(
&
waitset
,
SIGBUS
);
do
{
r
=
sigtimedwait
(
&
waitset
,
&
siginfo
,
&
ts
);
if
(
r
==
-
1
&&
!
(
errno
==
EAGAIN
||
errno
==
EINTR
))
{
perror
(
"sigtimedwait"
);
exit
(
1
);
}
switch
(
r
)
{
case
SIGBUS
:
if
(
kvm_on_sigbus_vcpu
(
env
,
siginfo
.
si_code
,
siginfo
.
si_addr
))
{
sigbus_reraise
();
}
break
;
default:
break
;
}
r
=
sigpending
(
&
chkset
);
if
(
r
==
-
1
)
{
perror
(
"sigpending"
);
exit
(
1
);
}
}
while
(
sigismember
(
&
chkset
,
SIG_IPI
)
||
sigismember
(
&
chkset
,
SIGBUS
));
#ifndef CONFIG_IOTHREAD
if
(
sigismember
(
&
chkset
,
SIGIO
)
||
sigismember
(
&
chkset
,
SIGALRM
))
{
qemu_notify_event
();
}
#endif
}
#else
/* !CONFIG_LINUX */
static
void
qemu_init_sigbus
(
void
)
{
}
static
void
qemu_kvm_eat_signals
(
CPUState
*
env
)
{
}
#endif
/* !CONFIG_LINUX */
#ifndef _WIN32
...
...
@@ -455,49 +482,6 @@ static void qemu_tcg_init_cpu_signals(void)
#endif
}
static
void
qemu_kvm_eat_signals
(
CPUState
*
env
)
{
struct
timespec
ts
=
{
0
,
0
};
siginfo_t
siginfo
;
sigset_t
waitset
;
sigset_t
chkset
;
int
r
;
sigemptyset
(
&
waitset
);
sigaddset
(
&
waitset
,
SIG_IPI
);
sigaddset
(
&
waitset
,
SIGBUS
);
do
{
r
=
sigtimedwait
(
&
waitset
,
&
siginfo
,
&
ts
);
if
(
r
==
-
1
&&
!
(
errno
==
EAGAIN
||
errno
==
EINTR
))
{
perror
(
"sigtimedwait"
);
exit
(
1
);
}
switch
(
r
)
{
case
SIGBUS
:
if
(
kvm_on_sigbus_vcpu
(
env
,
siginfo
.
si_code
,
siginfo
.
si_addr
))
{
sigbus_reraise
();
}
break
;
default:
break
;
}
r
=
sigpending
(
&
chkset
);
if
(
r
==
-
1
)
{
perror
(
"sigpending"
);
exit
(
1
);
}
}
while
(
sigismember
(
&
chkset
,
SIG_IPI
)
||
sigismember
(
&
chkset
,
SIGBUS
));
#ifndef CONFIG_IOTHREAD
if
(
sigismember
(
&
chkset
,
SIGIO
)
||
sigismember
(
&
chkset
,
SIGALRM
))
{
qemu_notify_event
();
}
#endif
}
#else
/* _WIN32 */
HANDLE
qemu_event_handle
;
...
...
@@ -526,10 +510,6 @@ static void qemu_event_increment(void)
}
}
static
void
qemu_kvm_eat_signals
(
CPUState
*
env
)
{
}
static
int
qemu_signal_init
(
void
)
{
return
0
;
...
...
@@ -796,6 +776,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
qemu_mutex_lock
(
&
qemu_global_mutex
);
qemu_thread_get_self
(
env
->
thread
);
env
->
thread_id
=
qemu_get_thread_id
();
r
=
kvm_init_vcpu
(
env
);
if
(
r
<
0
)
{
...
...
@@ -818,7 +799,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
if
(
cpu_can_run
(
env
))
{
r
=
kvm_cpu_exec
(
env
);
if
(
r
==
EXCP_DEBUG
)
{
cpu_handle_
debug_exception
(
env
);
cpu_handle_
guest_debug
(
env
);
}
}
qemu_kvm_wait_io_event
(
env
);
...
...
@@ -837,6 +818,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
/* signal CPU creation */
qemu_mutex_lock
(
&
qemu_global_mutex
);
for
(
env
=
first_cpu
;
env
!=
NULL
;
env
=
env
->
next_cpu
)
{
env
->
thread_id
=
qemu_get_thread_id
();
env
->
created
=
1
;
}
qemu_cond_signal
(
&
qemu_cpu_cond
);
...
...
@@ -1110,7 +1092,7 @@ bool cpu_exec_all(void)
r
=
tcg_cpu_exec
(
env
);
}
if
(
r
==
EXCP_DEBUG
)
{
cpu_handle_
debug_exception
(
env
);
cpu_handle_
guest_debug
(
env
);
break
;
}
}
else
if
(
env
->
stop
||
env
->
stopped
)
{
...
...
exec.c
View file @
31b7c261
...
...
@@ -638,6 +638,9 @@ void cpu_exec_init(CPUState *env)
env
->
numa_node
=
0
;
QTAILQ_INIT
(
&
env
->
breakpoints
);
QTAILQ_INIT
(
&
env
->
watchpoints
);
#ifndef CONFIG_USER_ONLY
env
->
thread_id
=
qemu_get_thread_id
();
#endif
*
penv
=
env
;
#if defined(CONFIG_USER_ONLY)
cpu_list_unlock
();
...
...
@@ -2867,6 +2870,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name,
if
(
host
)
{
new_block
->
host
=
host
;
new_block
->
flags
|=
RAM_PREALLOC_MASK
;
}
else
{
if
(
mem_path
)
{
#if defined (__linux__) && !defined(TARGET_S390X)
...
...
@@ -2920,7 +2924,9 @@ void qemu_ram_free(ram_addr_t addr)
QLIST_FOREACH
(
block
,
&
ram_list
.
blocks
,
next
)
{
if
(
addr
==
block
->
offset
)
{
QLIST_REMOVE
(
block
,
next
);
if
(
mem_path
)
{
if
(
block
->
flags
&
RAM_PREALLOC_MASK
)
{
;
}
else
if
(
mem_path
)
{
#if defined (__linux__) && !defined(TARGET_S390X)
if
(
block
->
fd
)
{
munmap
(
block
->
host
,
block
->
length
);
...
...
@@ -2928,6 +2934,8 @@ void qemu_ram_free(ram_addr_t addr)
}
else
{
qemu_vfree
(
block
->
host
);
}
#else
abort
();
#endif
}
else
{
#if defined(TARGET_S390X) && defined(CONFIG_KVM)
...
...
@@ -2943,6 +2951,66 @@ void qemu_ram_free(ram_addr_t addr)
}
#ifndef _WIN32
void
qemu_ram_remap
(
ram_addr_t
addr
,
ram_addr_t
length
)
{
RAMBlock
*
block
;
ram_addr_t
offset
;
int
flags
;
void
*
area
,
*
vaddr
;
QLIST_FOREACH
(
block
,
&
ram_list
.
blocks
,
next
)
{
offset
=
addr
-
block
->
offset
;
if
(
offset
<
block
->
length
)
{
vaddr
=
block
->
host
+
offset
;
if
(
block
->
flags
&
RAM_PREALLOC_MASK
)
{
;
}
else
{
flags
=
MAP_FIXED
;
munmap
(
vaddr
,
length
);
if
(
mem_path
)
{
#if defined(__linux__) && !defined(TARGET_S390X)
if
(
block
->
fd
)
{
#ifdef MAP_POPULATE
flags
|=
mem_prealloc
?
MAP_POPULATE
|
MAP_SHARED
:
MAP_PRIVATE
;
#else
flags
|=
MAP_PRIVATE
;
#endif
area
=
mmap
(
vaddr
,
length
,
PROT_READ
|
PROT_WRITE
,
flags
,
block
->
fd
,
offset
);
}
else
{
flags
|=
MAP_PRIVATE
|
MAP_ANONYMOUS
;
area
=
mmap
(
vaddr
,
length
,
PROT_READ
|
PROT_WRITE
,
flags
,
-
1
,
0
);
}
#else
abort
();
#endif
}
else
{
#if defined(TARGET_S390X) && defined(CONFIG_KVM)
flags
|=
MAP_SHARED
|
MAP_ANONYMOUS
;
area
=
mmap
(
vaddr
,
length
,
PROT_EXEC
|
PROT_READ
|
PROT_WRITE
,
flags
,
-
1
,
0
);
#else
flags
|=
MAP_PRIVATE
|
MAP_ANONYMOUS
;
area
=
mmap
(
vaddr
,
length
,
PROT_READ
|
PROT_WRITE
,
flags
,
-
1
,
0
);
#endif
}
if
(
area
!=
vaddr
)
{
fprintf
(
stderr
,
"Could not remap addr: %lx@%lx
\n
"
,
length
,
addr
);
exit
(
1
);
}
qemu_madvise
(
vaddr
,
length
,
QEMU_MADV_MERGEABLE
);
}
return
;
}
}
}
#endif
/* !_WIN32 */
/* Return a host pointer to ram allocated with qemu_ram_alloc.
With the exception of the softmmu code in this file, this should
only be used for local memory (e.g. video ram) that the device owns,
...
...
kvm-all.c
View file @
31b7c261
...
...
@@ -211,6 +211,7 @@ int kvm_init_vcpu(CPUState *env)
env
->
kvm_fd
=
ret
;
env
->
kvm_state
=
s
;
env
->
kvm_vcpu_dirty
=
1
;
mmap_size
=
kvm_ioctl
(
s
,
KVM_GET_VCPU_MMAP_SIZE
,
0
);
if
(
mmap_size
<
0
)
{
...
...
@@ -830,7 +831,7 @@ static int kvm_handle_internal_error(CPUState *env, struct kvm_run *run)
fprintf
(
stderr
,
"emulation failure
\n
"
);
if
(
!
kvm_arch_stop_on_emulation_error
(
env
))
{
cpu_dump_state
(
env
,
stderr
,
fprintf
,
CPU_DUMP_CODE
);
return
0
;
return
EXCP_INTERRUPT
;
}
}
/* FIXME: Should trigger a qmp message to let management know
...
...
@@ -889,11 +890,11 @@ void kvm_cpu_synchronize_post_init(CPUState *env)
int
kvm_cpu_exec
(
CPUState
*
env
)
{
struct
kvm_run
*
run
=
env
->
kvm_run
;
int
ret
;
int
ret
,
run_
ret
;
DPRINTF
(
"kvm_cpu_exec()
\n
"
);
if
(
kvm_arch_process_
irqchip
_events
(
env
))
{
if
(
kvm_arch_process_
async
_events
(
env
))
{
env
->
exit_request
=
0
;
return
EXCP_HLT
;
}
...
...
@@ -919,7 +920,7 @@ int kvm_cpu_exec(CPUState *env)
cpu_single_env
=
NULL
;
qemu_mutex_unlock_iothread
();
ret
=
kvm_vcpu_ioctl
(
env
,
KVM_RUN
,
0
);
run_
ret
=
kvm_vcpu_ioctl
(
env
,
KVM_RUN
,
0
);
qemu_mutex_lock_iothread
();
cpu_single_env
=
env
;
...
...
@@ -927,18 +928,16 @@ int kvm_cpu_exec(CPUState *env)
kvm_flush_coalesced_mmio_buffer
();
if
(
ret
==
-
EINTR
||
ret
==
-
EAGAIN
)
{
DPRINTF
(
"io window exit
\n
"
);
ret
=
0
;
break
;
}
if
(
ret
<
0
)
{
DPRINTF
(
"kvm run failed %s
\n
"
,
strerror
(
-
ret
));
if
(
run_ret
<
0
)
{
if
(
run_ret
==
-
EINTR
||
run_ret
==
-
EAGAIN
)
{
DPRINTF
(
"io window exit
\n
"
);
ret
=
EXCP_INTERRUPT
;
break
;
}
DPRINTF
(
"kvm run failed %s
\n
"
,
strerror
(
-
run_ret
));
abort
();
}
ret
=
0
;
/* exit loop */
switch
(
run
->
exit_reason
)
{
case
KVM_EXIT_IO
:
DPRINTF
(
"handle_io
\n
"
);
...
...
@@ -947,7 +946,7 @@ int kvm_cpu_exec(CPUState *env)
run
->
io
.
direction
,
run
->
io
.
size
,
run
->
io
.
count
);
ret
=
1
;
ret
=
0
;
break
;
case
KVM_EXIT_MMIO
:
DPRINTF
(
"handle_mmio
\n
"
);
...
...
@@ -955,14 +954,16 @@ int kvm_cpu_exec(CPUState *env)
run
->
mmio
.
data
,
run
->
mmio
.
len
,
run
->
mmio
.
is_write
);
ret
=
1
;
ret
=
0
;
break
;
case
KVM_EXIT_IRQ_WINDOW_OPEN
:
DPRINTF
(
"irq_window_open
\n
"
);
ret
=
EXCP_INTERRUPT
;
break
;
case
KVM_EXIT_SHUTDOWN
:
DPRINTF
(
"shutdown
\n
"
);
qemu_system_reset_request
();
ret
=
EXCP_INTERRUPT
;
break
;
case
KVM_EXIT_UNKNOWN
:
fprintf
(
stderr
,
"KVM: unknown exit, hardware reason %"
PRIx64
"
\n
"
,
...
...
@@ -974,31 +975,18 @@ int kvm_cpu_exec(CPUState *env)
ret
=
kvm_handle_internal_error
(
env
,
run
);
break
;
#endif
case
KVM_EXIT_DEBUG
:
DPRINTF
(
"kvm_exit_debug
\n
"
);
#ifdef KVM_CAP_SET_GUEST_DEBUG
if
(
kvm_arch_debug
(
&
run
->
debug
.
arch
))
{
ret
=
EXCP_DEBUG
;
goto
out
;
}
/* re-enter, this exception was guest-internal */
ret
=
1
;
#endif
/* KVM_CAP_SET_GUEST_DEBUG */
break
;
default:
DPRINTF
(
"kvm_arch_handle_exit
\n
"
);
ret
=
kvm_arch_handle_exit
(
env
,
run
);
break
;
}
}
while
(
ret
>
0
);
}
while
(
ret
==
0
);
if
(
ret
<
0
)
{
cpu_dump_state
(
env
,
stderr
,
fprintf
,
CPU_DUMP_CODE
);
vm_stop
(
VMSTOP_PANIC
);
}
ret
=
EXCP_INTERRUPT
;
out:
env
->
exit_request
=
0
;
cpu_single_env
=
NULL
;
return
ret
;
...
...
kvm.h
View file @
31b7c261
...
...
@@ -102,7 +102,7 @@ void kvm_arch_post_run(CPUState *env, struct kvm_run *run);
int
kvm_arch_handle_exit
(
CPUState
*
env
,
struct
kvm_run
*
run
);
int
kvm_arch_process_
irqchip
_events
(
CPUState
*
env
);
int
kvm_arch_process_
async
_events
(
CPUState
*
env
);
int
kvm_arch_get_registers
(
CPUState
*
env
);
...
...
@@ -136,8 +136,6 @@ struct kvm_sw_breakpoint {
QTAILQ_HEAD
(
kvm_sw_breakpoint_head
,
kvm_sw_breakpoint
);
int
kvm_arch_debug
(
struct
kvm_debug_exit_arch
*
arch_info
);
struct
kvm_sw_breakpoint
*
kvm_find_sw_breakpoint
(
CPUState
*
env
,
target_ulong
pc
);
...
...
monitor.c
View file @
31b7c261
...
...
@@ -897,6 +897,9 @@ static void print_cpu_iter(QObject *obj, void *opaque)
monitor_printf
(
mon
,
" (halted)"
);
}
monitor_printf
(
mon
,
" thread_id=%"
PRId64
" "
,
qdict_get_int
(
cpu
,
"thread_id"
));
monitor_printf
(
mon
,
"
\n
"
);
}
...
...
@@ -941,6 +944,7 @@ static void do_info_cpus(Monitor *mon, QObject **ret_data)
#elif defined(TARGET_MIPS)
qdict_put
(
cpu
,
"PC"
,
qint_from_int
(
env
->
active_tc
.
PC
));
#endif
qdict_put
(
cpu
,
"thread_id"
,
qint_from_int
(
env
->
thread_id
));
qlist_append
(
cpu_list
,
cpu
);
}
...
...
@@ -2709,12 +2713,15 @@ static void do_inject_mce(Monitor *mon, const QDict *qdict)
uint64_t
mcg_status
=
qdict_get_int
(
qdict
,
"mcg_status"
);
uint64_t
addr
=
qdict_get_int
(
qdict
,
"addr"
);
uint64_t
misc
=
qdict_get_int
(
qdict
,
"misc"
);
int
broadcast
=
qdict_get_try_bool
(
qdict
,
"broadcast"
,
0
)
;
int
flags
=
MCE_INJECT_UNCOND_AO
;
if
(
qdict_get_try_bool
(
qdict
,
"broadcast"
,
0
))
{
flags
|=
MCE_INJECT_BROADCAST
;
}
for
(
cenv
=
first_cpu
;
cenv
!=
NULL
;
cenv
=
cenv
->
next_cpu
)
{
if
(
cenv
->
cpu_index
==
cpu_index
&&
cenv
->
mcg_cap
)
{
cpu_inject_
x86_
mce
(
cenv
,
bank
,
status
,
mcg_status
,
addr
,
misc
,
broadcast
);
if
(
cenv
->
cpu_index
==
cpu_index
)
{
cpu_
x86_
inject_mce
(
mon
,
cenv
,
bank
,
status
,
mcg_status
,
addr
,
misc
,
flags
);
break
;
}
}
...
...
os-posix.c
View file @
31b7c261
...
...
@@ -41,6 +41,7 @@
#ifdef CONFIG_LINUX
#include <sys/prctl.h>
#include <sys/syscall.h>
#endif
#ifdef CONFIG_EVENTFD
...
...
@@ -382,3 +383,12 @@ int qemu_create_pidfile(const char *filename)
return
0
;
}
int
qemu_get_thread_id
(
void
)
{
#if defined (__linux__)
return
syscall
(
SYS_gettid
);
#else
return
getpid
();
#endif
}
os-win32.c
View file @
31b7c261
...
...
@@ -266,3 +266,8 @@ int qemu_create_pidfile(const char *filename)
}
return
0
;
}
int
qemu_get_thread_id
(
void
)
{
return
GetCurrentThreadId
();
}
osdep.h
View file @
31b7c261
...
...
@@ -128,6 +128,7 @@ void qemu_vfree(void *ptr);
int
qemu_madvise
(
void
*
addr
,
size_t
len
,
int
advice
);
int
qemu_create_pidfile
(
const
char
*
filename
);
int
qemu_get_thread_id
(
void
);
#ifdef _WIN32
static
inline
void
qemu_timersub
(
const
struct
timeval
*
val1
,
...
...
qemu-common.h
View file @
31b7c261
...
...
@@ -18,6 +18,9 @@ typedef struct QEMUFile QEMUFile;
typedef
struct
QEMUBH
QEMUBH
;
typedef
struct
DeviceState
DeviceState
;
struct
Monitor
;
typedef
struct
Monitor
Monitor
;
/* we put basic includes here to avoid repeating them in device drivers */
#include <stdlib.h>
#include <stdio.h>
...
...
@@ -327,9 +330,6 @@ void qemu_iovec_memset(QEMUIOVector *qiov, int c, size_t count);
void
qemu_iovec_memset_skip
(
QEMUIOVector
*
qiov
,
int
c
,
size_t
count
,
size_t
skip
);
struct
Monitor
;
typedef
struct
Monitor
Monitor
;
/* Convert a byte between binary and BCD. */
static
inline
uint8_t
to_bcd
(
uint8_t
val
)
{
...
...
qmp-commands.hx
View file @
31b7c261
...
...
@@ -1194,6 +1194,7 @@ Return a json-array. Each CPU is represented by a json-object, which contains:
"nip": PPC (json-int)
"pc" and "npc": sparc (json-int)
"PC": mips (json-int)
- "thread_id": ID of the underlying host thread (json-int)
Example:
...
...
@@ -1205,12 +1206,14 @@ Example:
"current":true,
"halted":false,
"pc":3227107138
"thread_id":3134
},
{
"CPU":1,
"current":false,
"halted":true,
"pc":7108165
"thread_id":3135
}