All of lore.kernel.org
 help / color / mirror / Atom feed
* RFC: Memory region accesses where .valid.min_access_size < .impl.min_access_size
@ 2021-05-13 11:47 Jonathan Cameron
  2021-05-13 12:23 ` Peter Maydell
  0 siblings, 1 reply; 7+ messages in thread
From: Jonathan Cameron @ 2021-05-13 11:47 UTC (permalink / raw)
  To: qemu-devel, Paolo Bonzini
  Cc: Peter Maydell, Ben Widawsky, david, mst, Chris Browy, linuxarm,
	Peter Xu, f4bug, imammedo, dan.j.williams, Alex Bennée

Hi All,

Cc list is a bit of guess, so please add anyone else who might be interested
in this topic.

This came up in discussion of the CXL emulation series a while back
and I've finally gotten around to looking more closely at it
(having carried a local hack in the meantime).

https://lore.kernel.org/qemu-devel/20210218165010.00004bce@Huawei.com/#t

The code in question is:

+static uint64_t mailbox_reg_read(void *opaque, hwaddr offset, unsigned size)
+{
+    CXLDeviceState *cxl_dstate = opaque;
+
+    switch (size) {
+    case 8:
+        return cxl_dstate->mbox_reg_state64[offset / 8];
+    case 4:
+        return cxl_dstate->mbox_reg_state32[offset / 4];
+    default:
+        g_assert_not_reached();
+    }
+}
+
+static void mailbox_reg_write(void *opaque, hwaddr offset, uint64_t value,
+                              unsigned size)
+{
+    CXLDeviceState *cxl_dstate = opaque;
+
+    if (offset >= A_CXL_DEV_CMD_PAYLOAD) {
+        memcpy(cxl_dstate->mbox_reg_state + offset, &value, size);
+        return;
+    }
+
+    /*
+     * Lock is needed to prevent concurrent writes as well as to prevent writes
+     * coming in while the firmware is processing. Without background commands
+     * or the second mailbox implemented, this serves no purpose since the
+     * memory access is synchronized at a higher level (per memory region).
+     */
+    RCU_READ_LOCK_GUARD();
+
+    switch (size) {
+    case 4:
+        mailbox_mem_writel(cxl_dstate->mbox_reg_state32, offset, value);
+        break;
+    case 8:
+        mailbox_mem_writeq(cxl_dstate->mbox_reg_state64, offset, value);
+        break;
+    default:
+        g_assert_not_reached();
+    }
+
+    if (ARRAY_FIELD_EX32(cxl_dstate->mbox_reg_state32, CXL_DEV_MAILBOX_CTRL,
+                         DOORBELL))
+        cxl_process_mailbox(cxl_dstate);
+}
...

+static const MemoryRegionOps mailbox_ops = {
+    .read = mailbox_reg_read,
+    .write = mailbox_reg_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .valid = {
+        .min_access_size = 1,
+        .max_access_size = 8,
+        .unaligned = false,
+    },
+    .impl = {
+        .min_access_size = 4,
+        .max_access_size = 8,
+    },
+};
+

And when run against the Linux driver, a particular memcpy_fromio() on ARM64
will result in byte reads when not 8 byte aligned whereas on x86 it will
result in 4 byte alignment. Byte reads under these circumstances today will
return whatever is in the lowest byte of the a 4 byte unaligned read (which
ends up being forced aligned by the simple implementation of the callback).

My initial suggestion was to fix this by adding the relatively
simple code needed in the driver to implement byte read / write,
but Ben pointed at the QEMU docs - docs/devel/memory.rst which
says
"
.impl.min_access_size, .impl.max_access_size define the access sizes
   (in bytes) supported by the *implementation*; other access sizes will be
   emulated using the ones available. For example a 4-byte write will be
   emulated using four 1-byte writes, if .impl.max_access_size = 1.
"

This isn't true when we have the situation where
.valid.min_access_size < .imp.min_access_size

So change the docs or try to make this work?

Assuming no side effects (if there are any then the emulated device
should not use this) it is reasonably easy to augment
access_with_adjusted_size() for the read case, but the write
case would require a read modify / write cycle.

You could argue that any driver doing this really needs to be sure
that reads and writes are side effect free, but it is pretty nasty.

So in conclusion, Docs wrong or implementation of this corner case 
wrong? (or are we misreading the docs or code?)

Thanks,

Jonathan




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

* Re: RFC: Memory region accesses where .valid.min_access_size < .impl.min_access_size
  2021-05-13 11:47 RFC: Memory region accesses where .valid.min_access_size < .impl.min_access_size Jonathan Cameron
@ 2021-05-13 12:23 ` Peter Maydell
  2021-05-13 12:36   ` Philippe Mathieu-Daudé
  0 siblings, 1 reply; 7+ messages in thread
From: Peter Maydell @ 2021-05-13 12:23 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Ben Widawsky, Michael S. Tsirkin, David Hildenbrand, Chris Browy,
	Linuxarm, Peter Xu, QEMU Developers, Igor Mammedov,
	Paolo Bonzini, Dan Williams, Alex Bennée,
	Philippe Mathieu-Daudé

On Thu, 13 May 2021 at 12:49, Jonathan Cameron
<Jonathan.Cameron@huawei.com> wrote:
> My initial suggestion was to fix this by adding the relatively
> simple code needed in the driver to implement byte read / write,
> but Ben pointed at the QEMU docs - docs/devel/memory.rst which
> says
> "
> .impl.min_access_size, .impl.max_access_size define the access sizes
>    (in bytes) supported by the *implementation*; other access sizes will be
>    emulated using the ones available. For example a 4-byte write will be
>    emulated using four 1-byte writes, if .impl.max_access_size = 1.
> "
>
> This isn't true when we have the situation where
> .valid.min_access_size < .imp.min_access_size
>
> So change the docs or try to make this work?

I don't (yet) have a view on what the in-principle right thing
should be, but in practice: how many devices do we have which
set .valid.min_access_size < .imp.min_access_size ? If we want
to change the semantics we'd need to look at those to see if they
need to be adjusted (or if they're just currently buggy and would
be fixed by the change).

thanks
-- PMM


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

* Re: RFC: Memory region accesses where .valid.min_access_size < .impl.min_access_size
  2021-05-13 12:23 ` Peter Maydell
@ 2021-05-13 12:36   ` Philippe Mathieu-Daudé
  2021-05-13 13:00     ` Jonathan Cameron
  0 siblings, 1 reply; 7+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-05-13 12:36 UTC (permalink / raw)
  To: Peter Maydell, Jonathan Cameron, Francisco Iglesias, Andrew Jeffery
  Cc: Ben Widawsky, David Hildenbrand, Michael S. Tsirkin, Chris Browy,
	Linuxarm, Peter Xu, QEMU Developers, Paolo Bonzini,
	Igor Mammedov, Dan Williams, Alex Bennée

On 5/13/21 2:23 PM, Peter Maydell wrote:
> On Thu, 13 May 2021 at 12:49, Jonathan Cameron
> <Jonathan.Cameron@huawei.com> wrote:
>> My initial suggestion was to fix this by adding the relatively
>> simple code needed in the driver to implement byte read / write,
>> but Ben pointed at the QEMU docs - docs/devel/memory.rst which
>> says
>> "
>> .impl.min_access_size, .impl.max_access_size define the access sizes
>>    (in bytes) supported by the *implementation*; other access sizes will be
>>    emulated using the ones available. For example a 4-byte write will be
>>    emulated using four 1-byte writes, if .impl.max_access_size = 1.
>> "
>>
>> This isn't true when we have the situation where
>> .valid.min_access_size < .imp.min_access_size
>>
>> So change the docs or try to make this work?

See also this patch from Francisco:
https://www.mail-archive.com/qemu-devel@nongnu.org/msg636935.html

And full unaligned access support from Andrew:
https://www.mail-archive.com/qemu-devel@nongnu.org/msg461247.html

> I don't (yet) have a view on what the in-principle right thing
> should be, but in practice: how many devices do we have which
> set .valid.min_access_size < .imp.min_access_size ? If we want
> to change the semantics we'd need to look at those to see if they
> need to be adjusted (or if they're just currently buggy and would
> be fixed by the change).
> 
> thanks
> -- PMM
> 



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

* Re: RFC: Memory region accesses where .valid.min_access_size < .impl.min_access_size
  2021-05-13 12:36   ` Philippe Mathieu-Daudé
@ 2021-05-13 13:00     ` Jonathan Cameron
  2021-05-13 13:32       ` Philippe Mathieu-Daudé
  2021-05-14  2:05       ` Andrew Jeffery
  0 siblings, 2 replies; 7+ messages in thread
From: Jonathan Cameron @ 2021-05-13 13:00 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé
  Cc: Peter Maydell, Ben Widawsky, David Hildenbrand, Andrew Jeffery,
	Francisco Iglesias, Michael S. Tsirkin, Chris Browy, Linuxarm,
	Peter Xu, QEMU Developers, Paolo Bonzini, Igor Mammedov,
	Dan Williams, Alex Bennée

On Thu, 13 May 2021 14:36:27 +0200
Philippe Mathieu-Daudé <philmd@redhat.com> wrote:

> On 5/13/21 2:23 PM, Peter Maydell wrote:
> > On Thu, 13 May 2021 at 12:49, Jonathan Cameron
> > <Jonathan.Cameron@huawei.com> wrote:  
> >> My initial suggestion was to fix this by adding the relatively
> >> simple code needed in the driver to implement byte read / write,
> >> but Ben pointed at the QEMU docs - docs/devel/memory.rst which
> >> says
> >> "
> >> .impl.min_access_size, .impl.max_access_size define the access sizes
> >>    (in bytes) supported by the *implementation*; other access sizes will be
> >>    emulated using the ones available. For example a 4-byte write will be
> >>    emulated using four 1-byte writes, if .impl.max_access_size = 1.
> >> "
> >>
> >> This isn't true when we have the situation where
> >> .valid.min_access_size < .imp.min_access_size
> >>
> >> So change the docs or try to make this work?  
> 
> See also this patch from Francisco:
> https://www.mail-archive.com/qemu-devel@nongnu.org/msg636935.html
> 
> And full unaligned access support from Andrew:
> https://www.mail-archive.com/qemu-devel@nongnu.org/msg461247.html

Thanks - that's very similar to what I was carrying, but I think it
only covers the read case.  That's backed up by the comment:
/* XXX: Can't do this hack for writes */

> 
> > I don't (yet) have a view on what the in-principle right thing
> > should be, but in practice: how many devices do we have which
> > set .valid.min_access_size < .imp.min_access_size ? If we want
> > to change the semantics we'd need to look at those to see if they
> > need to be adjusted (or if they're just currently buggy and would
> > be fixed by the change).

I'm only aware of this one CXL emulated device (+ the proposed code in
the ADC in the above patch set).  For the CXL device, working around
this limitation is straight forward if that's the right option
+ updating the docs to slightly reduced chances of this being hit in
the future.

Thanks,

Jonathan

> > 
> > thanks
> > -- PMM
> >   
> 



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

* Re: RFC: Memory region accesses where .valid.min_access_size < .impl.min_access_size
  2021-05-13 13:00     ` Jonathan Cameron
@ 2021-05-13 13:32       ` Philippe Mathieu-Daudé
  2021-05-14  2:05       ` Andrew Jeffery
  1 sibling, 0 replies; 7+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-05-13 13:32 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Peter Maydell, Ben Widawsky, David Hildenbrand, Andrew Jeffery,
	Francisco Iglesias, Michael S. Tsirkin, Chris Browy, Linuxarm,
	Peter Xu, QEMU Developers, Paolo Bonzini, Igor Mammedov,
	Dan Williams, Alex Bennée

On 5/13/21 3:00 PM, Jonathan Cameron wrote:
> On Thu, 13 May 2021 14:36:27 +0200
> Philippe Mathieu-Daudé <philmd@redhat.com> wrote:
> 
>> On 5/13/21 2:23 PM, Peter Maydell wrote:
>>> On Thu, 13 May 2021 at 12:49, Jonathan Cameron
>>> <Jonathan.Cameron@huawei.com> wrote:  
>>>> My initial suggestion was to fix this by adding the relatively
>>>> simple code needed in the driver to implement byte read / write,
>>>> but Ben pointed at the QEMU docs - docs/devel/memory.rst which
>>>> says
>>>> "
>>>> .impl.min_access_size, .impl.max_access_size define the access sizes
>>>>    (in bytes) supported by the *implementation*; other access sizes will be
>>>>    emulated using the ones available. For example a 4-byte write will be
>>>>    emulated using four 1-byte writes, if .impl.max_access_size = 1.
>>>> "
>>>>
>>>> This isn't true when we have the situation where
>>>> .valid.min_access_size < .imp.min_access_size
>>>>
>>>> So change the docs or try to make this work?  
>>
>> See also this patch from Francisco:
>> https://www.mail-archive.com/qemu-devel@nongnu.org/msg636935.html
>>
>> And full unaligned access support from Andrew:
>> https://www.mail-archive.com/qemu-devel@nongnu.org/msg461247.html
> 
> Thanks - that's very similar to what I was carrying, but I think it
> only covers the read case.  That's backed up by the comment:
> /* XXX: Can't do this hack for writes */

You might use the "MMIO test device" to write your tests, see:
https://www.mail-archive.com/qemu-devel@nongnu.org/msg730716.html
https://www.mail-archive.com/qemu-devel@nongnu.org/msg730720.html

I have a branch tagged v2, need to rebase it and post...

>>> I don't (yet) have a view on what the in-principle right thing
>>> should be, but in practice: how many devices do we have which
>>> set .valid.min_access_size < .imp.min_access_size ? If we want
>>> to change the semantics we'd need to look at those to see if they
>>> need to be adjusted (or if they're just currently buggy and would
>>> be fixed by the change).
> 
> I'm only aware of this one CXL emulated device (+ the proposed code in
> the ADC in the above patch set).  For the CXL device, working around
> this limitation is straight forward if that's the right option
> + updating the docs to slightly reduced chances of this being hit in
> the future.
> 
> Thanks,
> 
> Jonathan



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

* Re: RFC: Memory region accesses where .valid.min_access_size < .impl.min_access_size
  2021-05-13 13:00     ` Jonathan Cameron
  2021-05-13 13:32       ` Philippe Mathieu-Daudé
@ 2021-05-14  2:05       ` Andrew Jeffery
  2021-05-14  9:39         ` Jonathan Cameron
  1 sibling, 1 reply; 7+ messages in thread
From: Andrew Jeffery @ 2021-05-14  2:05 UTC (permalink / raw)
  To: Jonathan Cameron, Philippe Mathieu-Daudé
  Cc: Peter Maydell, Ben Widawsky, Michael S. Tsirkin,
	Francisco Iglesias, David Hildenbrand, Chris Browy, Linuxarm,
	Peter Xu, Cameron Esfahani via, Igor Mammedov, Paolo Bonzini,
	Dan Williams, Alex Bennée



On Thu, 13 May 2021, at 22:30, Jonathan Cameron wrote:
> On Thu, 13 May 2021 14:36:27 +0200
> Philippe Mathieu-Daudé <philmd@redhat.com> wrote:
> 
> > On 5/13/21 2:23 PM, Peter Maydell wrote:
> > > On Thu, 13 May 2021 at 12:49, Jonathan Cameron
> > > <Jonathan.Cameron@huawei.com> wrote:  
> > >> My initial suggestion was to fix this by adding the relatively
> > >> simple code needed in the driver to implement byte read / write,
> > >> but Ben pointed at the QEMU docs - docs/devel/memory.rst which
> > >> says
> > >> "
> > >> .impl.min_access_size, .impl.max_access_size define the access sizes
> > >>    (in bytes) supported by the *implementation*; other access sizes will be
> > >>    emulated using the ones available. For example a 4-byte write will be
> > >>    emulated using four 1-byte writes, if .impl.max_access_size = 1.
> > >> "
> > >>
> > >> This isn't true when we have the situation where
> > >> .valid.min_access_size < .imp.min_access_size
> > >>
> > >> So change the docs or try to make this work?  
> > 
> > See also this patch from Francisco:
> > https://www.mail-archive.com/qemu-devel@nongnu.org/msg636935.html
> > 
> > And full unaligned access support from Andrew:
> > https://www.mail-archive.com/qemu-devel@nongnu.org/msg461247.html

Much better to use lore.kernel.org:

https://lore.kernel.org/qemu-devel/20170630030058.28943-1-andrew@aj.id.au/

because...

> 
> Thanks - that's very similar to what I was carrying, but I think it
> only covers the read case.  That's backed up by the comment:
> /* XXX: Can't do this hack for writes */

It becomes easier to find Paolo's suggestion to fix that here:

https://lore.kernel.org/qemu-devel/cd1aba90-176f-9ec6-3e2b-d1135156a96d@redhat.com/

Would love to see this resolved! Unfortunately I haven't had the 
bandwidth to fix it all up for ... a long time now.

Andrew


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

* Re: RFC: Memory region accesses where .valid.min_access_size < .impl.min_access_size
  2021-05-14  2:05       ` Andrew Jeffery
@ 2021-05-14  9:39         ` Jonathan Cameron
  0 siblings, 0 replies; 7+ messages in thread
From: Jonathan Cameron @ 2021-05-14  9:39 UTC (permalink / raw)
  To: Andrew Jeffery
  Cc: Peter Maydell, Ben Widawsky, Michael S. Tsirkin,
	Francisco Iglesias, David Hildenbrand, Chris Browy, Linuxarm,
	Peter Xu, Cameron Esfahani via, Alex Bennée, Igor Mammedov,
	Paolo Bonzini, Dan Williams, Philippe Mathieu-Daudé

On Fri, 14 May 2021 11:35:57 +0930
"Andrew Jeffery" <andrew@aj.id.au> wrote:

> On Thu, 13 May 2021, at 22:30, Jonathan Cameron wrote:
> > On Thu, 13 May 2021 14:36:27 +0200
> > Philippe Mathieu-Daudé <philmd@redhat.com> wrote:
> >   
> > > On 5/13/21 2:23 PM, Peter Maydell wrote:  
> > > > On Thu, 13 May 2021 at 12:49, Jonathan Cameron
> > > > <Jonathan.Cameron@huawei.com> wrote:    
> > > >> My initial suggestion was to fix this by adding the relatively
> > > >> simple code needed in the driver to implement byte read / write,
> > > >> but Ben pointed at the QEMU docs - docs/devel/memory.rst which
> > > >> says
> > > >> "
> > > >> .impl.min_access_size, .impl.max_access_size define the access sizes
> > > >>    (in bytes) supported by the *implementation*; other access sizes will be
> > > >>    emulated using the ones available. For example a 4-byte write will be
> > > >>    emulated using four 1-byte writes, if .impl.max_access_size = 1.
> > > >> "
> > > >>
> > > >> This isn't true when we have the situation where
> > > >> .valid.min_access_size < .imp.min_access_size
> > > >>
> > > >> So change the docs or try to make this work?    
> > > 
> > > See also this patch from Francisco:
> > > https://www.mail-archive.com/qemu-devel@nongnu.org/msg636935.html
> > > 
> > > And full unaligned access support from Andrew:
> > > https://www.mail-archive.com/qemu-devel@nongnu.org/msg461247.html  
> 
> Much better to use lore.kernel.org:
> 
> https://lore.kernel.org/qemu-devel/20170630030058.28943-1-andrew@aj.id.au/
> 
> because...
> 
> > 
> > Thanks - that's very similar to what I was carrying, but I think it
> > only covers the read case.  That's backed up by the comment:
> > /* XXX: Can't do this hack for writes */  
> 
> It becomes easier to find Paolo's suggestion to fix that here:
> 
> https://lore.kernel.org/qemu-devel/cd1aba90-176f-9ec6-3e2b-d1135156a96d@redhat.com/
> 
> Would love to see this resolved! Unfortunately I haven't had the 
> bandwidth to fix it all up for ... a long time now.
> 

There is a bigger issue with writes.  You have to do a RMW cycle
because we only want to update part of a larger region.

It would worry me that this might have unexpected side effects
in some device implementations. It also looks a bit fiddly to do given
we'll need to pass the read callbacks to the write functions.

So the read path is straight forwards, but write less so.

Jonathan


> Andrew



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

end of thread, other threads:[~2021-05-14  9:42 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-13 11:47 RFC: Memory region accesses where .valid.min_access_size < .impl.min_access_size Jonathan Cameron
2021-05-13 12:23 ` Peter Maydell
2021-05-13 12:36   ` Philippe Mathieu-Daudé
2021-05-13 13:00     ` Jonathan Cameron
2021-05-13 13:32       ` Philippe Mathieu-Daudé
2021-05-14  2:05       ` Andrew Jeffery
2021-05-14  9:39         ` Jonathan Cameron

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.