[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v3] memory: Directly dispatch alias accesses on origin memory
From: |
Philippe Mathieu-Daudé |
Subject: |
Re: [PATCH v3] memory: Directly dispatch alias accesses on origin memory region |
Date: |
Tue, 20 Apr 2021 11:10:26 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.8.1 |
On 4/20/21 9:00 AM, Mark Cave-Ayland wrote:
> 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 :/
Yes, most of the commits in this area are from Paolo.
I Also Cc'ed:
- Michael S. Tsirkin
- Alexey Kardashevskiy
- Igor Mammedov
- David Gibson
- [PATCH v3] memory: Directly dispatch alias accesses on origin memory region, Philippe Mathieu-Daudé, 2021/04/17
- Re: [PATCH v3] memory: Directly dispatch alias accesses on origin memory region, Mark Cave-Ayland, 2021/04/19
- Re: [PATCH v3] memory: Directly dispatch alias accesses on origin memory region, Philippe Mathieu-Daudé, 2021/04/19
- Re: [PATCH v3] memory: Directly dispatch alias accesses on origin memory region, Mark Cave-Ayland, 2021/04/20
- Re: [PATCH v3] memory: Directly dispatch alias accesses on origin memory region,
Philippe Mathieu-Daudé <=
- Re: [PATCH v3] memory: Directly dispatch alias accesses on origin memory region, Peter Xu, 2021/04/20
- Re: [PATCH v3] memory: Directly dispatch alias accesses on origin memory region, Mark Cave-Ayland, 2021/04/21
- Re: [PATCH v3] memory: Directly dispatch alias accesses on origin memory region, Peter Xu, 2021/04/21
- Re: [PATCH v3] memory: Directly dispatch alias accesses on origin memory region, Peter Maydell, 2021/04/21