All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Alex Bennée" <alex.bennee@linaro.org>
To: Nikolay Igotti <igotti@gmail.com>
Cc: Riku Voipio <riku.voipio@iki.fi>,
	"Emilio G. Cota" <cota@braap.org>,
	Laurent Vivier <laurent@vivier.eu>,
	QEMU Developers <qemu-devel@nongnu.org>
Subject: Re: [PATCH 3/3] plugins: avoid failing plugin when CPU is inited several times
Date: Tue, 12 May 2020 20:35:00 +0100	[thread overview]
Message-ID: <873685eyl7.fsf@linaro.org> (raw)
In-Reply-To: <CAEme+7E+d4Obmc=6bDcZgP5oEx9F57qe9RE2X=iFw+Yo=+i9_A@mail.gmail.com>


Nikolay Igotti <igotti@gmail.com> writes:

> --- counter.c
>
> #include <assert.h>
> #include <pthread.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <unistd.h>
>
> #include <glib.h>
>
> #include <qemu-plugin.h>
>
> QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
>
> // Files with descriptors after this one are intercepted for instruction
> counting marks.
> #define CATCH_BASE 0xcafebabe
>
> static uint64_t insn_count = 0;
> static pthread_t counting = false;
> static pthread_t counting_for = 0;
> static bool on_every_close = false;
>
> static void vcpu_insn_exec_before(unsigned int cpu_index, void *udata)
> {
>     if (counting && pthread_self() == counting_for)
>         insn_count++;
> }
>
> static void vcpu_tb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb)
> {
>     size_t n = qemu_plugin_tb_n_insns(tb);
>     size_t i;
>
>     for (i = 0; i < n; i++) {
>         struct qemu_plugin_insn *insn = qemu_plugin_tb_get_insn(tb, i);
>
>         // TODO: do this call only on first insn in bb.
>         qemu_plugin_register_vcpu_insn_exec_cb(
>             insn, vcpu_insn_exec_before, QEMU_PLUGIN_CB_NO_REGS, NULL);
>     }
> }
>
> static void print_insn_count(void) {
>     g_autofree gchar *out = g_strdup_printf("executed %" PRIu64 "
> instructions\n", insn_count);
>     qemu_plugin_outs(out);
> }
>
> static void vcpu_syscall(qemu_plugin_id_t id, unsigned int vcpu_index,
>                         int64_t num, uint64_t a1, uint64_t a2,
>                         uint64_t a3, uint64_t a4, uint64_t a5,
>                         uint64_t a6, uint64_t a7, uint64_t a8)
> {
>     // We put our listener on fd reads in range [CATCH_BASE, CATCH_BASE + 1]
>     if (num == 0) { // sys_read
>         switch (a1)
>         {
>             case CATCH_BASE + 0:
>                 counting = true;
>                 counting_for = pthread_self();
>                 insn_count = 0;
>                 break;
>             case CATCH_BASE + 1: {
>                 counting = false;
>                 counting_for = 0;
>                 if (a3 == 8) {
>                     // In case of user emulation in QEMU, addresses are 1:1
> translated, so we can tell the caller
>                     // number of executed instructions by just writing into
> the buffer argument of read.
>                     *(uint64_t*)a2 = insn_count;

Hmm this was certainly unintentional - is it the host or guest address
you are messing with here? I wouldn't count on it pointing where you
think and relying on it to pass information back to the instrumented
guest.

Anyway I have a replication - we are trying to insert the same id into
the plugin cpu index hash table twice. 

>                 }
>                 print_insn_count();
>                 break;
>             }
>             default:
>                 break;
>         }
>     }
>     if (num == 3 && on_every_close) { // sys_close
>         print_insn_count();
>     }
> }
>
> QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,
>                                            const qemu_info_t *info,
>                                            int argc, char **argv)
> {
>     int i;
>     for (i = 0; i < argc; i++) {
>         if (!strcmp(argv[i], "on_every_close")) {
>             on_every_close = true;
>             counting = true;
>             counting_for = pthread_self();
>         }
>     }
>
>     qemu_plugin_register_vcpu_tb_trans_cb(id, vcpu_tb_trans);
>     qemu_plugin_register_vcpu_syscall_cb(id, vcpu_syscall);
>     return 0;
> }
>
> --- test.c
>
> #include <stdint.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <unistd.h>
> #include <pthread.h>
>
> #define CATCH_BASE 0xcafebabe
>
> static void start_counting() {
>     char buf;
>     int rv = read(CATCH_BASE, &buf, 1);
>     (void)rv;
> }
>
> static void end_counting() {
>     uint64_t counter = 0;
>     int rv = read(CATCH_BASE + 1, &counter, sizeof(counter));
>     (void)rv;
>     printf("We got %lld from TCG\n", counter);
> }
>
> int global = 0;
>
> typedef struct {
>     int delay;
> } ThreadArg;
>
> static void* thread_fn(void* varg)  {
>     ThreadArg* arg = varg;
>     usleep(arg->delay);
>     free(arg);
>     return NULL;
> }
>
> int main(int argc, char** argv) {
>     int i;
>     int repeat = 100;
> #define THREAD_NUM 10
>     pthread_t threads[THREAD_NUM];
>
>     if (argc > 1) {
>         repeat = atoi(argv[1]);
>     }
>
>     for (i = 0; i < THREAD_NUM; i++) {
>         ThreadArg* arg = calloc(sizeof(ThreadArg), 1);
>         arg->delay = i * 100;
>         pthread_create(threads + i, NULL, thread_fn, arg);
>     }
>
>     start_counting();
>     for (i = 0; i < repeat; i++) {
>         global += i;
>     }
>     end_counting();
>
>     for (i = 0; i < THREAD_NUM; i++) {
>         pthread_join(threads[i], NULL);
>     }
>
>     return 0;
> }
>
> On Tue, May 12, 2020 at 3:55 AM Emilio G. Cota <cota@braap.org> wrote:
>
>> On Mon, May 11, 2020 at 18:53:19 +0300, Nikolay Igotti wrote:
>> > Attached to the mail counter.c when running with attached test.c compiled
>> > to Linux standalone binary shows failing assert, unless the patch is
>> > applied.
>>
>> I didn't get the attachment. Can you paste the code at the end of your
>> reply?
>>
>> Thanks,
>>                 Emilio
>>


-- 
Alex Bennée


  reply	other threads:[~2020-05-12 19:42 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-20  9:15 [PATCH 3/3] plugins: avoid failing plugin when CPU is inited several times Nikolay Igotti
2020-04-20  9:51 ` Laurent Vivier
2020-04-20 10:04   ` Nikolay Igotti
2020-05-09 23:00     ` Emilio G. Cota
2020-05-11 15:53       ` Nikolay Igotti
2020-05-12  0:55         ` Emilio G. Cota
2020-05-12  8:38           ` Nikolay Igotti
2020-05-12 19:35             ` Alex Bennée [this message]
2020-05-12 20:11           ` Alex Bennée
2020-05-24 14:11             ` Emilio G. Cota
2020-04-20 10:11 ` Peter Maydell
2020-04-20 10:18   ` Nikolay Igotti
2020-04-20 10:30     ` Peter Maydell
2020-04-20 15:07   ` Alex Bennée
2020-04-20 16:14     ` Nikolay Igotti

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=873685eyl7.fsf@linaro.org \
    --to=alex.bennee@linaro.org \
    --cc=cota@braap.org \
    --cc=igotti@gmail.com \
    --cc=laurent@vivier.eu \
    --cc=qemu-devel@nongnu.org \
    --cc=riku.voipio@iki.fi \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.