Hi Alex,

You mentioned about a patch series; do you have it handy with you?

If so, could you please direct me to the same ?

On 14 Mar 2025, at 12:11 AM, Alex Bennée <alex.ben...@linaro.org> wrote:

Saanjh Sengupta <saanjhsengu...@outlook.com<mailto:saanjhsengu...@outlook.com>> 
writes:

Hi,

What we are trying to achieve is that the QEMU should run for a particular 
number of instructions, let's say for example
10000 instructions and then pause it's emulation. After a resume trigger is 
received to the QEMU it must resume it's
emulation and start the instruction count from 10001 (which basically
means that the context should be saved).

I think you want to run under icount and you will need to modify the
trigger plugin. Under icount we run each vCPU in turn, so if the plugin
pauses the vCPU will de-facto be paused.

You would have to implement some sort of control interface in the
plugin. Or you could add an API to trigger the gdbstub. I think I had
that on a patch series at one point.


In the previous mail when you mentioned g_usleep, I believe this shall not work 
(as per our use-case) since it will reset the
instruction count to 0 (as per what you mentioned).

To achieve the use-case, do you have any leads/suggestions ?

Regards
Saanjh Sengupta

-------------------------------------------------------------------------------------------------------------------------
From: Pierrick Bouvier <pierrick.bouv...@linaro.org>
Sent: Wednesday, March 12, 2025 11:50:23 am
To: Saanjh Sengupta <saanjhsengu...@outlook.com>; Philippe Mathieu-Daudé 
<phi...@linaro.org>; Paolo Bonzini
<pbonz...@redhat.com>; Marc-André Lureau <marcandre.lur...@redhat.com>
Cc: amir.gon...@neuroblade.ai <amir.gon...@neuroblade.ai>; 
qemu-devel@nongnu.org <qemu-devel@nongnu.org>; Alex
Bennée <alex.ben...@linaro.org>
Subject: Re: Building QEMU as a Shared Library

On 3/11/25 21:31, Saanjh Sengupta wrote:


Hi,

Thank you for the clarification. Regarding the last time
/"Stoptrigger might be a better fit for what you want to do, and instead
of exiting, you want to resume emulation after N insn. The function
qemu_clock_advance_virtual_time() can only be used to move the time
forward, and you can not stop the "virtual time" by design."/
/
/
I did not quite understand this. Even if I have to modify the
stopTrigger plugin, I would want it to pause rather than exiting.
For example: It gets 10000 instructions executed after that it should
pause and after some time it should then resume again execute till 20000
instructions (because previously it executed till 10000 and then it must
execute till 20000). How do I do this? How do I state the code to pause
the qemu's emulation after 10000 instructions?


By using g_usleep to pause the current cpu.
As well, it's needed to reset insn_count to 0 to count instructions again.

With this command line:
./build/qemu-system-x86_64 -plugin
./build/contrib/plugins/libstoptrigger.so,icount=1000 -d plugin

And with those changes to stoptrigger:

diff --git a/contrib/plugins/stoptrigger.c b/contrib/plugins/stoptrigger.c
index b3a6ed66a7b..77fd413cef1 100644
--- a/contrib/plugins/stoptrigger.c
+++ b/contrib/plugins/stoptrigger.c
@@ -41,11 +41,12 @@ typedef struct {
     int exit_code;
 } ExitInfo;

-static void exit_emulation(int return_code, char *message)
+static void pause_emulation(int return_code, char *message)
 {
     qemu_plugin_outs(message);
     g_free(message);
-    exit(return_code);
+    /* exit(return_code); */
+    g_usleep(1 * G_USEC_PER_SEC);
 }

 static void exit_icount_reached(unsigned int cpu_index, void *udata)
@@ -53,7 +54,9 @@ static void exit_icount_reached(unsigned int
cpu_index, void *udata)
     uint64_t insn_vaddr = qemu_plugin_u64_get(current_pc, cpu_index);
     char *msg = g_strdup_printf("icount reached at 0x%" PRIx64 ",
exiting\n",
                                 insn_vaddr);
-    exit_emulation(icount_exit_code, msg);
+    pause_emulation(icount_exit_code, msg);
+    /* reset instruction counter */
+    qemu_plugin_u64_set(insn_count, cpu_index, 0);
 }

 static void exit_address_reached(unsigned int cpu_index, void *udata)
@@ -61,7 +64,7 @@ static void exit_address_reached(unsigned int
cpu_index, void *udata)
     ExitInfo *ei = udata;
     g_assert(ei);
     char *msg = g_strdup_printf("0x%" PRIx64 " reached, exiting\n",
ei->exit_addr);
-    exit_emulation(ei->exit_code, msg);
+    pause_emulation(ei->exit_code, msg);
 }

Moreover, I tried an activity where I was utilising the QMP protocol to
control the virtual time (with respect to the IPS plugin). In that
context when the QMP stop is triggered, my virtual time does got freezed
until the resume is triggered. Does this mean I am able to manipulate
the virtual time of the QEMU?


I am not sure of how it works, but the plugin interface only allows to
move time forward.



Regards
Saanjh Sengupta
------------------------------------------------------------------------
*From:* Pierrick Bouvier <pierrick.bouv...@linaro.org>
*Sent:* Wednesday, March 12, 2025 2:14:47 AM
*To:* Saanjh Sengupta <saanjhsengu...@outlook.com>; Philippe Mathieu-
Daudé <phi...@linaro.org>; Paolo Bonzini <pbonz...@redhat.com>; Marc-
André Lureau <marcandre.lur...@redhat.com>
*Cc:* amir.gon...@neuroblade.ai <amir.gon...@neuroblade.ai>; qemu-
de...@nongnu.org <qemu-devel@nongnu.org>; Alex Bennée
<alex.ben...@linaro.org>
*Subject:* Re: Building QEMU as a Shared Library
On 3/11/25 02:50, Saanjh Sengupta wrote:
Hi,

I have a couple of questions:

1.
   When I use the libstoptrigger.so: in that case the QEMU 's emulation
   stops after executing the defined number of instructions. Post this,
   the whole QEMU terminates. And while using the libips.so I am
   assuming that the QEMU doesn't execute no more than the defined
   instructions. Please correct me if I am wrong.

That's correct for both plugins, with the additional note that libips
does this per second only.

2.
   In my case, I want the QEMU to start emulation for some time and
   PAUSE it's emulation for some time; after it is Paused (it's virtual
   time is also to be paused) and then let's say for after 'x' time
   period it should resume it's virtual time.


The virtual time variable in ips plugin is only related to this plugin,
and based on how many instructions have been executed, which is
different from what you want to achieve.

Stoptrigger might be a better fit for what you want to do, and instead
of exiting, you want to resume emulation after N insn.
The function qemu_clock_advance_virtual_time() can only be used to move
the time forward, and you can not stop the "virtual time" by design.

image


I have added this segment inside the update_system_time function inside
the ipsPlugin.c. but once the instructions reach to the defined limit
the virtual time does not seem to stop.
Do you have any suggestions on that front?


Regards
Saanjh Sengupta
------------------------------------------------------------------------
*From:* Pierrick Bouvier <pierrick.bouv...@linaro.org>
*Sent:* Wednesday, March 5, 2025 5:20:38 AM
*To:* Saanjh Sengupta <saanjhsengu...@outlook.com>; Philippe Mathieu-
Daudé <phi...@linaro.org>; Paolo Bonzini <pbonz...@redhat.com>; Marc-
André Lureau <marcandre.lur...@redhat.com>
*Cc:* amir.gon...@neuroblade.ai <amir.gon...@neuroblade.ai>; qemu-
de...@nongnu.org <qemu-devel@nongnu.org>; Alex Bennée
<alex.ben...@linaro.org>
*Subject:* Re: Building QEMU as a Shared Library
Hi Saanjh,

depending what you are trying to achieve exactly, plugins can provide a
solution. It's convenient and you can stay on top of QEMU upstream,
without having to create a downstream fork.

We already have plugins for stopping after a given number of
instructions, or slow down execution of a VM:

# stop after executing 1'000'000 instructions:
$ ./build/qemu-system-x86_64 -plugin
./build/contrib/plugins/libstoptrigger,icount=1000000 -d plugin

# execute no more than 1'000'000 instructions per second:
$ ./build/qemu-system-x86_64 -plugin
./build/contrib/plugins/libips.so,ips=1000000 -d plugin

You can see source code associated (./contrib/plugins/stoptrigger.c and
./contrib/plugins/ips.c), to implement something similar to what you
want, but based on time.
Would that satisfy your need?

Regards,
Pierrick

On 3/3/25 21:53, Saanjh Sengupta wrote:


Hi,

Thank you so much for your inputs. I was able to create the .so file of
QEMU.

Actually, what we are trying is to understand and explore possibilities
of Virtual Time Control in QEMU. In short, what I mean to say is an
approach via which I can tell QEMU to emulate for XYZ time when the I
give a trigger and then pause the emulation by itself after the XYZ time
is completed.

On that front itself, do you have any inputs/ideas regarding the same?


Regards
Saanjh Sengupta
------------------------------------------------------------------------
*From:* Pierrick Bouvier <pierrick.bouv...@linaro.org>
*Sent:* Tuesday, February 25, 2025 6:29:44 AM
*To:* Philippe Mathieu-Daudé <phi...@linaro.org>; Paolo Bonzini
<pbonz...@redhat.com>; Marc-André Lureau <marcandre.lur...@redhat.com>
*Cc:* amir.gon...@neuroblade.ai <amir.gon...@neuroblade.ai>; qemu-
de...@nongnu.org <qemu-devel@nongnu.org>; Saanjh Sengupta
<saanjhsengu...@outlook.com>
*Subject:* Re: Building QEMU as a Shared Library
Hi Saanjh,

here is a minimal patch that builds one shared library per target (arch,
mode) where arch is cpu arch, and mode is system or user, and launch
system-aarch64 through a simple driver:

https://github.com/pbo-linaro/qemu/commit/ <https://github.com/pbo-
linaro/qemu/commit/> <https://github.com/pbo-
linaro/qemu/commit/>
fbb39cc64f77d4bf1e5e50795c75b62735bf5c5f <https://github.com/pbo-linaro/
qemu/commit/fbb39cc64f77d4bf1e5e50795c75b62735bf5c5f>

With this, it could be possible to create a driver that can execute any
existing target. It's a sort of single binary for QEMU, but shared
objects are mandatory, and duplicates all the QEMU state. So there is no
real benefit compared to having different processes.

In more, to be able to do concurrent emulations, there are much more
problems to be solved. QEMU state is correctly kept per target, but all
other libraries states are shared. There are various issues if you
launch two emulations at the same time in two threads:
- glib global context
- qemu calls exit in many places, which stops the whole process
- probably other things I didn't explore

At this point, even though qemu targets can be built as shared objects,
I would recommend to use different processes, and implement some form on
IPC to synchronize all this.
Another possibility is to try to build machines without using the
existing main, but I'm not sure it's worth all the hassle.

What are you trying to achieve?

Regards,
Pierrick

On 2/24/25 01:10, Philippe Mathieu-Daudé wrote:
Cc'ing our meson experts

On 22/2/25 14:36, Saanjh Sengupta wrote:
Hi,

I referred to your mailing chains on suggesting QEMU to be built as a
shared library.

*Change meson.build to build QEMU as a shared library (with PIC enabled
for static libraries)*
*
*
Could you please suggest what exactly has to be enabled in the meson.build?

I am confused on that front.

Regards
Saanjh Sengupta





--
Alex Bennée
Virtualisation Tech Lead @ Linaro

Reply via email to