All of lore.kernel.org
 help / color / mirror / Atom feed
* Plugin Register Accesses
@ 2020-12-07 21:03 Aaron Lindsay
  2020-12-08 12:17 ` Alex Bennée
  0 siblings, 1 reply; 10+ messages in thread
From: Aaron Lindsay @ 2020-12-07 21:03 UTC (permalink / raw)
  To: qemu-devel; +Cc: cota, alex.bennee, richard.henderson

I'm trying to migrate to using the new plugin interface. I see the
following in include/qemu/qemu-plugin.h:

> enum qemu_plugin_cb_flags {
>     QEMU_PLUGIN_CB_NO_REGS, /* callback does not access the CPU's regs */
>     QEMU_PLUGIN_CB_R_REGS,  /* callback reads the CPU's regs */
>     QEMU_PLUGIN_CB_RW_REGS, /* callback reads and writes the CPU's regs */
> };

But I don't see a way to access registers in callbacks. Am I missing
something?

-Aaron


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

* Re: Plugin Register Accesses
  2020-12-07 21:03 Plugin Register Accesses Aaron Lindsay
@ 2020-12-08 12:17 ` Alex Bennée
  2020-12-08 14:46   ` Aaron Lindsay via
  0 siblings, 1 reply; 10+ messages in thread
From: Alex Bennée @ 2020-12-08 12:17 UTC (permalink / raw)
  To: Aaron Lindsay; +Cc: cota, richard.henderson, qemu-devel


Aaron Lindsay <aaron@os.amperecomputing.com> writes:

> I'm trying to migrate to using the new plugin interface. I see the
> following in include/qemu/qemu-plugin.h:
>
>> enum qemu_plugin_cb_flags {
>>     QEMU_PLUGIN_CB_NO_REGS, /* callback does not access the CPU's regs */
>>     QEMU_PLUGIN_CB_R_REGS,  /* callback reads the CPU's regs */
>>     QEMU_PLUGIN_CB_RW_REGS, /* callback reads and writes the CPU's regs */
>> };
>
> But I don't see a way to access registers in callbacks. Am I missing
> something?

No - while those symbols do inform the TCG to not try and optimise
the register file we don't yet have an API for the plugins for reading
(or writing) the CPU registers.

There has been discussion about this before, I'll quote what I said
off-list to someone else who asked:

  > Has there been any clarification or softening of the position that 
  > exposing register and memory contents to the QEMU plugin would provide a 
  > way to circumvent the GPL of QEMU?

  I don't think implementing read only access would be a problem and
  should probably be a first step anyway.

  For registers I think there needs to be some re-factoring of QEMU's
  internals to do it cleanly. Currently we have each front-end providing
  hooks to the gdbstub as well as building up their own regid and xml to
  be consumed by it. We probably want a architectural neutral central
  repository that the front ends can register their registers (sic) and
  helpers with. This would then provide hooks for gdbstub to cleanly
  generate XML as well as an interface point for the plugin infrastructure
  (and probably whatever the HMP uses as well).

  Memory is a little trickier because you can't know at any point if a
  given virtual address is actually mapped to real memory. The safest way
  would be to extend the existing memory tracking code to save the values
  saved/loaded from a given address. However if you had register access
  you could probably achieve the same thing after the fact by examining
  the opcode and pulling the values from the registers.


>
> -Aaron


-- 
Alex Bennée


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

* Re: Plugin Register Accesses
  2020-12-08 12:17 ` Alex Bennée
@ 2020-12-08 14:46   ` Aaron Lindsay via
  2020-12-08 17:56     ` Alex Bennée
  0 siblings, 1 reply; 10+ messages in thread
From: Aaron Lindsay via @ 2020-12-08 14:46 UTC (permalink / raw)
  To: Alex Bennée; +Cc: qemu-devel, cota, richard.henderson

On Dec 08 12:17, Alex Bennée wrote:
> Aaron Lindsay <aaron@os.amperecomputing.com> writes:
> 
> > I'm trying to migrate to using the new plugin interface. I see the
> > following in include/qemu/qemu-plugin.h:
> >
> >> enum qemu_plugin_cb_flags {
> >>     QEMU_PLUGIN_CB_NO_REGS, /* callback does not access the CPU's regs */
> >>     QEMU_PLUGIN_CB_R_REGS,  /* callback reads the CPU's regs */
> >>     QEMU_PLUGIN_CB_RW_REGS, /* callback reads and writes the CPU's regs */
> >> };
> >
> > But I don't see a way to access registers in callbacks. Am I missing
> > something?
> 
> No - while those symbols do inform the TCG to not try and optimise
> the register file we don't yet have an API for the plugins for reading
> (or writing) the CPU registers.
> 
> There has been discussion about this before, I'll quote what I said
> off-list to someone else who asked:
> 
>   > Has there been any clarification or softening of the position that 
>   > exposing register and memory contents to the QEMU plugin would provide a 
>   > way to circumvent the GPL of QEMU?
> 
>   I don't think implementing read only access would be a problem and
>   should probably be a first step anyway.

That seems reasonable to me. For the time being, at least, I am most
interested in read-only access.

>   For registers I think there needs to be some re-factoring of QEMU's
>   internals to do it cleanly. Currently we have each front-end providing
>   hooks to the gdbstub as well as building up their own regid and xml to
>   be consumed by it. We probably want a architectural neutral central
>   repository that the front ends can register their registers (sic) and
>   helpers with. This would then provide hooks for gdbstub to cleanly
>   generate XML as well as an interface point for the plugin infrastructure
>   (and probably whatever the HMP uses as well).

In a previous incarnation, I was proxying calls to the plugin API
directly through to gdb_read_register() in gdbstub.c and therefore using
gdb as the point of commonality. I'm not saying it's ideal but... it
works? One downside is that you have to know 'out-of-band' which integer
value corresponds to the register you want to query for your
architecture, though it hasn't been a significant issue for me.

>   Memory is a little trickier because you can't know at any point if a
>   given virtual address is actually mapped to real memory. The safest way
>   would be to extend the existing memory tracking code to save the values
>   saved/loaded from a given address. However if you had register access
>   you could probably achieve the same thing after the fact by examining
>   the opcode and pulling the values from the registers.

What if memory reads were requested by `qemu_plugin_hwaddr` instead of
by virtual address? `qemu_plugin_get_hwaddr()` is already exposed, and I
would expect being able to successfully get a `qemu_plugin_hwaddr` in a
callback would mean it is currently mapped. Am I overlooking something?

I think I might actually prefer a plugin memory access interface be in
the physical address space - it seems like it might allow you to get
more mileage out of one interface without having to support accesses by
virtual and physical address separately.

Or, even if that won't work for whatever reason, it seems reasonable for
a plugin call accessing memory by virtual address to fail in the case
where it's not mapped. As long as that failure case is well-documented
and easy to distinguish from others within a plugin, why not?

-Aaron


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

* Re: Plugin Register Accesses
  2020-12-08 14:46   ` Aaron Lindsay via
@ 2020-12-08 17:56     ` Alex Bennée
  2020-12-08 19:44       ` Aaron Lindsay via
  2020-12-08 19:49       ` Aaron Lindsay via
  0 siblings, 2 replies; 10+ messages in thread
From: Alex Bennée @ 2020-12-08 17:56 UTC (permalink / raw)
  To: Aaron Lindsay; +Cc: cota, richard.henderson, qemu-devel


Aaron Lindsay <aaron@os.amperecomputing.com> writes:

> On Dec 08 12:17, Alex Bennée wrote:
>> Aaron Lindsay <aaron@os.amperecomputing.com> writes:
>> 
>> > I'm trying to migrate to using the new plugin interface. I see the
>> > following in include/qemu/qemu-plugin.h:
>> >
>> >> enum qemu_plugin_cb_flags {
>> >>     QEMU_PLUGIN_CB_NO_REGS, /* callback does not access the CPU's regs */
>> >>     QEMU_PLUGIN_CB_R_REGS,  /* callback reads the CPU's regs */
>> >>     QEMU_PLUGIN_CB_RW_REGS, /* callback reads and writes the CPU's regs */
>> >> };
>> >
>> > But I don't see a way to access registers in callbacks. Am I missing
>> > something?
>> 
>> No - while those symbols do inform the TCG to not try and optimise
>> the register file we don't yet have an API for the plugins for reading
>> (or writing) the CPU registers.
>> 
>> There has been discussion about this before, I'll quote what I said
>> off-list to someone else who asked:
>> 
>>   > Has there been any clarification or softening of the position that 
>>   > exposing register and memory contents to the QEMU plugin would provide a 
>>   > way to circumvent the GPL of QEMU?
>> 
>>   I don't think implementing read only access would be a problem and
>>   should probably be a first step anyway.
>
> That seems reasonable to me. For the time being, at least, I am most
> interested in read-only access.
>
>>   For registers I think there needs to be some re-factoring of QEMU's
>>   internals to do it cleanly. Currently we have each front-end providing
>>   hooks to the gdbstub as well as building up their own regid and xml to
>>   be consumed by it. We probably want a architectural neutral central
>>   repository that the front ends can register their registers (sic) and
>>   helpers with. This would then provide hooks for gdbstub to cleanly
>>   generate XML as well as an interface point for the plugin infrastructure
>>   (and probably whatever the HMP uses as well).
>
> In a previous incarnation, I was proxying calls to the plugin API
> directly through to gdb_read_register() in gdbstub.c and therefore using
> gdb as the point of commonality. I'm not saying it's ideal but... it
> works? One downside is that you have to know 'out-of-band' which integer
> value corresponds to the register you want to query for your
> architecture, though it hasn't been a significant issue for me.

Certainly workable for a private branch but I don't want to merge
anything like that upstream. As far as I can see there are a number of
consumers of register information:

  - plugins
  - gdbstub
  - monitor (info registers)
  - -d LOG_CPU logging

so rather than have them all have their hooks into every front-end I can
see a case for consolidation.

For the plugin case providing an introspection helper to get a handle on
the register makes sense and would be less painful than teachning
plugins about gdb regids which can and do move around with new system
registers.

  qemu_plugin_reg_t *handle = qemu_plugin_find_register("x2")

if we document the handle as usable across calls this can be done on
start-up. Then it would be:

  uint64_t val = qemu_plugin_read_register(cpu_index, handle);

>>   Memory is a little trickier because you can't know at any point if a
>>   given virtual address is actually mapped to real memory. The safest way
>>   would be to extend the existing memory tracking code to save the values
>>   saved/loaded from a given address. However if you had register access
>>   you could probably achieve the same thing after the fact by examining
>>   the opcode and pulling the values from the registers.
>
> What if memory reads were requested by `qemu_plugin_hwaddr` instead of
> by virtual address? `qemu_plugin_get_hwaddr()` is already exposed, and I
> would expect being able to successfully get a `qemu_plugin_hwaddr` in a
> callback would mean it is currently mapped. Am I overlooking
> something?

We can't re-run the transaction - there may have been a change to the
memory layout that instruction caused (see tlb_plugin_lookup and the
interaction with io_writex). However I think we can expand the options
for memory instrumentation to cache the read or written value.

> I think I might actually prefer a plugin memory access interface be in
> the physical address space - it seems like it might allow you to get
> more mileage out of one interface without having to support accesses by
> virtual and physical address separately.
>
> Or, even if that won't work for whatever reason, it seems reasonable for
> a plugin call accessing memory by virtual address to fail in the case
> where it's not mapped. As long as that failure case is well-documented
> and easy to distinguish from others within a plugin, why not?

Hmmm I'm not sure - I don't want to expose internal implementation
details to the plugins because we don't want plugins to rely on them.

>
> -Aaron


-- 
Alex Bennée


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

* Re: Plugin Register Accesses
  2020-12-08 17:56     ` Alex Bennée
@ 2020-12-08 19:44       ` Aaron Lindsay via
  2020-12-30 21:12         ` Aaron Lindsay via
  2020-12-08 19:49       ` Aaron Lindsay via
  1 sibling, 1 reply; 10+ messages in thread
From: Aaron Lindsay via @ 2020-12-08 19:44 UTC (permalink / raw)
  To: Alex Bennée; +Cc: qemu-devel, cota, richard.henderson

On Dec 08 17:56, Alex Bennée wrote:
> Aaron Lindsay <aaron@os.amperecomputing.com> writes:
> > On Dec 08 12:17, Alex Bennée wrote:
> >> Aaron Lindsay <aaron@os.amperecomputing.com> writes:
> >>   Memory is a little trickier because you can't know at any point if a
> >>   given virtual address is actually mapped to real memory. The safest way
> >>   would be to extend the existing memory tracking code to save the values
> >>   saved/loaded from a given address. However if you had register access
> >>   you could probably achieve the same thing after the fact by examining
> >>   the opcode and pulling the values from the registers.
> >
> > What if memory reads were requested by `qemu_plugin_hwaddr` instead of
> > by virtual address? `qemu_plugin_get_hwaddr()` is already exposed, and I
> > would expect being able to successfully get a `qemu_plugin_hwaddr` in a
> > callback would mean it is currently mapped. Am I overlooking
> > something?
> 
> We can't re-run the transaction - there may have been a change to the
> memory layout that instruction caused (see tlb_plugin_lookup and the
> interaction with io_writex).

To make sure I understand, your concern is that such a memory access
would be made against the state from *after* the instruction's execution
rather than before (and that my `qemu_plugin_hwaddr` would be a
reference to before)?

> However I think we can expand the options for memory instrumentation
> to cache the read or written value.

Would this include any non-software accesses as well (i.e. page table
reads made by hardware on architectures which support doing so)? I
suspect you're going to tell me that this is hard to do without exposing
QEMU/TCG internals, but I'll ask anyway!

> > I think I might actually prefer a plugin memory access interface be in
> > the physical address space - it seems like it might allow you to get
> > more mileage out of one interface without having to support accesses by
> > virtual and physical address separately.
> >
> > Or, even if that won't work for whatever reason, it seems reasonable for
> > a plugin call accessing memory by virtual address to fail in the case
> > where it's not mapped. As long as that failure case is well-documented
> > and easy to distinguish from others within a plugin, why not?
> 
> Hmmm I'm not sure - I don't want to expose internal implementation
> details to the plugins because we don't want plugins to rely on them.

Ohhh, was your "you can't know [...] mapped to real memory" discussing
whether it was currently mapped on the *host*?

I assumed you were discussing whether it was mapped from the guest's
point of view, and therefore expected that whether a guest VA was mapped
was a function of the guest code being executed, and not of the TCG
implementation. I confess I'm not that familiar with how QEMU handles
memory internally.

-Aaron


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

* Re: Plugin Register Accesses
  2020-12-08 17:56     ` Alex Bennée
  2020-12-08 19:44       ` Aaron Lindsay via
@ 2020-12-08 19:49       ` Aaron Lindsay via
  2020-12-08 22:34         ` Alex Bennée
  1 sibling, 1 reply; 10+ messages in thread
From: Aaron Lindsay via @ 2020-12-08 19:49 UTC (permalink / raw)
  To: Alex Bennée; +Cc: qemu-devel, cota, richard.henderson

On Dec 08 17:56, Alex Bennée wrote:
> Aaron Lindsay <aaron@os.amperecomputing.com> writes:
> > On Dec 08 12:17, Alex Bennée wrote:
> >>   For registers I think there needs to be some re-factoring of QEMU's
> >>   internals to do it cleanly. Currently we have each front-end providing
> >>   hooks to the gdbstub as well as building up their own regid and xml to
> >>   be consumed by it. We probably want a architectural neutral central
> >>   repository that the front ends can register their registers (sic) and
> >>   helpers with. This would then provide hooks for gdbstub to cleanly
> >>   generate XML as well as an interface point for the plugin infrastructure
> >>   (and probably whatever the HMP uses as well).
> >
> > In a previous incarnation, I was proxying calls to the plugin API
> > directly through to gdb_read_register() in gdbstub.c and therefore using
> > gdb as the point of commonality. I'm not saying it's ideal but... it
> > works? One downside is that you have to know 'out-of-band' which integer
> > value corresponds to the register you want to query for your
> > architecture, though it hasn't been a significant issue for me.
> 
> Certainly workable for a private branch but I don't want to merge
> anything like that upstream.

Sure - I was more commenting on what I've done in case it's useful than
pushing for it to be upstreamed!

> As far as I can see there are a number of
> consumers of register information:
> 
>   - plugins
>   - gdbstub
>   - monitor (info registers)
>   - -d LOG_CPU logging
> 
> so rather than have them all have their hooks into every front-end I can
> see a case for consolidation.
> 
> For the plugin case providing an introspection helper to get a handle on
> the register makes sense and would be less painful than teachning
> plugins about gdb regids which can and do move around with new system
> registers.
> 
>   qemu_plugin_reg_t *handle = qemu_plugin_find_register("x2")
> 
> if we document the handle as usable across calls this can be done on
> start-up. Then it would be:
> 
>   uint64_t val = qemu_plugin_read_register(cpu_index, handle);

I recognize this is pseudocode, but I'm wondering "out loud" if this
would need to be variable-width instead of a uint64_t to allow for wider
registers in an actual implementation.

-Aaron


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

* Re: Plugin Register Accesses
  2020-12-08 19:49       ` Aaron Lindsay via
@ 2020-12-08 22:34         ` Alex Bennée
  0 siblings, 0 replies; 10+ messages in thread
From: Alex Bennée @ 2020-12-08 22:34 UTC (permalink / raw)
  To: Aaron Lindsay; +Cc: cota, richard.henderson, qemu-devel


Aaron Lindsay <aaron@os.amperecomputing.com> writes:

> On Dec 08 17:56, Alex Bennée wrote:
>> Aaron Lindsay <aaron@os.amperecomputing.com> writes:
>> > On Dec 08 12:17, Alex Bennée wrote:
>> >>   For registers I think there needs to be some re-factoring of QEMU's
>> >>   internals to do it cleanly. Currently we have each front-end providing
>> >>   hooks to the gdbstub as well as building up their own regid and xml to
>> >>   be consumed by it. We probably want a architectural neutral central
>> >>   repository that the front ends can register their registers (sic) and
>> >>   helpers with. This would then provide hooks for gdbstub to cleanly
>> >>   generate XML as well as an interface point for the plugin infrastructure
>> >>   (and probably whatever the HMP uses as well).
>> >
>> > In a previous incarnation, I was proxying calls to the plugin API
>> > directly through to gdb_read_register() in gdbstub.c and therefore using
>> > gdb as the point of commonality. I'm not saying it's ideal but... it
>> > works? One downside is that you have to know 'out-of-band' which integer
>> > value corresponds to the register you want to query for your
>> > architecture, though it hasn't been a significant issue for me.
>> 
>> Certainly workable for a private branch but I don't want to merge
>> anything like that upstream.
>
> Sure - I was more commenting on what I've done in case it's useful than
> pushing for it to be upstreamed!
>
>> As far as I can see there are a number of
>> consumers of register information:
>> 
>>   - plugins
>>   - gdbstub
>>   - monitor (info registers)
>>   - -d LOG_CPU logging
>> 
>> so rather than have them all have their hooks into every front-end I can
>> see a case for consolidation.
>> 
>> For the plugin case providing an introspection helper to get a handle on
>> the register makes sense and would be less painful than teachning
>> plugins about gdb regids which can and do move around with new system
>> registers.
>> 
>>   qemu_plugin_reg_t *handle = qemu_plugin_find_register("x2")
>> 
>> if we document the handle as usable across calls this can be done on
>> start-up. Then it would be:
>> 
>>   uint64_t val = qemu_plugin_read_register(cpu_index, handle);
>
> I recognize this is pseudocode, but I'm wondering "out loud" if this
> would need to be variable-width instead of a uint64_t to allow for wider
> registers in an actual implementation.

Yeah probably. The current internal interface for gdb uses GByteArray's
so that may be something you pass into the read function.

>
> -Aaron


-- 
Alex Bennée


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

* Re: Plugin Register Accesses
  2020-12-08 19:44       ` Aaron Lindsay via
@ 2020-12-30 21:12         ` Aaron Lindsay via
  2021-01-07 16:49           ` Alex Bennée
  0 siblings, 1 reply; 10+ messages in thread
From: Aaron Lindsay via @ 2020-12-30 21:12 UTC (permalink / raw)
  To: Alex Bennée; +Cc: cota, richard.henderson, qemu-devel

On Dec 08 14:44, Aaron Lindsay wrote:
> On Dec 08 17:56, Alex Bennée wrote:
> > Aaron Lindsay <aaron@os.amperecomputing.com> writes:
> > > On Dec 08 12:17, Alex Bennée wrote:
> > >> Aaron Lindsay <aaron@os.amperecomputing.com> writes:
> > >>   Memory is a little trickier because you can't know at any point if a
> > >>   given virtual address is actually mapped to real memory. The safest way
> > >>   would be to extend the existing memory tracking code to save the values
> > >>   saved/loaded from a given address. However if you had register access
> > >>   you could probably achieve the same thing after the fact by examining
> > >>   the opcode and pulling the values from the registers.
> > >
> > > What if memory reads were requested by `qemu_plugin_hwaddr` instead of
> > > by virtual address? `qemu_plugin_get_hwaddr()` is already exposed, and I
> > > would expect being able to successfully get a `qemu_plugin_hwaddr` in a
> > > callback would mean it is currently mapped. Am I overlooking
> > > something?
> > 
> > We can't re-run the transaction - there may have been a change to the
> > memory layout that instruction caused (see tlb_plugin_lookup and the
> > interaction with io_writex).
> 
> To make sure I understand, your concern is that such a memory access
> would be made against the state from *after* the instruction's execution
> rather than before (and that my `qemu_plugin_hwaddr` would be a
> reference to before)?
> 
> > However I think we can expand the options for memory instrumentation
> > to cache the read or written value.
> 
> Would this include any non-software accesses as well (i.e. page table
> reads made by hardware on architectures which support doing so)? I
> suspect you're going to tell me that this is hard to do without exposing
> QEMU/TCG internals, but I'll ask anyway!
> 
> > > I think I might actually prefer a plugin memory access interface be in
> > > the physical address space - it seems like it might allow you to get
> > > more mileage out of one interface without having to support accesses by
> > > virtual and physical address separately.
> > >
> > > Or, even if that won't work for whatever reason, it seems reasonable for
> > > a plugin call accessing memory by virtual address to fail in the case
> > > where it's not mapped. As long as that failure case is well-documented
> > > and easy to distinguish from others within a plugin, why not?
> > 
> > Hmmm I'm not sure - I don't want to expose internal implementation
> > details to the plugins because we don't want plugins to rely on them.
> 
> Ohhh, was your "you can't know [...] mapped to real memory" discussing
> whether it was currently mapped on the *host*?
> 
> I assumed you were discussing whether it was mapped from the guest's
> point of view, and therefore expected that whether a guest VA was mapped
> was a function of the guest code being executed, and not of the TCG
> implementation. I confess I'm not that familiar with how QEMU handles
> memory internally.

I'm trying to understand the issue here a little more... does calling
`cpu_memory_rw_debug()` not work because it's not safe to call in a
plugin instruction-execution callback? Is there any way to make that
sort of arbitrary access to memory safely?

-Aaron


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

* Re: Plugin Register Accesses
  2020-12-30 21:12         ` Aaron Lindsay via
@ 2021-01-07 16:49           ` Alex Bennée
  2021-01-07 20:45             ` Aaron Lindsay via
  0 siblings, 1 reply; 10+ messages in thread
From: Alex Bennée @ 2021-01-07 16:49 UTC (permalink / raw)
  To: Aaron Lindsay; +Cc: cota, richard.henderson, qemu-devel


Aaron Lindsay <aaron@os.amperecomputing.com> writes:

> On Dec 08 14:44, Aaron Lindsay wrote:
>> On Dec 08 17:56, Alex Bennée wrote:
>> > Aaron Lindsay <aaron@os.amperecomputing.com> writes:
>> > > On Dec 08 12:17, Alex Bennée wrote:
>> > >> Aaron Lindsay <aaron@os.amperecomputing.com> writes:
>> > >>   Memory is a little trickier because you can't know at any point if a
>> > >>   given virtual address is actually mapped to real memory. The safest way
>> > >>   would be to extend the existing memory tracking code to save the values
>> > >>   saved/loaded from a given address. However if you had register access
>> > >>   you could probably achieve the same thing after the fact by examining
>> > >>   the opcode and pulling the values from the registers.
>> > >
>> > > What if memory reads were requested by `qemu_plugin_hwaddr` instead of
>> > > by virtual address? `qemu_plugin_get_hwaddr()` is already exposed, and I
>> > > would expect being able to successfully get a `qemu_plugin_hwaddr` in a
>> > > callback would mean it is currently mapped. Am I overlooking
>> > > something?
>> > 
>> > We can't re-run the transaction - there may have been a change to the
>> > memory layout that instruction caused (see tlb_plugin_lookup and the
>> > interaction with io_writex).
>> 
>> To make sure I understand, your concern is that such a memory access
>> would be made against the state from *after* the instruction's execution
>> rather than before (and that my `qemu_plugin_hwaddr` would be a
>> reference to before)?
>> 
>> > However I think we can expand the options for memory instrumentation
>> > to cache the read or written value.
>> 
>> Would this include any non-software accesses as well (i.e. page table
>> reads made by hardware on architectures which support doing so)? I
>> suspect you're going to tell me that this is hard to do without exposing
>> QEMU/TCG internals, but I'll ask anyway!
>> 
>> > > I think I might actually prefer a plugin memory access interface be in
>> > > the physical address space - it seems like it might allow you to get
>> > > more mileage out of one interface without having to support accesses by
>> > > virtual and physical address separately.
>> > >
>> > > Or, even if that won't work for whatever reason, it seems reasonable for
>> > > a plugin call accessing memory by virtual address to fail in the case
>> > > where it's not mapped. As long as that failure case is well-documented
>> > > and easy to distinguish from others within a plugin, why not?
>> > 
>> > Hmmm I'm not sure - I don't want to expose internal implementation
>> > details to the plugins because we don't want plugins to rely on them.
>> 
>> Ohhh, was your "you can't know [...] mapped to real memory" discussing
>> whether it was currently mapped on the *host*?
>> 
>> I assumed you were discussing whether it was mapped from the guest's
>> point of view, and therefore expected that whether a guest VA was mapped
>> was a function of the guest code being executed, and not of the TCG
>> implementation. I confess I'm not that familiar with how QEMU handles
>> memory internally.
>
> I'm trying to understand the issue here a little more... does calling
> `cpu_memory_rw_debug()` not work because it's not safe to call in a
> plugin instruction-execution callback? Is there any way to make that
> sort of arbitrary access to memory safely?

It would be safe on a halted system. However you might not get the same
data back as the load/store instruction just executed if the execution
of the instruction caused a change in the page table mappings. For
example on ARM M-profile writing to the mmio MPU control registers will
flush the current address mappings. For example:

  1. access page X
  2. update architecture page tables for page X -> Y
  3. write to MPU control register, trigger tlb_flush
  4. access page X from plugin -> get Y results

IOW accessing cpu_memory_rw_debug from a instrumented load/store helper
for the address just accessed would be fine for that particular address
because nothing will replace the TLB entry while in the helper. However
as a generalised access to memory things may have changed.

I think we can store enough data for a helper like:

  qemu_plugin_hwaddr_get_value(const struct qemu_plugin_hwaddr *haddr)

but we would certainly want to cache the values io_readx and io_writex
use as they will otherwise be lost into the depths of the emulation.

>
> -Aaron


-- 
Alex Bennée


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

* Re: Plugin Register Accesses
  2021-01-07 16:49           ` Alex Bennée
@ 2021-01-07 20:45             ` Aaron Lindsay via
  0 siblings, 0 replies; 10+ messages in thread
From: Aaron Lindsay via @ 2021-01-07 20:45 UTC (permalink / raw)
  To: Alex Bennée; +Cc: cota, richard.henderson, qemu-devel

On Jan 07 16:49, Alex Bennée wrote:
> 
> Aaron Lindsay <aaron@os.amperecomputing.com> writes:
> 
> > On Dec 08 14:44, Aaron Lindsay wrote:
> >> On Dec 08 17:56, Alex Bennée wrote:
> >> > Aaron Lindsay <aaron@os.amperecomputing.com> writes:
> >> > > On Dec 08 12:17, Alex Bennée wrote:
> >> > >> Aaron Lindsay <aaron@os.amperecomputing.com> writes:
> >> > >>   Memory is a little trickier because you can't know at any point if a
> >> > >>   given virtual address is actually mapped to real memory. The safest way
> >> > >>   would be to extend the existing memory tracking code to save the values
> >> > >>   saved/loaded from a given address. However if you had register access
> >> > >>   you could probably achieve the same thing after the fact by examining
> >> > >>   the opcode and pulling the values from the registers.
> >> > >
> >> > > What if memory reads were requested by `qemu_plugin_hwaddr` instead of
> >> > > by virtual address? `qemu_plugin_get_hwaddr()` is already exposed, and I
> >> > > would expect being able to successfully get a `qemu_plugin_hwaddr` in a
> >> > > callback would mean it is currently mapped. Am I overlooking
> >> > > something?
> >> > 
> >> > We can't re-run the transaction - there may have been a change to the
> >> > memory layout that instruction caused (see tlb_plugin_lookup and the
> >> > interaction with io_writex).
> >> 
> >> To make sure I understand, your concern is that such a memory access
> >> would be made against the state from *after* the instruction's execution
> >> rather than before (and that my `qemu_plugin_hwaddr` would be a
> >> reference to before)?
> >> 
> >> > However I think we can expand the options for memory instrumentation
> >> > to cache the read or written value.
> >> 
> >> Would this include any non-software accesses as well (i.e. page table
> >> reads made by hardware on architectures which support doing so)? I
> >> suspect you're going to tell me that this is hard to do without exposing
> >> QEMU/TCG internals, but I'll ask anyway!
> >> 
> >> > > I think I might actually prefer a plugin memory access interface be in
> >> > > the physical address space - it seems like it might allow you to get
> >> > > more mileage out of one interface without having to support accesses by
> >> > > virtual and physical address separately.
> >> > >
> >> > > Or, even if that won't work for whatever reason, it seems reasonable for
> >> > > a plugin call accessing memory by virtual address to fail in the case
> >> > > where it's not mapped. As long as that failure case is well-documented
> >> > > and easy to distinguish from others within a plugin, why not?
> >> > 
> >> > Hmmm I'm not sure - I don't want to expose internal implementation
> >> > details to the plugins because we don't want plugins to rely on them.
> >> 
> >> Ohhh, was your "you can't know [...] mapped to real memory" discussing
> >> whether it was currently mapped on the *host*?
> >> 
> >> I assumed you were discussing whether it was mapped from the guest's
> >> point of view, and therefore expected that whether a guest VA was mapped
> >> was a function of the guest code being executed, and not of the TCG
> >> implementation. I confess I'm not that familiar with how QEMU handles
> >> memory internally.
> >
> > I'm trying to understand the issue here a little more... does calling
> > `cpu_memory_rw_debug()` not work because it's not safe to call in a
> > plugin instruction-execution callback? Is there any way to make that
> > sort of arbitrary access to memory safely?
> 
> It would be safe on a halted system. However you might not get the same
> data back as the load/store instruction just executed if the execution
> of the instruction caused a change in the page table mappings. For
> example on ARM M-profile writing to the mmio MPU control registers will
> flush the current address mappings. For example:
> 
>   1. access page X
>   2. update architecture page tables for page X -> Y
>   3. write to MPU control register, trigger tlb_flush
>   4. access page X from plugin -> get Y results
> 
> IOW accessing cpu_memory_rw_debug from a instrumented load/store helper
> for the address just accessed would be fine for that particular address
> because nothing will replace the TLB entry while in the helper. However
> as a generalised access to memory things may have changed.

To make sure I understand - are you saying that calling
`cpu_memory_rw_debug()` will always reflect a consistent view of memory,
just that it's the view of memory from *after* the current instruction
has executed (and with contents potentially modified by other cpus in
the meantime)?

> I think we can store enough data for a helper like:
> 
>   qemu_plugin_hwaddr_get_value(const struct qemu_plugin_hwaddr *haddr)
> 
> but we would certainly want to cache the values io_readx and io_writex
> use as they will otherwise be lost into the depths of the emulation.

I think this would be helpful, but it wouldn't get you to arbitrary
access of memory, correct? (Since you wouldn't be able to create an
qemu_plugin_hwaddr for an arbitrary, non-instrumented, address you
wanted to inspect).

-Aaron


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

end of thread, other threads:[~2021-01-07 21:03 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-07 21:03 Plugin Register Accesses Aaron Lindsay
2020-12-08 12:17 ` Alex Bennée
2020-12-08 14:46   ` Aaron Lindsay via
2020-12-08 17:56     ` Alex Bennée
2020-12-08 19:44       ` Aaron Lindsay via
2020-12-30 21:12         ` Aaron Lindsay via
2021-01-07 16:49           ` Alex Bennée
2021-01-07 20:45             ` Aaron Lindsay via
2020-12-08 19:49       ` Aaron Lindsay via
2020-12-08 22:34         ` 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.