All of lore.kernel.org
 help / color / mirror / Atom feed
* access guest address from within instruction
@ 2022-10-01 20:10 BitFriends
  2022-10-01 20:23 ` Richard Henderson
  2022-10-02 13:56 ` Alex Bennée
  0 siblings, 2 replies; 10+ messages in thread
From: BitFriends @ 2022-10-01 20:10 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 493 bytes --]

Hello,

I am trying to create a custom instruction that accesses guest memory
specified by an address in a register. I specifically want to read from
that address. So I tried to do that using "tcg_gen_qemu_ld_i64(&res,
env->regs[R_EDI], 0, MO_LEUQ);", but that doesn't save any result in res.
So either my call is wrong, or I need to translate that guest address to a
usable host address. I can't find much about this stuff in the docs. Could
anyone help me out with that?

Cheers

BitFriends

[-- Attachment #2: Type: text/html, Size: 627 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: access guest address from within instruction
  2022-10-01 20:10 access guest address from within instruction BitFriends
@ 2022-10-01 20:23 ` Richard Henderson
  2022-10-01 20:59   ` BitFriends
  2022-10-02  9:20   ` BitFriends
  2022-10-02 13:56 ` Alex Bennée
  1 sibling, 2 replies; 10+ messages in thread
From: Richard Henderson @ 2022-10-01 20:23 UTC (permalink / raw)
  To: BitFriends, qemu-devel

On 10/1/22 13:10, BitFriends wrote:
> Hello,
> 
> I am trying to create a custom instruction that accesses guest memory specified by an 
> address in a register. I specifically want to read from that address. So I tried to do 
> that using "tcg_gen_qemu_ld_i64(&res, env->regs[R_EDI], 0, MO_LEUQ);", but that doesn't 
> save any result in res.

This statement should have given you compilation errors, so I don't know what you mean by 
"doesn't save any result".  There's clearly a disconnect between what you describe and 
what you actually attempted.

Anyway, by the name you can see that function "gen"erates a "tcg" operation, which is then 
later compiled by the jit, the output of which is later executed to produce a result. 
Which is, in general, what you want for implementing a custom instruction.


r~


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: access guest address from within instruction
  2022-10-01 20:23 ` Richard Henderson
@ 2022-10-01 20:59   ` BitFriends
  2022-10-02  9:20   ` BitFriends
  1 sibling, 0 replies; 10+ messages in thread
From: BitFriends @ 2022-10-01 20:59 UTC (permalink / raw)
  To: richard.henderson, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 1263 bytes --]

well, it doesn't give errors, but warnings because of unsigned longs being
converted to TCGv_i64, which exact definiton I cannot find in the qemu
repo. Where is it located? When stepping through the instructions' code,
the value that should be read isn't read. Maybe that'll work when fixing
the warnings.

Regards

Am Sa., 1. Okt. 2022 um 22:23 Uhr schrieb Richard Henderson <
richard.henderson@linaro.org>:

> On 10/1/22 13:10, BitFriends wrote:
> > Hello,
> >
> > I am trying to create a custom instruction that accesses guest memory
> specified by an
> > address in a register. I specifically want to read from that address. So
> I tried to do
> > that using "tcg_gen_qemu_ld_i64(&res, env->regs[R_EDI], 0, MO_LEUQ);",
> but that doesn't
> > save any result in res.
>
> This statement should have given you compilation errors, so I don't know
> what you mean by
> "doesn't save any result".  There's clearly a disconnect between what you
> describe and
> what you actually attempted.
>
> Anyway, by the name you can see that function "gen"erates a "tcg"
> operation, which is then
> later compiled by the jit, the output of which is later executed to
> produce a result.
> Which is, in general, what you want for implementing a custom instruction.
>
>
> r~
>

[-- Attachment #2: Type: text/html, Size: 1742 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: access guest address from within instruction
  2022-10-01 20:23 ` Richard Henderson
  2022-10-01 20:59   ` BitFriends
@ 2022-10-02  9:20   ` BitFriends
  2022-10-02 14:40     ` Richard Henderson
  2022-10-02 14:45     ` Peter Maydell
  1 sibling, 2 replies; 10+ messages in thread
From: BitFriends @ 2022-10-02  9:20 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel


[-- Attachment #1.1: Type: text/plain, Size: 1385 bytes --]

I now came up with this code:

TCGv_i64 res = 0;
TCGv_i64 addr = (TCGv_i64)(env->regs[R_EDI]);

tcg_gen_qemu_ld_i64(res, addr, 0, MO_LEUQ);

env->regs[R_EAX] = (target_ulong)res;

However this crashes afterwards in test_bit. Maybe this is caused by an
invalid access? Anything wrong about the code? This still gives some
warnings, like TCGv_i32 expected (and when you use TCGv_i32, it says
TCGv_i64 expected) plus some casting warnings.

Am Sa., 1. Okt. 2022 um 22:23 Uhr schrieb Richard Henderson <
richard.henderson@linaro.org>:

> On 10/1/22 13:10, BitFriends wrote:
> > Hello,
> >
> > I am trying to create a custom instruction that accesses guest memory
> specified by an
> > address in a register. I specifically want to read from that address. So
> I tried to do
> > that using "tcg_gen_qemu_ld_i64(&res, env->regs[R_EDI], 0, MO_LEUQ);",
> but that doesn't
> > save any result in res.
>
> This statement should have given you compilation errors, so I don't know
> what you mean by
> "doesn't save any result".  There's clearly a disconnect between what you
> describe and
> what you actually attempted.
>
> Anyway, by the name you can see that function "gen"erates a "tcg"
> operation, which is then
> later compiled by the jit, the output of which is later executed to
> produce a result.
> Which is, in general, what you want for implementing a custom instruction.
>
>
> r~
>

[-- Attachment #1.2: Type: text/html, Size: 1890 bytes --]

[-- Attachment #2: bt --]
[-- Type: application/octet-stream, Size: 1328 bytes --]

#0  0x0000555555b55c9d in test_bit (addr=0x7ffff5fae520, nr=0xb6db6db6db6db6cb) at /pwd/my_fuzzer/tools/qemu-7.1.0/include/qemu/bitops.h:135
#1  init_ts_info (ctx=ctx@entry=0x7ffff5fae510, ts=0x7fffec000b60) at ../tcg/optimize.c:152
#2  0x0000555555b563bd in init_arguments (nb_args=<optimized out>, op=0x7fffec00ad38, ctx=0x7ffff5fae510) at ../tcg/optimize.c:671
#3  tcg_optimize (s=s@entry=0x7fffec000b60) at ../tcg/optimize.c:2054
#4  0x0000555555b61045 in tcg_gen_code (s=0x7fffec000b60, tb=tb@entry=0x7fffa9c90140 <code_gen_buffer+29950227>) at ../tcg/tcg.c:4254
#5  0x0000555555ba0e7e in tb_gen_code (cpu=cpu@entry=0x555556849010, pc=pc@entry=0x401cb5, cs_base=cs_base@entry=0x0, flags=flags@entry=0xc0c2b3, cflags=0xff080000) at3
#6  0x0000555555b9aae5 in cpu_exec (cpu=cpu@entry=0x555556849010) at ../accel/tcg/cpu-exec.c:982
#7  0x0000555555bb9d84 in tcg_cpus_exec (cpu=cpu@entry=0x555556849010) at ../accel/tcg/tcg-accel-ops.c:67
#8  0x0000555555bb9ef3 in mttcg_cpu_thread_fn (arg=arg@entry=0x555556849010) at ../accel/tcg/tcg-accel-ops-mttcg.c:97
#9  0x0000555555d18113 in qemu_thread_start (args=<optimized out>) at ../util/qemu-thread-posix.c:504
#10 0x00007ffff7992609 in start_thread (arg=<optimized out>) at pthread_create.c:477
#11 0x00007ffff78b5133 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: access guest address from within instruction
  2022-10-01 20:10 access guest address from within instruction BitFriends
  2022-10-01 20:23 ` Richard Henderson
@ 2022-10-02 13:56 ` Alex Bennée
  1 sibling, 0 replies; 10+ messages in thread
From: Alex Bennée @ 2022-10-02 13:56 UTC (permalink / raw)
  To: BitFriends; +Cc: qemu-devel


BitFriends <commandspider12@gmail.com> writes:

> Hello,
>
> I am trying to create a custom instruction that accesses guest memory specified by an address in a register. I specifically
> want to read from that address. So I tried to do that using "tcg_gen_qemu_ld_i64(&res, env->regs[R_EDI], 0,
> MO_LEUQ);", but that doesn't save any result in res. So either my call is wrong, or I need to translate that guest address
> to a usable host address. I can't find much about this stuff in the
> docs. Could anyone help me out with that?

I still think you could solve your problem using semihosting (which
exactly exposes a "fake" instruction to make semihosting calls to save
data on the host system).

>
> Cheers
>
> BitFriends


-- 
Alex Bennée


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: access guest address from within instruction
  2022-10-02  9:20   ` BitFriends
@ 2022-10-02 14:40     ` Richard Henderson
  2022-10-02 14:52       ` BitFriends
  2022-10-02 14:45     ` Peter Maydell
  1 sibling, 1 reply; 10+ messages in thread
From: Richard Henderson @ 2022-10-02 14:40 UTC (permalink / raw)
  To: BitFriends, qemu-devel

On 10/2/22 02:20, BitFriends wrote:
> I now came up with this code:
> 
> TCGv_i64 res = 0;
> TCGv_i64 addr = (TCGv_i64)(env->regs[R_EDI]);
> 
> tcg_gen_qemu_ld_i64(res, addr, 0, MO_LEUQ);
> 
> env->regs[R_EAX] = (target_ulong)res;
> 
> However this crashes afterwards in test_bit. Maybe this is caused by an invalid access? 
> Anything wrong about the code? This still gives some warnings, like TCGv_i32 expected (and 
> when you use TCGv_i32, it says TCGv_i64 expected) plus some casting warnings.

It is as if you did not read the second paragraph of my response at all.
tcg_gen_qemu_ld_i64 is for generating code, not performing a direct action.
Can you see how your code differs from *all* of the code around it?

r~

> 
> Am Sa., 1. Okt. 2022 um 22:23 Uhr schrieb Richard Henderson <richard.henderson@linaro.org 
> <mailto:richard.henderson@linaro.org>>:
> 
>     On 10/1/22 13:10, BitFriends wrote:
>      > Hello,
>      >
>      > I am trying to create a custom instruction that accesses guest memory specified by an
>      > address in a register. I specifically want to read from that address. So I tried to do
>      > that using "tcg_gen_qemu_ld_i64(&res, env->regs[R_EDI], 0, MO_LEUQ);", but that
>     doesn't
>      > save any result in res.
> 
>     This statement should have given you compilation errors, so I don't know what you mean by
>     "doesn't save any result".  There's clearly a disconnect between what you describe and
>     what you actually attempted.
> 
>     Anyway, by the name you can see that function "gen"erates a "tcg" operation, which is
>     then
>     later compiled by the jit, the output of which is later executed to produce a result.
>     Which is, in general, what you want for implementing a custom instruction.
> 
> 
>     r~
> 



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: access guest address from within instruction
  2022-10-02  9:20   ` BitFriends
  2022-10-02 14:40     ` Richard Henderson
@ 2022-10-02 14:45     ` Peter Maydell
  2022-10-02 14:57       ` BitFriends
  1 sibling, 1 reply; 10+ messages in thread
From: Peter Maydell @ 2022-10-02 14:45 UTC (permalink / raw)
  To: BitFriends; +Cc: Richard Henderson, qemu-devel

On Sun, 2 Oct 2022 at 10:22, BitFriends <commandspider12@gmail.com> wrote:
> I now came up with this code:
>
> TCGv_i64 res = 0;
> TCGv_i64 addr = (TCGv_i64)(env->regs[R_EDI]);
>
> tcg_gen_qemu_ld_i64(res, addr, 0, MO_LEUQ);
>
> env->regs[R_EAX] = (target_ulong)res;

This is wrong, because you cannot read or write env->regs[] at
translate time. The "translate time" vs "run time" distinction
in a JIT is critical to understand:

 * translate time is when we read guest instructions,
   and output TCG ops. We do this once, the first time
   we encounter a particular piece of guest code. At
   this point you cannot directly access the state of the
   guest CPU. This is because the exact value of EDI
   will be *different* each time the generated code is run.
 * run time is when we are actually emulating the guest
   CPU, by executing the code built from the TCG ops.
   At run time the CPU state is known and can be updated.

You should look at how existing instructions in the x86
translator generate code to read and write registers --
you will see that they use cpu_regs[], which is an array
of TCGv which correspond to the CPU registers (so they can
say "generate code which will read EDI"), and they
never use env->regs[] (which would be "read EDI right now").

More generally, "read guest memory and get the result into
a guest CPU register" is a common thing in existing x86
instructions. So find how we implement one of those
existing insns that's similar to what you want, and see
how that is handled.

(NB: so far you haven't said why your custom instruction
would be any different from a normal load instruction
that x86 already has...)

thanks
-- PMM


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: access guest address from within instruction
  2022-10-02 14:40     ` Richard Henderson
@ 2022-10-02 14:52       ` BitFriends
  2022-10-02 17:13         ` Richard Henderson
  0 siblings, 1 reply; 10+ messages in thread
From: BitFriends @ 2022-10-02 14:52 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 2321 bytes --]

my bad, then I was mislead by "Which is, in general, what you want for
implementing a custom instruction". Also the code around me is full of gen
instructions, so I thought that's what I should use.

So, when reading the doc I found out about the cpu_{ld,st}*_mmu functions.
That sounds more what I want for a direct action, No?

Regards

BitFriends

Richard Henderson <richard.henderson@linaro.org> schrieb am So., 2. Okt.
2022, 16:40:

> On 10/2/22 02:20, BitFriends wrote:
> > I now came up with this code:
> >
> > TCGv_i64 res = 0;
> > TCGv_i64 addr = (TCGv_i64)(env->regs[R_EDI]);
> >
> > tcg_gen_qemu_ld_i64(res, addr, 0, MO_LEUQ);
> >
> > env->regs[R_EAX] = (target_ulong)res;
> >
> > However this crashes afterwards in test_bit. Maybe this is caused by an
> invalid access?
> > Anything wrong about the code? This still gives some warnings, like
> TCGv_i32 expected (and
> > when you use TCGv_i32, it says TCGv_i64 expected) plus some casting
> warnings.
>
> It is as if you did not read the second paragraph of my response at all.
> tcg_gen_qemu_ld_i64 is for generating code, not performing a direct action.
> Can you see how your code differs from *all* of the code around it?
>
> r~
>
> >
> > Am Sa., 1. Okt. 2022 um 22:23 Uhr schrieb Richard Henderson <
> richard.henderson@linaro.org
> > <mailto:richard.henderson@linaro.org>>:
> >
> >     On 10/1/22 13:10, BitFriends wrote:
> >      > Hello,
> >      >
> >      > I am trying to create a custom instruction that accesses guest
> memory specified by an
> >      > address in a register. I specifically want to read from that
> address. So I tried to do
> >      > that using "tcg_gen_qemu_ld_i64(&res, env->regs[R_EDI], 0,
> MO_LEUQ);", but that
> >     doesn't
> >      > save any result in res.
> >
> >     This statement should have given you compilation errors, so I don't
> know what you mean by
> >     "doesn't save any result".  There's clearly a disconnect between
> what you describe and
> >     what you actually attempted.
> >
> >     Anyway, by the name you can see that function "gen"erates a "tcg"
> operation, which is
> >     then
> >     later compiled by the jit, the output of which is later executed to
> produce a result.
> >     Which is, in general, what you want for implementing a custom
> instruction.
> >
> >
> >     r~
> >
>
>

[-- Attachment #2: Type: text/html, Size: 3423 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: access guest address from within instruction
  2022-10-02 14:45     ` Peter Maydell
@ 2022-10-02 14:57       ` BitFriends
  0 siblings, 0 replies; 10+ messages in thread
From: BitFriends @ 2022-10-02 14:57 UTC (permalink / raw)
  To: Peter Maydell, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 2013 bytes --]

thanks for the clarification, I will look at those insns. My instruction is
for some more advanced logging between guest and host, that should be done
quickly.

Regards

BitFriends

Peter Maydell <peter.maydell@linaro.org> schrieb am So., 2. Okt. 2022,
16:45:

> On Sun, 2 Oct 2022 at 10:22, BitFriends <commandspider12@gmail.com> wrote:
> > I now came up with this code:
> >
> > TCGv_i64 res = 0;
> > TCGv_i64 addr = (TCGv_i64)(env->regs[R_EDI]);
> >
> > tcg_gen_qemu_ld_i64(res, addr, 0, MO_LEUQ);
> >
> > env->regs[R_EAX] = (target_ulong)res;
>
> This is wrong, because you cannot read or write env->regs[] at
> translate time. The "translate time" vs "run time" distinction
> in a JIT is critical to understand:
>
>  * translate time is when we read guest instructions,
>    and output TCG ops. We do this once, the first time
>    we encounter a particular piece of guest code. At
>    this point you cannot directly access the state of the
>    guest CPU. This is because the exact value of EDI
>    will be *different* each time the generated code is run.
>  * run time is when we are actually emulating the guest
>    CPU, by executing the code built from the TCG ops.
>    At run time the CPU state is known and can be updated.
>
> You should look at how existing instructions in the x86
> translator generate code to read and write registers --
> you will see that they use cpu_regs[], which is an array
> of TCGv which correspond to the CPU registers (so they can
> say "generate code which will read EDI"), and they
> never use env->regs[] (which would be "read EDI right now").
>
> More generally, "read guest memory and get the result into
> a guest CPU register" is a common thing in existing x86
> instructions. So find how we implement one of those
> existing insns that's similar to what you want, and see
> how that is handled.
>
> (NB: so far you haven't said why your custom instruction
> would be any different from a normal load instruction
> that x86 already has...)
>
> thanks
> -- PMM
>

[-- Attachment #2: Type: text/html, Size: 2702 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: access guest address from within instruction
  2022-10-02 14:52       ` BitFriends
@ 2022-10-02 17:13         ` Richard Henderson
  0 siblings, 0 replies; 10+ messages in thread
From: Richard Henderson @ 2022-10-02 17:13 UTC (permalink / raw)
  To: BitFriends, qemu-devel

On 10/2/22 07:52, BitFriends wrote:
> my bad, then I was mislead by "Which is, in general, what you want for implementing a 
> custom instruction". Also the code around me is full of gen instructions, so I thought 
> that's what I should use.
> 
> So, when reading the doc I found out about the cpu_{ld,st}*_mmu functions. That sounds 
> more what I want for a direct action, No?

That all depends on where you're putting the code.  Based on what you've written so far, 
I'd guess the answer is still no.  But you haven't been overly verbose about what you're 
trying to do.


r~

> 
> Regards
> 
> BitFriends
> 
> Richard Henderson <richard.henderson@linaro.org <mailto:richard.henderson@linaro.org>> 
> schrieb am So., 2. Okt. 2022, 16:40:
> 
>     On 10/2/22 02:20, BitFriends wrote:
>      > I now came up with this code:
>      >
>      > TCGv_i64 res = 0;
>      > TCGv_i64 addr = (TCGv_i64)(env->regs[R_EDI]);
>      >
>      > tcg_gen_qemu_ld_i64(res, addr, 0, MO_LEUQ);
>      >
>      > env->regs[R_EAX] = (target_ulong)res;
>      >
>      > However this crashes afterwards in test_bit. Maybe this is caused by an invalid
>     access?
>      > Anything wrong about the code? This still gives some warnings, like TCGv_i32
>     expected (and
>      > when you use TCGv_i32, it says TCGv_i64 expected) plus some casting warnings.
> 
>     It is as if you did not read the second paragraph of my response at all.
>     tcg_gen_qemu_ld_i64 is for generating code, not performing a direct action.
>     Can you see how your code differs from *all* of the code around it?
> 
>     r~
> 
>      >
>      > Am Sa., 1. Okt. 2022 um 22:23 Uhr schrieb Richard Henderson
>     <richard.henderson@linaro.org <mailto:richard.henderson@linaro.org>
>      > <mailto:richard.henderson@linaro.org <mailto:richard.henderson@linaro.org>>>:
>      >
>      >     On 10/1/22 13:10, BitFriends wrote:
>      >      > Hello,
>      >      >
>      >      > I am trying to create a custom instruction that accesses guest memory
>     specified by an
>      >      > address in a register. I specifically want to read from that address. So I
>     tried to do
>      >      > that using "tcg_gen_qemu_ld_i64(&res, env->regs[R_EDI], 0, MO_LEUQ);", but that
>      >     doesn't
>      >      > save any result in res.
>      >
>      >     This statement should have given you compilation errors, so I don't know what
>     you mean by
>      >     "doesn't save any result".  There's clearly a disconnect between what you
>     describe and
>      >     what you actually attempted.
>      >
>      >     Anyway, by the name you can see that function "gen"erates a "tcg" operation,
>     which is
>      >     then
>      >     later compiled by the jit, the output of which is later executed to produce a
>     result.
>      >     Which is, in general, what you want for implementing a custom instruction.
>      >
>      >
>      >     r~
>      >
> 



^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2022-10-02 17:16 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-01 20:10 access guest address from within instruction BitFriends
2022-10-01 20:23 ` Richard Henderson
2022-10-01 20:59   ` BitFriends
2022-10-02  9:20   ` BitFriends
2022-10-02 14:40     ` Richard Henderson
2022-10-02 14:52       ` BitFriends
2022-10-02 17:13         ` Richard Henderson
2022-10-02 14:45     ` Peter Maydell
2022-10-02 14:57       ` BitFriends
2022-10-02 13:56 ` Alex Bennée

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.