@@ -167,6 +167,33 @@ void do_run_on_cpu(CPUState *cpu, run_on_cpu_func func, run_on_cpu_data data,
}
}
+void do_run_on_cpu2(CPUState *cpu, run_on_cpu_func2 func2, run_on_cpu_data data,
+ QemuMutex *mutex, Error **errp)
+{
+ struct qemu_work_item wi;
+
+ if (qemu_cpu_is_self(cpu)) {
+ func2(cpu, data, errp);
+ return;
+ }
+
+ wi.func2 = func2;
+ wi.data = data;
+ wi.done = false;
+ wi.free = false;
+ wi.exclusive = false;
+ wi.has_errp = true;
+ wi.errp = errp;
+
+ queue_work_on_cpu(cpu, &wi);
+ while (!qatomic_mb_read(&wi.done)) {
+ CPUState *self_cpu = current_cpu;
+
+ qemu_cond_wait(&qemu_work_cond, mutex);
+ current_cpu = self_cpu;
+ }
+}
+
void async_run_on_cpu(CPUState *cpu, run_on_cpu_func func, run_on_cpu_data data)
{
struct qemu_work_item *wi;
@@ -709,6 +709,19 @@ bool cpu_is_stopped(CPUState *cpu);
void do_run_on_cpu(CPUState *cpu, run_on_cpu_func func, run_on_cpu_data data,
QemuMutex *mutex);
+/**
+ * do_run_on_cpu2:
+ * @cpu: The vCPU to run on.
+ * @func2: The function to be executed.
+ * @data: Data to pass to the function.
+ * @mutex: Mutex to release while waiting for @func2 to run.
+ * @errp: The Error** pointer to be passed into @func2.
+ *
+ * Used internally in the implementation of run_on_cpu2.
+ */
+void do_run_on_cpu2(CPUState *cpu, run_on_cpu_func2 func2, run_on_cpu_data data,
+ QemuMutex *mutex, Error **errp);
+
/**
* run_on_cpu:
* @cpu: The vCPU to run on.
@@ -719,6 +732,19 @@ void do_run_on_cpu(CPUState *cpu, run_on_cpu_func func, run_on_cpu_data data,
*/
void run_on_cpu(CPUState *cpu, run_on_cpu_func func, run_on_cpu_data data);
+/**
+ * run_on_cpu2:
+ * @cpu: The vCPU to run on.
+ * @func: The function to be executed.
+ * @data: Data to pass to the function.
+ * @errp: The Error** pointer to be passed into @func2.
+ *
+ * Schedules the function @func2 for execution on the vCPU @cpu, capture
+ * any error and put it into *@errp when provided.
+ */
+void run_on_cpu2(CPUState *cpu, run_on_cpu_func2 func2, run_on_cpu_data data,
+ Error **errp);
+
/**
* async_run_on_cpu:
* @cpu: The vCPU to run on.
@@ -391,6 +391,12 @@ void run_on_cpu(CPUState *cpu, run_on_cpu_func func, run_on_cpu_data data)
do_run_on_cpu(cpu, func, data, &qemu_global_mutex);
}
+void run_on_cpu2(CPUState *cpu, run_on_cpu_func2 func2, run_on_cpu_data data,
+ Error **errp)
+{
+ do_run_on_cpu2(cpu, func2, data, &qemu_global_mutex, errp);
+}
+
static void qemu_cpu_stop(CPUState *cpu, bool exit)
{
g_assert(qemu_cpu_is_self(cpu));
This version of run_on_cpu() allows to take an Error** to detect errors. Signed-off-by: Peter Xu <peterx@redhat.com> --- cpus-common.c | 27 +++++++++++++++++++++++++++ include/hw/core/cpu.h | 26 ++++++++++++++++++++++++++ softmmu/cpus.c | 6 ++++++ 3 files changed, 59 insertions(+)