All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
To: "Philippe Mathieu-Daudé" <f4bug@amsat.org>,
	qemu-devel@nongnu.org, "Peter Maydell" <peter.maydell@linaro.org>
Cc: Paolo Bonzini <pbonzini@redhat.com>,
	Richard Henderson <richard.henderson@linaro.org>,
	Peter Xu <peterx@redhat.com>
Subject: Re: [PATCH v3] memory: Directly dispatch alias accesses on origin memory region
Date: Tue, 20 Apr 2021 08:00:09 +0100	[thread overview]
Message-ID: <efea7689-15c6-44bf-77a8-3d6ee945d097@ilande.co.uk> (raw)
In-Reply-To: <67955dd0-dfc7-271f-009f-cf7247f3b6c2@amsat.org>

On 19/04/2021 21:58, Philippe Mathieu-Daudé wrote:

> Hi Mark,
> 
> On 4/19/21 10:13 PM, Mark Cave-Ayland wrote:
>> On 17/04/2021 15:02, Philippe Mathieu-Daudé wrote:
>>
>>> Since commit 2cdfcf272d ("memory: assign MemoryRegionOps to all
>>> regions"), all newly created regions are assigned with
>>> unassigned_mem_ops (which might be then overwritten).
>>>
>>> When using aliased container regions, and there is no region mapped
>>> at address 0 in the container, the memory_region_dispatch_read()
>>> and memory_region_dispatch_write() calls incorrectly return the
>>> container unassigned_mem_ops, because the alias offset is not used.
>>>
>>> The memory_region_init_alias() flow is:
>>>
>>>     memory_region_init_alias()
>>>     -> memory_region_init()
>>>        -> object_initialize(TYPE_MEMORY_REGION)
>>>           -> memory_region_initfn()
>>>              -> mr->ops = &unassigned_mem_ops;
>>>
>>> Later when accessing the alias, the memory_region_dispatch_read()
>>> flow is:
>>>
>>>     memory_region_dispatch_read(offset)
>>>     -> memory_region_access_valid(mr)   <- offset is ignored
>>>        -> mr->ops->valid.accepts()
>>>           -> unassigned_mem_accepts()
>>>           <- false
>>>        <- false
>>>      <- MEMTX_DECODE_ERROR
>>>
>>> The caller gets a MEMTX_DECODE_ERROR while the access is OK.
>>>
>>> Fix by dispatching aliases recusirvely, accessing its origin region
>>> after adding the alias offset.
>>>
>>> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
>>> ---
>>> v3:
>>> - reworded, mentioning the "alias to container" case
>>> - use recursive call instead of while(), because easier when debugging
>>>     therefore reset Richard R-b tag.
>>> v2:
>>> - use while()
>>> ---
>>>    softmmu/memory.c | 10 ++++++++++
>>>    1 file changed, 10 insertions(+)
>>>
>>> diff --git a/softmmu/memory.c b/softmmu/memory.c
>>> index d4493ef9e43..23bdbfac079 100644
>>> --- a/softmmu/memory.c
>>> +++ b/softmmu/memory.c
>>> @@ -1442,6 +1442,11 @@ MemTxResult
>>> memory_region_dispatch_read(MemoryRegion *mr,
>>>        unsigned size = memop_size(op);
>>>        MemTxResult r;
>>>    +    if (mr->alias) {
>>> +        return memory_region_dispatch_read(mr->alias,
>>> +                                           addr + mr->alias_offset,
>>> +                                           pval, op, attrs);
>>> +    }
>>>        if (!memory_region_access_valid(mr, addr, size, false, attrs)) {
>>>            *pval = unassigned_mem_read(mr, addr, size);
>>>            return MEMTX_DECODE_ERROR;
>>> @@ -1486,6 +1491,11 @@ MemTxResult
>>> memory_region_dispatch_write(MemoryRegion *mr,
>>>    {
>>>        unsigned size = memop_size(op);
>>>    +    if (mr->alias) {
>>> +        return memory_region_dispatch_write(mr->alias,
>>> +                                            addr + mr->alias_offset,
>>> +                                            data, op, attrs);
>>> +    }
>>>        if (!memory_region_access_valid(mr, addr, size, true, attrs)) {
>>>            unassigned_mem_write(mr, addr, data, size);
>>>            return MEMTX_DECODE_ERROR;
>>
>> Whilst working on my q800 patches I realised that this was a similar
>> problem to the one I had with my macio.alias implementation at [1]:
>> except that in my case the unassigned_mem_ops mr->ops->valid.accepts()
>> function was being invoked on a ROM memory region instead of an alias. I
>> think this is exactly the same issue that you are attempting to fix with
>> your related patch at
>> https://lists.gnu.org/archive/html/qemu-devel/2021-04/msg03190.html
>> ("memory: Initialize MemoryRegionOps for RAM memory regions").
> 
> So if 2 contributors hit similar issues, there is something wrong with
> the API. I don't see your use case or mine as forbidded by the
> documentation in "exec/memory.h".
> 
> My patch might not be the proper fix, but we need to figure out how
> to avoid others to hit the same problem, as it is very hard to debug.

I agree with this sentiment: it has taken me a while to figure out what was 
happening, and that was only because I spotted accesses being rejected with -d 
guest_errors.

 From my perspective the names memory_region_dispatch_read() and 
memory_region_dispatch_write() were the misleading part, although I remember thinking 
it odd whilst trying to use them that I had to start delving into sections etc. just 
to recurse a memory access.

> At least an assertion and a comment.
> 
>> I eventually realised that I needed functions that could dispatch
>> reads/writes to both IO memory regions and ROM memory regions, and that
>> functionality is covered by the address_space_*() access functions.
>> Using the address_space_*() functions I was then able to come up with
>> the working implementation at [2] that handles accesses to both IO
>> memory regions and ROM memory regions correctly.
>>
>> The reason I initially used the
>> memory_region_dispatch_read()/memory_region_dispatch_write() functions
>> was because I could see that was how the virtio devices dispatched
>> accesses through the proxy. However I'm wondering now if this API can
>> only be used for terminating IO memory regions, and so the alias_offset
>> that you're applying above should actually be applied elsewhere instead.
> 
> I figured out the AddressSpace API make these cases simpler, but IIRC
> there is some overhead, some function tries to resolve / update
> something and iterate over a list. While from the MemoryRegion API we
> already know which region we want to access.
> 
> I Cc'ed Peter considering him expert in this area, but don't know else
> who to ask for help on this topic...

Yeah possibly Paolo, otherwise it's a dig through the git history of memory.c :/


ATB,

Mark.


  parent reply	other threads:[~2021-04-20  7:02 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-17 14:02 [PATCH v3] memory: Directly dispatch alias accesses on origin memory region Philippe Mathieu-Daudé
2021-04-19 20:13 ` Mark Cave-Ayland
2021-04-19 20:58   ` Philippe Mathieu-Daudé
2021-04-19 21:11     ` Philippe Mathieu-Daudé
2021-04-20  7:22       ` Mark Cave-Ayland
2021-04-20  7:00     ` Mark Cave-Ayland [this message]
2021-04-20  9:10       ` Philippe Mathieu-Daudé
2021-04-20 20:59         ` Peter Xu
2021-04-21 10:33           ` Mark Cave-Ayland
2021-04-21 14:48             ` Peter Xu
2021-04-21 11:05           ` Peter Maydell

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=efea7689-15c6-44bf-77a8-3d6ee945d097@ilande.co.uk \
    --to=mark.cave-ayland@ilande.co.uk \
    --cc=f4bug@amsat.org \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=peterx@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=richard.henderson@linaro.org \
    /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.