Skip to content

Commit

Permalink
bsd-user: Sync fork_start/fork_end with linux-user
Browse files Browse the repository at this point in the history
This reorders some of the calls, deduplicates code between branches and,
most importantly, fixes a double end_exclusive call in the parent that
will cause exclusive_context_count to go negative.

Signed-off-by: Jessica Clarke <[email protected]>
Pull-Request: qemu-bsd-user/qemu-bsd-user#52
Reviewed-by: Warner Losh <[email protected]>
Signed-off-by: Warner Losh <[email protected]>
Reviewed-by: Richard Henderson <[email protected]>
  • Loading branch information
jrtc27 authored and bsdimp committed Jul 23, 2024
1 parent b314fd0 commit 5b6828d
Showing 1 changed file with 14 additions and 12 deletions.
26 changes: 14 additions & 12 deletions bsd-user/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "qemu/path.h"
#include "qemu/help_option.h"
#include "qemu/module.h"
#include "qemu/plugin.h"
#include "exec/exec-all.h"
#include "user/guest-base.h"
#include "tcg/startup.h"
Expand Down Expand Up @@ -103,40 +104,41 @@ unsigned long target_sgrowsiz = TARGET_SGROWSIZ; /* amount to grow stack */
void fork_start(void)
{
start_exclusive();
cpu_list_lock();
mmap_fork_start();
cpu_list_lock();
qemu_plugin_user_prefork_lock();
gdbserver_fork_start();
}

void fork_end(pid_t pid)
{
bool child = pid == 0;

qemu_plugin_user_postfork(child);
mmap_fork_end(child);
if (child) {
CPUState *cpu, *next_cpu;
/*
* Child processes created by fork() only have a single thread. Discard
* information about the parent threads.
* Child processes created by fork() only have a single thread.
* Discard information about the parent threads.
*/
CPU_FOREACH_SAFE(cpu, next_cpu) {
if (cpu != thread_cpu) {
QTAILQ_REMOVE_RCU(&cpus_queue, cpu, node);
}
}
mmap_fork_end(child);
/*
* qemu_init_cpu_list() takes care of reinitializing the exclusive
* state, so we don't need to end_exclusive() here.
*/
qemu_init_cpu_list();
get_task_state(thread_cpu)->ts_tid = qemu_get_thread_id();
gdbserver_fork_end(thread_cpu, pid);
} else {
mmap_fork_end(child);
cpu_list_unlock();
gdbserver_fork_end(thread_cpu, pid);
end_exclusive();
}
gdbserver_fork_end(thread_cpu, pid);
/*
* qemu_init_cpu_list() reinitialized the child exclusive state, but we
* also need to keep current_cpu consistent, so call end_exclusive() for
* both child and parent.
*/
end_exclusive();
}

void cpu_loop(CPUArchState *env)
Expand Down

0 comments on commit 5b6828d

Please sign in to comment.