Skip to content

Commit

Permalink
plugins: add [pre|post]fork helpers to linux-user
Browse files Browse the repository at this point in the history
Special care needs to be taken in ensuring locks are in a consistent
state across fork events. Add helpers so the plugin system can ensure
that.

Signed-off-by: Alex Bennée <[email protected]>
Fixes: https://gitlab.com/qemu-project/qemu/-/issues/358
Reviewed-by: Daniel P. Berrangé <[email protected]>
Tested-by: Daniel P. Berrangé <[email protected]>
Message-Id: <[email protected]>
  • Loading branch information
stsquad committed Oct 6, 2022
1 parent 37e6269 commit f7e15af
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 0 deletions.
24 changes: 24 additions & 0 deletions include/qemu/plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,23 @@ void qemu_plugin_disable_mem_helpers(CPUState *cpu);
*/
void qemu_plugin_user_exit(void);

/**
* qemu_plugin_user_prefork_lock(): take plugin lock before forking
*
* This is a user-mode only helper to take the internal plugin lock
* before a fork event. This is ensure a consistent lock state
*/
void qemu_plugin_user_prefork_lock(void);

/**
* qemu_plugin_user_postfork(): reset the plugin lock
* @is_child: is this thread the child
*
* This user-mode only helper resets the lock state after a fork so we
* can continue using the plugin interface.
*/
void qemu_plugin_user_postfork(bool is_child);

#else /* !CONFIG_PLUGIN */

static inline void qemu_plugin_add_opts(void)
Expand Down Expand Up @@ -287,6 +304,13 @@ static inline void qemu_plugin_disable_mem_helpers(CPUState *cpu)

static inline void qemu_plugin_user_exit(void)
{ }

static inline void qemu_plugin_user_prefork_lock(void)
{ }

static inline void qemu_plugin_user_postfork(bool is_child)
{ }

#endif /* !CONFIG_PLUGIN */

#endif /* QEMU_PLUGIN_H */
2 changes: 2 additions & 0 deletions linux-user/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,12 @@ void fork_start(void)
start_exclusive();
mmap_fork_start();
cpu_list_lock();
qemu_plugin_user_prefork_lock();
}

void fork_end(int child)
{
qemu_plugin_user_postfork(child);
mmap_fork_end(child);
if (child) {
CPUState *cpu, *next_cpu;
Expand Down
20 changes: 20 additions & 0 deletions plugins/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,26 @@ void qemu_plugin_user_exit(void)
qemu_plugin_atexit_cb();
}

/*
* Helpers for *-user to ensure locks are sane across fork() events.
*/

void qemu_plugin_user_prefork_lock(void)
{
qemu_rec_mutex_lock(&plugin.lock);
}

void qemu_plugin_user_postfork(bool is_child)
{
if (is_child) {
/* should we just reset via plugin_init? */
qemu_rec_mutex_init(&plugin.lock);
} else {
qemu_rec_mutex_unlock(&plugin.lock);
}
}


/*
* Call this function after longjmp'ing to the main loop. It's possible that the
* last instruction of a TB might have used helpers, and therefore the
Expand Down

0 comments on commit f7e15af

Please sign in to comment.