From: Tomoyuki HIROSE <tomoyuki.hirose@igel.co.jp>
To: Peter Xu <peterx@redhat.com>
Cc: qemu-devel@nongnu.org, "Paolo Bonzini" <pbonzini@redhat.com>,
"David Hildenbrand" <david@redhat.com>,
"Philippe Mathieu-Daudé" <philmd@linaro.org>
Subject: Re: [RFC PATCH 2/5] system/memory: support unaligned access
Date: Wed, 11 Dec 2024 18:35:57 +0900 [thread overview]
Message-ID: <9d1f07e5-2c08-455c-a653-e57e219666ab@igel.co.jp> (raw)
In-Reply-To: <Z1MpY7ZIAAoBDbZU@x1n>
Sorry for late reply.
On 2024/12/07 1:42, Peter Xu wrote:
> On Fri, Dec 06, 2024 at 05:31:33PM +0900, Tomoyuki HIROSE wrote:
>> In this email, I explain what this patch set will resolve and an
>> overview of this patch set. I will respond to your specific code
>> review comments in a separate email.
> Yes, that's OK.
>
>> On 2024/12/03 6:23, Peter Xu wrote:
>>> On Fri, Nov 08, 2024 at 12:29:46PM +0900, Tomoyuki HIROSE wrote:
>>>> The previous code ignored 'impl.unaligned' and handled unaligned
>>>> accesses as is. But this implementation could not emulate specific
>>>> registers of some devices that allow unaligned access such as xHCI
>>>> Host Controller Capability Registers.
>>> I have some comment that can be naive, please bare with me..
>>>
>>> Firstly, could you provide an example in the commit message, of what would
>>> start working after this patch?
>> Sorry, I'll describe what will start working in the next version of
>> this patch set. I'll also provide an example here. After applying
>> this patch set, a read(addr=0x2, size=2) in the xHCI Host Controller
>> Capability Registers region will work correctly. For example, the read
>> result will return 0x0110 (version 1.1.0). Previously, a
>> read(addr=0x2, size=2) in the Capability Register region would return
>> 0, which is incorrect. According to the xHCI specification, the
>> Capability Register region does not prohibit accesses of any size or
>> unaligned accesses.
> Thanks for the context, Tomoyuki.
>
> I assume it's about xhci_cap_ops then. If you agree we can also mention
> xhci_cap_ops when dscribing it, so readers can easily reference the MR
> attributes from the code alongside with understanding the use case.
>
> Does it mean that it could also work if xhci_cap_ops.impl.min_access_size
> can be changed to 2 (together with additional xhci_cap_read/write support)?
>
> Note that I'm not saying it must do so even if it would work for xHCI, but
> if the memory API change is only for one device, then it can still be
> discussed about which option would be better on changing the device or the
> core.
>
> Meanwhile, if there's more use cases on the impl.unaligned, it'll be nice
> to share together when describing the issue. That will be very persuasive
> input that a generic solution is needed.
OK, I understand. I will try to describe 'xhci_cap_ops' and related topics.
Currently, the actual 'xhci_cap_ops' code is as follows:
```
static const MemoryRegionOps xhci_cap_ops = {
.read = xhci_cap_read,
.write = xhci_cap_write,
.valid.min_access_size = 1,
.valid.max_access_size = 4,
.impl.min_access_size = 4,
.impl.max_access_size = 4,
.endianness = DEVICE_LITTLE_ENDIAN,
};
```
According to the above code, the guest can access this MemoryRegion
with 1-4 bytes. 'valid.unaligned' is also not explicitly defined, so
it is treated as 'false'. This means the guest can access this MR with
1-4 bytes, as long as the access is aligned. However, the xHCI
specification does not prohibit unaligned accesses.
Simply adding '.valid.unaligned = true' will not resolve this problem
because 'impl.unaligned' is also 'false'. In this situation, where
'valid.unaligned' is 'true' but 'impl.unaligned' is 'false', we need
to emulate unaligned accesses by splitting them into multiple aligned
accesses.
An alternative solution would be to fix 'xhci_cap_{read,write}',
update '.impl.min_access_size = 1', and set '.impl.unaligned = true'
to allow the guest to perform unaligned accesses with 1-4 bytes. With
this solution, we wouldn't need to modify core memory code.
However, applying this approach throughout the QEMU codebase would
increase the complexity of device implementations. If a device allows
unaligned guest access to its register region, the device implementer
would needs to handle unaligned accesses explicitly. Additionally,
the distinction between 'valid' and 'impl' would become almost
meaningless, making it unclear why they are separated.
"Ideally", we could consider one of the following changes:
1. Introduce an emulation mechanism for unaligned accesses using
multiple aligned accesses.
2. Remove either 'valid' or 'impl' and unify these functionality.
Solution 2 would require extensive changes to the codebase and memory
API, making it impractical. Solution 1 seems to align with QEMU's
original intentions. Actually, there is a comment in 'memory.c' that
states:
`/* FIXME: support unaligned access? */`
This patch set implements solution 1. If there is a better way to
resolve these issues, I would greatly appreciate your suggestions.
Thanks,
Tomoyuki HIROSE
>>> IIUC things like read(addr=0x2, size=8) should already working before but
>>> it'll be cut into 4 times read() over 2 bytes for unaligned=false, am I
>>> right?
>> Yes, I also think so. I think the operation read(addr=0x2, size=8) in
>> a MemoryRegion with impl.unaligned==false should be split into
>> multiple aligned read() operations. The access size should depends on
>> the region's 'impl.max_access_size' and 'impl.min_access_size'
>> . Actually, the comments in 'include/exec/memory.h' seem to confirm
>> this behavior:
>>
>> ```
>> /* If true, unaligned accesses are supported. Otherwise all accesses
>> * are converted to (possibly multiple) naturally aligned accesses.
>> */
>> bool unaligned;
>> ```
>>
>> MemoryRegionOps struct in the MemoryRegion has two members, 'valid'
>> and 'impl' . I think 'valid' determines the behavior of the
>> MemoryRegion exposed to the guest, and 'impl' determines the behavior
>> of the MemoryRegion exposed to the QEMU memory region manager.
>>
>> Consider the situation where we have a MemoryRegion with the following
>> parameters:
>>
>> ```
>> MemoryRegion mr = (MemoryRegion){
>> //...
>> .ops = (MemoryRegionOps){
>> //...
>> .read = ops_read_function;
>> .write = ops_write_function;
>> .valid.min_access_size = 4;
>> .valid.max_access_size = 4;
>> .valid.unaligned = true;
>> .impl.min_access_size = 2;
>> .impl.max_access_size = 2;
>> .impl.unaligned = false;
>> };
>> };
>> ```
>>
>> With this MemoryRegion 'mr', the guest can read(addr=0x1, size=4)
>> because 'valid.unaligned' is true. But 'impl.unaligned' is false, so
>> 'mr.ops->read()' function does not support addr=0x1, which is
>> unaligned. In this situation, we need to convert the unaligned access
>> to multiple aligned accesses, such as:
>>
>> - mr.ops->read(addr=0x0, size=2)
>> - mr.ops->read(addr=0x2, size=2)
>> - mr.ops->read(addr=0x4, size=2)
>>
>> After that, we should return a result of read(addr=0x1, size=4) from
>> above mr.ops->read() results, I think.
> Yes. I agree with your analysis and understanding.
>
> Thanks,
>
next prev parent reply other threads:[~2024-12-11 9:36 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-08 3:29 [RFC PATCH 0/5] support unaligned access to xHCI Capability Tomoyuki HIROSE
2024-11-08 3:29 ` [RFC PATCH 1/5] hw/nvme/ctrl: specify the 'valid' field in MemoryRegionOps Tomoyuki HIROSE
2024-11-08 3:29 ` [RFC PATCH 2/5] system/memory: support unaligned access Tomoyuki HIROSE
2024-12-02 21:23 ` Peter Xu
2024-12-06 8:31 ` Tomoyuki HIROSE
2024-12-06 16:42 ` Peter Xu
2024-12-11 9:35 ` Tomoyuki HIROSE [this message]
2024-12-11 22:54 ` Peter Xu
2024-12-12 5:39 ` Tomoyuki HIROSE
2024-12-12 15:46 ` Peter Xu
2025-01-08 2:58 ` Tomoyuki HIROSE
2025-01-08 16:50 ` Peter Xu
2025-01-10 10:11 ` Tomoyuki HIROSE
2025-01-10 15:08 ` Peter Xu
2025-01-15 2:01 ` Tomoyuki HIROSE
2024-12-11 9:56 ` Peter Maydell
2024-12-11 22:25 ` Peter Xu
2024-11-08 3:29 ` [RFC PATCH 3/5] hw/misc: add test device for memory access Tomoyuki HIROSE
2024-11-08 3:29 ` [RFC PATCH 4/5] tests/qtest: add test for memory region access Tomoyuki HIROSE
2024-11-08 3:29 ` [RFC PATCH 5/5] hw/usb/hcd-xhci: allow unaligned access to Capability Registers Tomoyuki HIROSE
2024-11-27 4:32 ` [RFC PATCH 0/5] support unaligned access to xHCI Capability Tomoyuki HIROSE
2024-11-27 11:23 ` Peter Maydell
2024-11-28 6:19 ` Tomoyuki HIROSE
2024-11-28 11:15 ` Peter Maydell
2024-11-29 3:33 ` Tomoyuki HIROSE
2024-12-02 14:17 ` Peter Maydell
2024-12-04 10:04 ` Tomoyuki HIROSE
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=9d1f07e5-2c08-455c-a653-e57e219666ab@igel.co.jp \
--to=tomoyuki.hirose@igel.co.jp \
--cc=david@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peterx@redhat.com \
--cc=philmd@linaro.org \
--cc=qemu-devel@nongnu.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).