[PULL v1 3/3] xen: mapcache: Fix unmapping of first entries in buckets

2024-07-12 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

This fixes the clobbering of the entry->next pointer when
unmapping the first entry in a bucket of a mapcache.

Fixes: 123acd816d ("xen: mapcache: Unmap first entries in buckets")
Reported-by: Anthony PERARD 
Signed-off-by: Edgar E. Iglesias 
Reviewed-by: Anthony PERARD 
Reviewed-by: Stefano Stabellini 
---
 hw/xen/xen-mapcache.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
index 5f23b0adbe..18ba7b1d8f 100644
--- a/hw/xen/xen-mapcache.c
+++ b/hw/xen/xen-mapcache.c
@@ -597,7 +597,17 @@ static void 
xen_invalidate_map_cache_entry_unlocked(MapCache *mc,
 pentry->next = entry->next;
 g_free(entry);
 } else {
-memset(entry, 0, sizeof *entry);
+/*
+ * Invalidate mapping but keep entry->next pointing to the rest
+ * of the list.
+ *
+ * Note that lock is already zero here, otherwise we don't unmap.
+ */
+entry->paddr_index = 0;
+entry->vaddr_base = NULL;
+entry->valid_mapping = NULL;
+entry->flags = 0;
+entry->size = 0;
 }
 }
 
-- 
2.43.0




Re: [PATCH v1 2/2] xen: mapcache: Fix unmapping of first entries in buckets

2024-07-06 Thread Edgar E. Iglesias
On Thu, Jul 4, 2024 at 9:48 PM Edgar E. Iglesias 
wrote:

> On Thu, Jul 04, 2024 at 05:44:52PM +0100, Alex Bennée wrote:
> > Anthony PERARD  writes:
> >
> > > On Tue, Jul 02, 2024 at 12:44:21AM +0200, Edgar E. Iglesias wrote:
> > >> From: "Edgar E. Iglesias" 
> > >>
> > >> This fixes the clobbering of the entry->next pointer when
> > >> unmapping the first entry in a bucket of a mapcache.
> > >>
> > >> Fixes: 123acd816d ("xen: mapcache: Unmap first entries in buckets")
> > >> Reported-by: Anthony PERARD 
> > >> Signed-off-by: Edgar E. Iglesias 
> > >> ---
> > >>  hw/xen/xen-mapcache.c | 12 +++-
> > >>  1 file changed, 11 insertions(+), 1 deletion(-)
> > >>
> > >> diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
> > >> index 5f23b0adbe..18ba7b1d8f 100644
> > >> --- a/hw/xen/xen-mapcache.c
> > >> +++ b/hw/xen/xen-mapcache.c
> > >> @@ -597,7 +597,17 @@ static void
> xen_invalidate_map_cache_entry_unlocked(MapCache *mc,
> > >>  pentry->next = entry->next;
> > >>  g_free(entry);
> > >>  } else {
> > >> -memset(entry, 0, sizeof *entry);
> > >> +/*
> > >> + * Invalidate mapping but keep entry->next pointing to the
> rest
> > >> + * of the list.
> > >> + *
> > >> + * Note that lock is already zero here, otherwise we don't
> unmap.
> > >> + */
> > >> +entry->paddr_index = 0;
> > >> +entry->vaddr_base = NULL;
> > >> +entry->valid_mapping = NULL;
> > >> +entry->flags = 0;
> > >> +entry->size = 0;
> > >
> > > This kind of feels like mc->entry should be an array of pointer rather
> > > than an array of MapCacheEntry but that seems to work well enough and
> > > not the first time entries are been cleared like that.
> >
> > The use of a hand rolled list is a bit of a concern considering QEMU and
> > Glib both provide various abstractions used around the rest of the code
> > base. The original patch that introduces the mapcache doesn't tell me
> > much about access patterns for the cache, just that it is trying to
> > solve memory exhaustion issues with lots of dynamic small mappings.
> >
> > Maybe a simpler structure is desirable?
> >
> > We also have an interval tree implementation ("qemu/interval-tree.h") if
> > what we really want is a sorted tree of memory that can be iterated
> > locklessly.
> >
>
> Yes, it would be interesting to benchmark other options.
> I agree that we should at minimum reuse existing lists/hash tables.
>
> We've also had some discussions around removing it partially or
> alltogether but
> there are some concerns around that. We're going to need something to
> keep track of grants. For 32-bit hosts, it's a problem to exhaust virtual
> address-space if mapping all of the guest (are folks still using 32-bit
> hosts?).
> There may be other issues aswell.
>
> Some benefits are that we'll remove some of the complexity and latency for
> mapping
> and unmapping stuff continously.
>
>
One more thing I forgot to add is that IMO, these larger longer term
changes should not block this tiny bugfix...

Cheers,
Edgar


Re: [PATCH v1 2/2] xen: mapcache: Fix unmapping of first entries in buckets

2024-07-04 Thread Edgar E. Iglesias
On Thu, Jul 04, 2024 at 05:44:52PM +0100, Alex Bennée wrote:
> Anthony PERARD  writes:
> 
> > On Tue, Jul 02, 2024 at 12:44:21AM +0200, Edgar E. Iglesias wrote:
> >> From: "Edgar E. Iglesias" 
> >> 
> >> This fixes the clobbering of the entry->next pointer when
> >> unmapping the first entry in a bucket of a mapcache.
> >> 
> >> Fixes: 123acd816d ("xen: mapcache: Unmap first entries in buckets")
> >> Reported-by: Anthony PERARD 
> >> Signed-off-by: Edgar E. Iglesias 
> >> ---
> >>  hw/xen/xen-mapcache.c | 12 +++-
> >>  1 file changed, 11 insertions(+), 1 deletion(-)
> >> 
> >> diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
> >> index 5f23b0adbe..18ba7b1d8f 100644
> >> --- a/hw/xen/xen-mapcache.c
> >> +++ b/hw/xen/xen-mapcache.c
> >> @@ -597,7 +597,17 @@ static void 
> >> xen_invalidate_map_cache_entry_unlocked(MapCache *mc,
> >>  pentry->next = entry->next;
> >>  g_free(entry);
> >>  } else {
> >> -memset(entry, 0, sizeof *entry);
> >> +/*
> >> + * Invalidate mapping but keep entry->next pointing to the rest
> >> + * of the list.
> >> + *
> >> + * Note that lock is already zero here, otherwise we don't unmap.
> >> + */
> >> +entry->paddr_index = 0;
> >> +entry->vaddr_base = NULL;
> >> +entry->valid_mapping = NULL;
> >> +entry->flags = 0;
> >> +entry->size = 0;
> >
> > This kind of feels like mc->entry should be an array of pointer rather
> > than an array of MapCacheEntry but that seems to work well enough and
> > not the first time entries are been cleared like that.
> 
> The use of a hand rolled list is a bit of a concern considering QEMU and
> Glib both provide various abstractions used around the rest of the code
> base. The original patch that introduces the mapcache doesn't tell me
> much about access patterns for the cache, just that it is trying to
> solve memory exhaustion issues with lots of dynamic small mappings.
> 
> Maybe a simpler structure is desirable?
> 
> We also have an interval tree implementation ("qemu/interval-tree.h") if
> what we really want is a sorted tree of memory that can be iterated
> locklessly.
> 

Yes, it would be interesting to benchmark other options.
I agree that we should at minimum reuse existing lists/hash tables.

We've also had some discussions around removing it partially or alltogether but
there are some concerns around that. We're going to need something to
keep track of grants. For 32-bit hosts, it's a problem to exhaust virtual
address-space if mapping all of the guest (are folks still using 32-bit hosts?).
There may be other issues aswell.

Some benefits are that we'll remove some of the complexity and latency for 
mapping
and unmapping stuff continously.

Cheers,
Edgar



Re: [PATCH v1 1/2] physmem: Bail out qemu_ram_block_from_host() for invalid ram addrs

2024-07-04 Thread Edgar E. Iglesias
On Thu, Jul 4, 2024 at 1:26 PM Alex Bennée  wrote:

> "Edgar E. Iglesias"  writes:
>
> > From: "Edgar E. Iglesias" 
> >
> > Bail out in qemu_ram_block_from_host() when
> > xen_ram_addr_from_mapcache() does not find an existing
> > mapping.
> >
> > Signed-off-by: Edgar E. Iglesias 
> > ---
> >  system/physmem.c | 4 
> >  1 file changed, 4 insertions(+)
> >
> > diff --git a/system/physmem.c b/system/physmem.c
> > index 33d09f7571..59d1576c2b 100644
> > --- a/system/physmem.c
> > +++ b/system/physmem.c
> > @@ -2277,6 +2277,10 @@ RAMBlock *qemu_ram_block_from_host(void *ptr,
> bool round_offset,
> >  ram_addr_t ram_addr;
> >  RCU_READ_LOCK_GUARD();
> >  ram_addr = xen_ram_addr_from_mapcache(ptr);
> > +if (ram_addr == RAM_ADDR_INVALID) {
> > +return NULL;
> > +}
> > +
>
> Isn't this indicative of a failure? Should there at least be a trace
> point for failed mappings?
>
>
Yes but there are already trace points for the failure cases inside
xen_ram_addr_from_mapcache().
Do those address your concerns or do you think we need additional trace
points?

Cheers,
Edgar


> >  block = qemu_get_ram_block(ram_addr);
> >  if (block) {
> >  *offset = ram_addr - block->offset;
>
> --
> Alex Bennée
> Virtualisation Tech Lead @ Linaro
>


[PATCH v1 1/2] physmem: Bail out qemu_ram_block_from_host() for invalid ram addrs

2024-07-01 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Bail out in qemu_ram_block_from_host() when
xen_ram_addr_from_mapcache() does not find an existing
mapping.

Signed-off-by: Edgar E. Iglesias 
---
 system/physmem.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/system/physmem.c b/system/physmem.c
index 33d09f7571..59d1576c2b 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -2277,6 +2277,10 @@ RAMBlock *qemu_ram_block_from_host(void *ptr, bool 
round_offset,
 ram_addr_t ram_addr;
 RCU_READ_LOCK_GUARD();
 ram_addr = xen_ram_addr_from_mapcache(ptr);
+if (ram_addr == RAM_ADDR_INVALID) {
+return NULL;
+}
+
 block = qemu_get_ram_block(ram_addr);
 if (block) {
 *offset = ram_addr - block->offset;
-- 
2.43.0




[PATCH v1 0/2] xen: mapcache: Fix unmapping of first the entry in a bucket

2024-07-01 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

This fixes the unmapping of the first mapping in a bucket of a mapcache.

We also add error handling to qemu_ram_block_from_host() to bail out when
xen_ram_addr_from_mapcache() doesn't find an existing mapping.

Cheers,
Edgar

Edgar E. Iglesias (2):
  physmem: Bail out qemu_ram_block_from_host() for invalid ram addrs
  xen: mapcache: Fix unmapping of first entries in buckets

 hw/xen/xen-mapcache.c | 12 +++-
 system/physmem.c  |  4 
 2 files changed, 15 insertions(+), 1 deletion(-)

-- 
2.43.0




[PATCH v1 2/2] xen: mapcache: Fix unmapping of first entries in buckets

2024-07-01 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

This fixes the clobbering of the entry->next pointer when
unmapping the first entry in a bucket of a mapcache.

Fixes: 123acd816d ("xen: mapcache: Unmap first entries in buckets")
Reported-by: Anthony PERARD 
Signed-off-by: Edgar E. Iglesias 
---
 hw/xen/xen-mapcache.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
index 5f23b0adbe..18ba7b1d8f 100644
--- a/hw/xen/xen-mapcache.c
+++ b/hw/xen/xen-mapcache.c
@@ -597,7 +597,17 @@ static void 
xen_invalidate_map_cache_entry_unlocked(MapCache *mc,
 pentry->next = entry->next;
 g_free(entry);
 } else {
-memset(entry, 0, sizeof *entry);
+/*
+ * Invalidate mapping but keep entry->next pointing to the rest
+ * of the list.
+ *
+ * Note that lock is already zero here, otherwise we don't unmap.
+ */
+entry->paddr_index = 0;
+entry->vaddr_base = NULL;
+entry->valid_mapping = NULL;
+entry->flags = 0;
+entry->size = 0;
 }
 }
 
-- 
2.43.0




Re: [PATCH v8 2/8] xen: mapcache: Unmap first entries in buckets

2024-07-01 Thread Edgar E. Iglesias
On Mon, Jul 1, 2024 at 6:21 PM Anthony PERARD 
wrote:

> On Mon, Jul 01, 2024 at 04:34:53PM +0200, Edgar E. Iglesias wrote:
> > On Mon, Jul 1, 2024 at 4:30 PM Edgar E. Iglesias <
> edgar.igles...@gmail.com>
> > wrote:
> > > On Mon, Jul 1, 2024 at 3:58 PM Edgar E. Iglesias <
> edgar.igles...@gmail.com>
> > > wrote:
> > >> Any chance you could try to get a backtrace from QEMU when it failed?
>
> Here it is:
>
>
> #3  0x7fa8762f4472 in __GI_abort () at ./stdlib/abort.c:79
> save_stage = 1
> act = {__sigaction_handler = {sa_handler = 0x20, sa_sigaction =
> 0x20}, sa_mask = {__val = {94603440166168, 18446744073709551615,
> 94603406369640, 0, 0, 94603406346720, 94603440166168, 140361486774256, 0,
> 140361486773376, 94603401285536, 140361496232688, 94603440166096,
> 140361486773456, 94603401289576, 140360849280256}}, sa_flags = -1804462896,
> sa_restorer = 0x748f2d40}
> #4  0x560a92230f0d in qemu_get_ram_block (addr=18446744073709551615)
> at ../system/physmem.c:801
> block = 0x0
> #5  0x560a922350ab in qemu_ram_block_from_host (ptr=0x7fa84e8fcd00,
> round_offset=false, offset=0x7fa8748f2de8) at ../system/physmem.c:2280
> ram_addr = 18446744073709551615
> _rcu_read_auto = 0x1
> block = 0x0
> host = 0x7fa84e8fcd00 ""
> _rcu_read_auto = 0x7fa8751f8288
> #6  0x560a92229669 in memory_region_from_host (ptr=0x7fa84e8fcd00,
> offset=0x7fa8748f2de8) at ../system/memory.c:2440
> block = 0x0
> #7  0x560a92237418 in address_space_unmap (as=0x560a94b05a20,
> buffer=0x7fa84e8fcd00, len=32768, is_write=true, access_len=32768) at
> ../system/physmem.c:3246
> mr = 0x0
> addr1 = 0
> __PRETTY_FUNCTION__ = "address_space_unmap"
> #8  0x560a91fd6cd3 in dma_memory_unmap (as=0x560a94b05a20,
> buffer=0x7fa84e8fcd00, len=32768, dir=DMA_DIRECTION_FROM_DEVICE,
> access_len=32768) at /root/build/qemu/include/sysemu/dma.h:236
> #9  0x560a91fd763d in dma_blk_unmap (dbs=0x560a94d87400) at
> ../system/dma-helpers.c:93
> i = 1
> #10 0x560a91fd76e6 in dma_complete (dbs=0x560a94d87400, ret=0) at
> ../system/dma-helpers.c:105
> __PRETTY_FUNCTION__ = "dma_complete"
> #11 0x560a91fd781c in dma_blk_cb (opaque=0x560a94d87400, ret=0) at
> ../system/dma-helpers.c:129
> dbs = 0x560a94d87400
> ctx = 0x560a9448da90
> cur_addr = 0
> cur_len = 0
> mem = 0x0
> __PRETTY_FUNCTION__ = "dma_blk_cb"
> #12 0x560a9232e974 in blk_aio_complete (acb=0x560a9448d5f0) at
> ../block/block-backend.c:1555
> #13 0x560a9232ebd1 in blk_aio_read_entry (opaque=0x560a9448d5f0) at
> ../block/block-backend.c:1610
> acb = 0x560a9448d5f0
> rwco = 0x560a9448d618
> qiov = 0x560a94d87460
> __PRETTY_FUNCTION__ = "blk_aio_read_entry"
>
> > > One more thing, regarding this specific patch. I don't think we should
> > > clear the
> > > entire entry, the next field should be kept, otherwise we'll disconnect
> > > following
> > > mappings that will never be found again. IIUC, this could very well be
> > > causing the problem you see.
> > >
> > > Does the following make sense?
> > >
> > And here without double-freeing entry->valid_mapping:
> >
> > diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
> > index 5f23b0adbe..667807b3b6 100644
> > --- a/hw/xen/xen-mapcache.c
> > +++ b/hw/xen/xen-mapcache.c
> > @@ -597,7 +597,13 @@ static void
> > xen_invalidate_map_cache_entry_unlocked(MapCache *mc,
> >  pentry->next = entry->next;
> >  g_free(entry);
> >  } else {
> > -memset(entry, 0, sizeof *entry);
> > +/* Invalidate mapping.  */
> > +entry->paddr_index = 0;
> > +entry->vaddr_base = NULL;
> > +entry->size = 0;
> > +entry->valid_mapping = NULL;
> > +entry->flags = 0;
> > +/* Keep entry->next pointing to the rest of the list.  */
> >  }
> >  }
>
> I've tried this patch, and that fix the issue I've seen. I'll run more
> tests on it, just in case, but there's no reason that would break
> something else.
>
> Cheers,
>

Thanks Anthony, I'll send out a proper patch tomorrow.

Cheers,
Edgar


Re: [PATCH v8 2/8] xen: mapcache: Unmap first entries in buckets

2024-07-01 Thread Edgar E. Iglesias
On Mon, Jul 1, 2024 at 4:30 PM Edgar E. Iglesias 
wrote:

>
>
> On Mon, Jul 1, 2024 at 3:58 PM Edgar E. Iglesias 
> wrote:
>
>> On Mon, Jul 1, 2024 at 2:55 PM Anthony PERARD 
>> wrote:
>>
>>> Hi all,
>>>
>>> Following this commit, a test which install Debian in a guest with OVMF
>>> as firmware started to fail. QEMU exit with an error when GRUB is
>>> running on the freshly installed Debian (I don't know if GRUB is
>>> starting Linux or not).
>>> The error is:
>>> Bad ram offset 
>>>
>>> Some logs:
>>>
>>> http://logs.test-lab.xenproject.org/osstest/logs/186611/test-amd64-amd64-xl-qemuu-ovmf-amd64/info.html
>>>
>>> Any idea? Something is trying to do something with the address "-1" when
>>> it shouldn't?
>>>
>>>
>> Hi Anothny,
>>
>> Yes, it looks like something is calling qemu_get_ram_block() on something
>> that isn't mapped.
>> One possible path is in qemu_ram_block_from_host() but there may be
>> others.
>>
>> The following patch may help.
>> Any chance you could try to get a backtrace from QEMU when it failed?
>>
>> diff --git a/system/physmem.c b/system/physmem.c
>> index 33d09f7571..2669c4dbbb 100644
>> --- a/system/physmem.c
>> +++ b/system/physmem.c
>> @@ -2277,6 +2277,9 @@ RAMBlock *qemu_ram_block_from_host(void *ptr, bool
>> round_offset,
>>  ram_addr_t ram_addr;
>>  RCU_READ_LOCK_GUARD();
>>  ram_addr = xen_ram_addr_from_mapcache(ptr);
>> +if (ram_addr == RAM_ADDR_INVALID) {
>> +return NULL;
>> +}
>>  block = qemu_get_ram_block(ram_addr);
>>  if (block) {
>>  *offset = ram_addr - block->offset;
>>
>>
>>
> One more thing, regarding this specific patch. I don't think we should
> clear the
> entire entry, the next field should be kept, otherwise we'll disconnect
> following
> mappings that will never be found again. IIUC, this could very well be
> causing the problem you see.
>
> Does the following make sense?
>
> diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
> index 5f23b0adbe..e9df53c19d 100644
> --- a/hw/xen/xen-mapcache.c
> +++ b/hw/xen/xen-mapcache.c
> @@ -597,7 +597,14 @@ static void
> xen_invalidate_map_cache_entry_unlocked(MapCache *mc,
>  pentry->next = entry->next;
>  g_free(entry);
>  } else {
> -memset(entry, 0, sizeof *entry);
> +/* Invalidate mapping.  */
> +entry->paddr_index = 0;
> +entry->vaddr_base = NULL;
> +entry->size = 0;
> +g_free(entry->valid_mapping);
> +entry->valid_mapping = NULL;
> +entry->flags = 0;
> +/* Keep entry->next pointing to the rest of the list.  */
>  }
>  }
>
>
>

And here without double-freeing entry->valid_mapping:

diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
index 5f23b0adbe..667807b3b6 100644
--- a/hw/xen/xen-mapcache.c
+++ b/hw/xen/xen-mapcache.c
@@ -597,7 +597,13 @@ static void
xen_invalidate_map_cache_entry_unlocked(MapCache *mc,
 pentry->next = entry->next;
 g_free(entry);
 } else {
-memset(entry, 0, sizeof *entry);
+/* Invalidate mapping.  */
+entry->paddr_index = 0;
+entry->vaddr_base = NULL;
+entry->size = 0;
+entry->valid_mapping = NULL;
+entry->flags = 0;
+/* Keep entry->next pointing to the rest of the list.  */
 }
 }


Re: [PATCH v8 2/8] xen: mapcache: Unmap first entries in buckets

2024-07-01 Thread Edgar E. Iglesias
On Mon, Jul 1, 2024 at 3:58 PM Edgar E. Iglesias 
wrote:

> On Mon, Jul 1, 2024 at 2:55 PM Anthony PERARD 
> wrote:
>
>> Hi all,
>>
>> Following this commit, a test which install Debian in a guest with OVMF
>> as firmware started to fail. QEMU exit with an error when GRUB is
>> running on the freshly installed Debian (I don't know if GRUB is
>> starting Linux or not).
>> The error is:
>> Bad ram offset 
>>
>> Some logs:
>>
>> http://logs.test-lab.xenproject.org/osstest/logs/186611/test-amd64-amd64-xl-qemuu-ovmf-amd64/info.html
>>
>> Any idea? Something is trying to do something with the address "-1" when
>> it shouldn't?
>>
>>
> Hi Anothny,
>
> Yes, it looks like something is calling qemu_get_ram_block() on something
> that isn't mapped.
> One possible path is in qemu_ram_block_from_host() but there may be others.
>
> The following patch may help.
> Any chance you could try to get a backtrace from QEMU when it failed?
>
> diff --git a/system/physmem.c b/system/physmem.c
> index 33d09f7571..2669c4dbbb 100644
> --- a/system/physmem.c
> +++ b/system/physmem.c
> @@ -2277,6 +2277,9 @@ RAMBlock *qemu_ram_block_from_host(void *ptr, bool
> round_offset,
>  ram_addr_t ram_addr;
>  RCU_READ_LOCK_GUARD();
>  ram_addr = xen_ram_addr_from_mapcache(ptr);
> +if (ram_addr == RAM_ADDR_INVALID) {
> +return NULL;
> +}
>  block = qemu_get_ram_block(ram_addr);
>  if (block) {
>  *offset = ram_addr - block->offset;
>
>
>
One more thing, regarding this specific patch. I don't think we should
clear the
entire entry, the next field should be kept, otherwise we'll disconnect
following
mappings that will never be found again. IIUC, this could very well be
causing the problem you see.

Does the following make sense?

diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
index 5f23b0adbe..e9df53c19d 100644
--- a/hw/xen/xen-mapcache.c
+++ b/hw/xen/xen-mapcache.c
@@ -597,7 +597,14 @@ static void
xen_invalidate_map_cache_entry_unlocked(MapCache *mc,
 pentry->next = entry->next;
 g_free(entry);
 } else {
-memset(entry, 0, sizeof *entry);
+/* Invalidate mapping.  */
+entry->paddr_index = 0;
+entry->vaddr_base = NULL;
+entry->size = 0;
+g_free(entry->valid_mapping);
+entry->valid_mapping = NULL;
+    entry->flags = 0;
+/* Keep entry->next pointing to the rest of the list.  */
 }
 }









>
>
>> Cheers,
>>
>> Anthony
>>
>> On Wed, May 29, 2024 at 04:07:33PM +0200, Edgar E. Iglesias wrote:
>> > From: "Edgar E. Iglesias" 
>> >
>> > When invalidating memory ranges, if we happen to hit the first
>> > entry in a bucket we were never unmapping it. This was harmless
>> > for foreign mappings but now that we're looking to reuse the
>> > mapcache for transient grant mappings, we must unmap entries
>> > when invalidated.
>> >
>> > Signed-off-by: Edgar E. Iglesias 
>> > Reviewed-by: Stefano Stabellini 
>> > ---
>> >  hw/xen/xen-mapcache.c | 11 ---
>> >  1 file changed, 8 insertions(+), 3 deletions(-)
>> >
>> > diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
>> > index bc860f4373..ec95445696 100644
>> > --- a/hw/xen/xen-mapcache.c
>> > +++ b/hw/xen/xen-mapcache.c
>> > @@ -491,18 +491,23 @@ static void
>> xen_invalidate_map_cache_entry_unlocked(MapCache *mc,
>> >  return;
>> >  }
>> >  entry->lock--;
>> > -if (entry->lock > 0 || pentry == NULL) {
>> > +if (entry->lock > 0) {
>> >  return;
>> >  }
>> >
>> > -pentry->next = entry->next;
>> >  ram_block_notify_remove(entry->vaddr_base, entry->size,
>> entry->size);
>> >  if (munmap(entry->vaddr_base, entry->size) != 0) {
>> >  perror("unmap fails");
>> >  exit(-1);
>> >  }
>> > +
>> >  g_free(entry->valid_mapping);
>> > -g_free(entry);
>> > +if (pentry) {
>> > +pentry->next = entry->next;
>> > +g_free(entry);
>> > +} else {
>> > +memset(entry, 0, sizeof *entry);
>> > +}
>> >  }
>> >
>> >  typedef struct XenMapCacheData {
>> > --
>> > 2.40.1
>> >
>> >
>> --
>>
>> Anthony Perard | Vates XCP-ng Developer
>>
>> XCP-ng & Xen Orchestra - Vates solutions
>>
>> web: https://vates.tech
>>
>


Re: [PATCH v8 2/8] xen: mapcache: Unmap first entries in buckets

2024-07-01 Thread Edgar E. Iglesias
On Mon, Jul 1, 2024 at 2:55 PM Anthony PERARD 
wrote:

> Hi all,
>
> Following this commit, a test which install Debian in a guest with OVMF
> as firmware started to fail. QEMU exit with an error when GRUB is
> running on the freshly installed Debian (I don't know if GRUB is
> starting Linux or not).
> The error is:
> Bad ram offset 
>
> Some logs:
>
> http://logs.test-lab.xenproject.org/osstest/logs/186611/test-amd64-amd64-xl-qemuu-ovmf-amd64/info.html
>
> Any idea? Something is trying to do something with the address "-1" when
> it shouldn't?
>
>
Hi Anothny,

Yes, it looks like something is calling qemu_get_ram_block() on something
that isn't mapped.
One possible path is in qemu_ram_block_from_host() but there may be others.

The following patch may help.
Any chance you could try to get a backtrace from QEMU when it failed?

diff --git a/system/physmem.c b/system/physmem.c
index 33d09f7571..2669c4dbbb 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -2277,6 +2277,9 @@ RAMBlock *qemu_ram_block_from_host(void *ptr, bool
round_offset,
 ram_addr_t ram_addr;
 RCU_READ_LOCK_GUARD();
 ram_addr = xen_ram_addr_from_mapcache(ptr);
+if (ram_addr == RAM_ADDR_INVALID) {
+return NULL;
+}
 block = qemu_get_ram_block(ram_addr);
 if (block) {
 *offset = ram_addr - block->offset;





> Cheers,
>
> Anthony
>
> On Wed, May 29, 2024 at 04:07:33PM +0200, Edgar E. Iglesias wrote:
> > From: "Edgar E. Iglesias" 
> >
> > When invalidating memory ranges, if we happen to hit the first
> > entry in a bucket we were never unmapping it. This was harmless
> > for foreign mappings but now that we're looking to reuse the
> > mapcache for transient grant mappings, we must unmap entries
> > when invalidated.
> >
> > Signed-off-by: Edgar E. Iglesias 
> > Reviewed-by: Stefano Stabellini 
> > ---
> >  hw/xen/xen-mapcache.c | 11 ---
> >  1 file changed, 8 insertions(+), 3 deletions(-)
> >
> > diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
> > index bc860f4373..ec95445696 100644
> > --- a/hw/xen/xen-mapcache.c
> > +++ b/hw/xen/xen-mapcache.c
> > @@ -491,18 +491,23 @@ static void
> xen_invalidate_map_cache_entry_unlocked(MapCache *mc,
> >  return;
> >  }
> >  entry->lock--;
> > -if (entry->lock > 0 || pentry == NULL) {
> > +if (entry->lock > 0) {
> >  return;
> >  }
> >
> > -pentry->next = entry->next;
> >  ram_block_notify_remove(entry->vaddr_base, entry->size,
> entry->size);
> >  if (munmap(entry->vaddr_base, entry->size) != 0) {
> >  perror("unmap fails");
> >  exit(-1);
> >  }
> > +
> >  g_free(entry->valid_mapping);
> > -g_free(entry);
> > +if (pentry) {
> > +pentry->next = entry->next;
> > +g_free(entry);
> > +} else {
> > +memset(entry, 0, sizeof *entry);
> > +}
> >  }
> >
> >  typedef struct XenMapCacheData {
> > --
> > 2.40.1
> >
> >
> --
>
> Anthony Perard | Vates XCP-ng Developer
>
> XCP-ng & Xen Orchestra - Vates solutions
>
> web: https://vates.tech
>


[PATCH v8 1/8] xen: mapcache: Make MCACHE_BUCKET_SHIFT runtime configurable

2024-05-29 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Make MCACHE_BUCKET_SHIFT runtime configurable per cache instance.

Signed-off-by: Edgar E. Iglesias 
Reviewed-by: Stefano Stabellini 
---
 hw/xen/xen-mapcache.c | 54 ++-
 1 file changed, 33 insertions(+), 21 deletions(-)

diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
index fa6813b1ad..bc860f4373 100644
--- a/hw/xen/xen-mapcache.c
+++ b/hw/xen/xen-mapcache.c
@@ -23,13 +23,10 @@
 
 
 #if HOST_LONG_BITS == 32
-#  define MCACHE_BUCKET_SHIFT 16
 #  define MCACHE_MAX_SIZE (1UL<<31) /* 2GB Cap */
 #else
-#  define MCACHE_BUCKET_SHIFT 20
 #  define MCACHE_MAX_SIZE (1UL<<35) /* 32GB Cap */
 #endif
-#define MCACHE_BUCKET_SIZE (1UL << MCACHE_BUCKET_SHIFT)
 
 /* This is the size of the virtual address space reserve to QEMU that will not
  * be use by MapCache.
@@ -65,7 +62,8 @@ typedef struct MapCache {
 /* For most cases (>99.9%), the page address is the same. */
 MapCacheEntry *last_entry;
 unsigned long max_mcache_size;
-unsigned int mcache_bucket_shift;
+unsigned int bucket_shift;
+unsigned long bucket_size;
 
 phys_offset_to_gaddr_t phys_offset_to_gaddr;
 QemuMutex lock;
@@ -95,11 +93,14 @@ static inline int test_bits(int nr, int size, const 
unsigned long *addr)
 
 static MapCache *xen_map_cache_init_single(phys_offset_to_gaddr_t f,
void *opaque,
+   unsigned int bucket_shift,
unsigned long max_size)
 {
 unsigned long size;
 MapCache *mc;
 
+assert(bucket_shift >= XC_PAGE_SHIFT);
+
 mc = g_new0(MapCache, 1);
 
 mc->phys_offset_to_gaddr = f;
@@ -108,12 +109,14 @@ static MapCache 
*xen_map_cache_init_single(phys_offset_to_gaddr_t f,
 
 QTAILQ_INIT(>locked_entries);
 
+mc->bucket_shift = bucket_shift;
+mc->bucket_size = 1UL << bucket_shift;
 mc->max_mcache_size = max_size;
 
 mc->nr_buckets =
 (((mc->max_mcache_size >> XC_PAGE_SHIFT) +
-  (1UL << (MCACHE_BUCKET_SHIFT - XC_PAGE_SHIFT)) - 1) >>
- (MCACHE_BUCKET_SHIFT - XC_PAGE_SHIFT));
+  (1UL << (bucket_shift - XC_PAGE_SHIFT)) - 1) >>
+ (bucket_shift - XC_PAGE_SHIFT));
 
 size = mc->nr_buckets * sizeof(MapCacheEntry);
 size = (size + XC_PAGE_SIZE - 1) & ~(XC_PAGE_SIZE - 1);
@@ -126,6 +129,13 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f, void 
*opaque)
 {
 struct rlimit rlimit_as;
 unsigned long max_mcache_size;
+unsigned int bucket_shift;
+
+if (HOST_LONG_BITS == 32) {
+bucket_shift = 16;
+} else {
+bucket_shift = 20;
+}
 
 if (geteuid() == 0) {
 rlimit_as.rlim_cur = RLIM_INFINITY;
@@ -146,7 +156,9 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f, void 
*opaque)
 }
 }
 
-mapcache = xen_map_cache_init_single(f, opaque, max_mcache_size);
+mapcache = xen_map_cache_init_single(f, opaque,
+ bucket_shift,
+ max_mcache_size);
 setrlimit(RLIMIT_AS, _as);
 }
 
@@ -195,7 +207,7 @@ static void xen_remap_bucket(MapCache *mc,
 entry->valid_mapping = NULL;
 
 for (i = 0; i < nb_pfn; i++) {
-pfns[i] = (address_index << (MCACHE_BUCKET_SHIFT-XC_PAGE_SHIFT)) + i;
+pfns[i] = (address_index << (mc->bucket_shift - XC_PAGE_SHIFT)) + i;
 }
 
 /*
@@ -266,8 +278,8 @@ static uint8_t *xen_map_cache_unlocked(MapCache *mc,
 bool dummy = false;
 
 tryagain:
-address_index  = phys_addr >> MCACHE_BUCKET_SHIFT;
-address_offset = phys_addr & (MCACHE_BUCKET_SIZE - 1);
+address_index  = phys_addr >> mc->bucket_shift;
+address_offset = phys_addr & (mc->bucket_size - 1);
 
 trace_xen_map_cache(phys_addr);
 
@@ -294,14 +306,14 @@ tryagain:
 return mc->last_entry->vaddr_base + address_offset;
 }
 
-/* size is always a multiple of MCACHE_BUCKET_SIZE */
+/* size is always a multiple of mc->bucket_size */
 if (size) {
 cache_size = size + address_offset;
-if (cache_size % MCACHE_BUCKET_SIZE) {
-cache_size += MCACHE_BUCKET_SIZE - (cache_size % 
MCACHE_BUCKET_SIZE);
+if (cache_size % mc->bucket_size) {
+cache_size += mc->bucket_size - (cache_size % mc->bucket_size);
 }
 } else {
-cache_size = MCACHE_BUCKET_SIZE;
+cache_size = mc->bucket_size;
 }
 
 entry = >entry[address_index % mc->nr_buckets];
@@ -422,7 +434,7 @@ static ram_addr_t 
xen_ram_addr_from_mapcache_single(MapCache *mc, void *ptr)
 trace_xen_ram_addr_from_mapcache_not_in_cache(ptr);
 raddr = RAM_ADDR_INVALID;
 } else {
-raddr = (reventry->paddr_index << MCACHE_BUCKET_SHIFT) +
+   

[PATCH v8 7/8] xen: mapcache: Add support for grant mappings

2024-05-29 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Add a second mapcache for grant mappings. The mapcache for
grants needs to work with XC_PAGE_SIZE granularity since
we can't map larger ranges than what has been granted to us.

Like with foreign mappings (xen_memory), machines using grants
are expected to initialize the xen_grants MR and map it
into their address-map accordingly.

CC: Manos Pitsidianakis 
Signed-off-by: Edgar E. Iglesias 
Reviewed-by: Stefano Stabellini 
---
 hw/xen/xen-hvm-common.c |  12 ++-
 hw/xen/xen-mapcache.c   | 165 +---
 include/hw/xen/xen-hvm-common.h |   3 +
 include/sysemu/xen.h|   1 +
 4 files changed, 144 insertions(+), 37 deletions(-)

diff --git a/hw/xen/xen-hvm-common.c b/hw/xen/xen-hvm-common.c
index a0a0252da0..b8ace1c368 100644
--- a/hw/xen/xen-hvm-common.c
+++ b/hw/xen/xen-hvm-common.c
@@ -10,12 +10,18 @@
 #include "hw/boards.h"
 #include "hw/xen/arch_hvm.h"
 
-MemoryRegion xen_memory;
+MemoryRegion xen_memory, xen_grants;
 
-/* Check for xen memory.  */
+/* Check for any kind of xen memory, foreign mappings or grants.  */
 bool xen_mr_is_memory(MemoryRegion *mr)
 {
-return mr == _memory;
+return mr == _memory || mr == _grants;
+}
+
+/* Check specifically for grants.  */
+bool xen_mr_is_grants(MemoryRegion *mr)
+{
+return mr == _grants;
 }
 
 void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr,
diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
index a07c47b0b1..5f23b0adbe 100644
--- a/hw/xen/xen-mapcache.c
+++ b/hw/xen/xen-mapcache.c
@@ -14,6 +14,7 @@
 
 #include 
 
+#include "hw/xen/xen-hvm-common.h"
 #include "hw/xen/xen_native.h"
 #include "qemu/bitmap.h"
 
@@ -21,6 +22,8 @@
 #include "sysemu/xen-mapcache.h"
 #include "trace.h"
 
+#include 
+#include 
 
 #if HOST_LONG_BITS == 32
 #  define MCACHE_MAX_SIZE (1UL<<31) /* 2GB Cap */
@@ -41,6 +44,7 @@ typedef struct MapCacheEntry {
 unsigned long *valid_mapping;
 uint32_t lock;
 #define XEN_MAPCACHE_ENTRY_DUMMY (1 << 0)
+#define XEN_MAPCACHE_ENTRY_GRANT (1 << 1)
 uint8_t flags;
 hwaddr size;
 struct MapCacheEntry *next;
@@ -71,6 +75,8 @@ typedef struct MapCache {
 } MapCache;
 
 static MapCache *mapcache;
+static MapCache *mapcache_grants;
+static xengnttab_handle *xen_region_gnttabdev;
 
 static inline void mapcache_lock(MapCache *mc)
 {
@@ -131,6 +137,12 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f, void 
*opaque)
 unsigned long max_mcache_size;
 unsigned int bucket_shift;
 
+xen_region_gnttabdev = xengnttab_open(NULL, 0);
+if (xen_region_gnttabdev == NULL) {
+error_report("mapcache: Failed to open gnttab device");
+exit(EXIT_FAILURE);
+}
+
 if (HOST_LONG_BITS == 32) {
 bucket_shift = 16;
 } else {
@@ -159,6 +171,15 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f, void 
*opaque)
 mapcache = xen_map_cache_init_single(f, opaque,
  bucket_shift,
  max_mcache_size);
+
+/*
+ * Grant mappings must use XC_PAGE_SIZE granularity since we can't
+ * map anything beyond the number of pages granted to us.
+ */
+mapcache_grants = xen_map_cache_init_single(f, opaque,
+XC_PAGE_SHIFT,
+max_mcache_size);
+
 setrlimit(RLIMIT_AS, _as);
 }
 
@@ -168,17 +189,24 @@ static void xen_remap_bucket(MapCache *mc,
  hwaddr size,
  hwaddr address_index,
  bool dummy,
+ bool grant,
+ bool is_write,
  ram_addr_t ram_offset)
 {
 uint8_t *vaddr_base;
-xen_pfn_t *pfns;
-int *err;
+g_autofree uint32_t *refs = NULL;
+g_autofree xen_pfn_t *pfns = NULL;
+g_autofree int *err;
 unsigned int i;
 hwaddr nb_pfn = size >> XC_PAGE_SHIFT;
 
 trace_xen_remap_bucket(address_index);
 
-pfns = g_new0(xen_pfn_t, nb_pfn);
+if (grant) {
+refs = g_new0(uint32_t, nb_pfn);
+} else {
+pfns = g_new0(xen_pfn_t, nb_pfn);
+}
 err = g_new0(int, nb_pfn);
 
 if (entry->vaddr_base != NULL) {
@@ -207,21 +235,51 @@ static void xen_remap_bucket(MapCache *mc,
 g_free(entry->valid_mapping);
 entry->valid_mapping = NULL;
 
-for (i = 0; i < nb_pfn; i++) {
-pfns[i] = (address_index << (mc->bucket_shift - XC_PAGE_SHIFT)) + i;
+if (grant) {
+hwaddr grant_base = address_index - (ram_offset >> XC_PAGE_SHIFT);
+
+for (i = 0; i < nb_pfn; i++) {
+refs[i] = grant_base + i;
+}
+} else {
+for (i = 0; i < nb_pfn; i++) {
+pfns[i] = (address_index << (mc->bucket_shift 

[PATCH v8 3/8] xen: Add xen_mr_is_memory()

2024-05-29 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Add xen_mr_is_memory() to abstract away tests for the
xen_memory MR.

No functional changes.

Signed-off-by: Edgar E. Iglesias 
Reviewed-by: Stefano Stabellini 
Acked-by: David Hildenbrand 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/xen/xen-hvm-common.c | 10 --
 include/sysemu/xen.h|  1 +
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/hw/xen/xen-hvm-common.c b/hw/xen/xen-hvm-common.c
index 2d1b032121..a0a0252da0 100644
--- a/hw/xen/xen-hvm-common.c
+++ b/hw/xen/xen-hvm-common.c
@@ -12,6 +12,12 @@
 
 MemoryRegion xen_memory;
 
+/* Check for xen memory.  */
+bool xen_mr_is_memory(MemoryRegion *mr)
+{
+return mr == _memory;
+}
+
 void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr,
Error **errp)
 {
@@ -28,7 +34,7 @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, 
MemoryRegion *mr,
 return;
 }
 
-if (mr == _memory) {
+if (xen_mr_is_memory(mr)) {
 return;
 }
 
@@ -55,7 +61,7 @@ static void xen_set_memory(struct MemoryListener *listener,
 {
 XenIOState *state = container_of(listener, XenIOState, memory_listener);
 
-if (section->mr == _memory) {
+if (xen_mr_is_memory(section->mr)) {
 return;
 } else {
 if (add) {
diff --git a/include/sysemu/xen.h b/include/sysemu/xen.h
index 754ec2e6cb..3445888e39 100644
--- a/include/sysemu/xen.h
+++ b/include/sysemu/xen.h
@@ -49,4 +49,5 @@ static inline void xen_ram_alloc(ram_addr_t ram_addr, 
ram_addr_t size,
 
 #endif /* CONFIG_XEN_IS_POSSIBLE */
 
+bool xen_mr_is_memory(MemoryRegion *mr);
 #endif
-- 
2.40.1




[PATCH v8 6/8] xen: mapcache: Pass the ram_addr offset to xen_map_cache()

2024-05-29 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Pass the ram_addr offset to xen_map_cache.
This is in preparation for adding grant mappings that need
to compute the address within the RAMBlock.

No functional changes.

Signed-off-by: Edgar E. Iglesias 
Reviewed-by: David Hildenbrand 
Reviewed-by: Stefano Stabellini 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/xen/xen-mapcache.c | 16 +++-
 include/sysemu/xen-mapcache.h |  2 ++
 system/physmem.c  |  9 +
 3 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
index ec95445696..a07c47b0b1 100644
--- a/hw/xen/xen-mapcache.c
+++ b/hw/xen/xen-mapcache.c
@@ -167,7 +167,8 @@ static void xen_remap_bucket(MapCache *mc,
  void *vaddr,
  hwaddr size,
  hwaddr address_index,
- bool dummy)
+ bool dummy,
+ ram_addr_t ram_offset)
 {
 uint8_t *vaddr_base;
 xen_pfn_t *pfns;
@@ -266,6 +267,7 @@ static void xen_remap_bucket(MapCache *mc,
 
 static uint8_t *xen_map_cache_unlocked(MapCache *mc,
hwaddr phys_addr, hwaddr size,
+   ram_addr_t ram_offset,
uint8_t lock, bool dma, bool is_write)
 {
 MapCacheEntry *entry, *pentry = NULL,
@@ -337,14 +339,16 @@ tryagain:
 if (!entry) {
 entry = g_new0(MapCacheEntry, 1);
 pentry->next = entry;
-xen_remap_bucket(mc, entry, NULL, cache_size, address_index, dummy);
+xen_remap_bucket(mc, entry, NULL, cache_size, address_index, dummy,
+ ram_offset);
 } else if (!entry->lock) {
 if (!entry->vaddr_base || entry->paddr_index != address_index ||
 entry->size != cache_size ||
 !test_bits(address_offset >> XC_PAGE_SHIFT,
 test_bit_size >> XC_PAGE_SHIFT,
 entry->valid_mapping)) {
-xen_remap_bucket(mc, entry, NULL, cache_size, address_index, 
dummy);
+xen_remap_bucket(mc, entry, NULL, cache_size, address_index, dummy,
+ ram_offset);
 }
 }
 
@@ -391,13 +395,15 @@ tryagain:
 
 uint8_t *xen_map_cache(MemoryRegion *mr,
hwaddr phys_addr, hwaddr size,
+   ram_addr_t ram_addr_offset,
uint8_t lock, bool dma,
bool is_write)
 {
 uint8_t *p;
 
 mapcache_lock(mapcache);
-p = xen_map_cache_unlocked(mapcache, phys_addr, size, lock, dma, is_write);
+p = xen_map_cache_unlocked(mapcache, phys_addr, size, ram_addr_offset,
+   lock, dma, is_write);
 mapcache_unlock(mapcache);
 return p;
 }
@@ -632,7 +638,7 @@ static uint8_t *xen_replace_cache_entry_unlocked(MapCache 
*mc,
 trace_xen_replace_cache_entry_dummy(old_phys_addr, new_phys_addr);
 
 xen_remap_bucket(mc, entry, entry->vaddr_base,
- cache_size, address_index, false);
+ cache_size, address_index, false, old_phys_addr);
 if (!test_bits(address_offset >> XC_PAGE_SHIFT,
 test_bit_size >> XC_PAGE_SHIFT,
 entry->valid_mapping)) {
diff --git a/include/sysemu/xen-mapcache.h b/include/sysemu/xen-mapcache.h
index 1ec9e66752..b5e3ea1bc0 100644
--- a/include/sysemu/xen-mapcache.h
+++ b/include/sysemu/xen-mapcache.h
@@ -19,6 +19,7 @@ typedef hwaddr (*phys_offset_to_gaddr_t)(hwaddr phys_offset,
 void xen_map_cache_init(phys_offset_to_gaddr_t f,
 void *opaque);
 uint8_t *xen_map_cache(MemoryRegion *mr, hwaddr phys_addr, hwaddr size,
+   ram_addr_t ram_addr_offset,
uint8_t lock, bool dma,
bool is_write);
 ram_addr_t xen_ram_addr_from_mapcache(void *ptr);
@@ -37,6 +38,7 @@ static inline void xen_map_cache_init(phys_offset_to_gaddr_t 
f,
 static inline uint8_t *xen_map_cache(MemoryRegion *mr,
  hwaddr phys_addr,
  hwaddr size,
+ ram_addr_t ram_addr_offset,
  uint8_t lock,
  bool dma,
  bool is_write)
diff --git a/system/physmem.c b/system/physmem.c
index b7847db1a2..33d09f7571 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -2231,13 +2231,14 @@ static void *qemu_ram_ptr_length(RAMBlock *block, 
ram_addr_t addr,
  */
 if (xen_mr_is_memory(block->mr)) {
 return xen_map_cache(block->mr, block->offset + addr,
- len, lock, lock,
- is_write);
+  

[PATCH v8 2/8] xen: mapcache: Unmap first entries in buckets

2024-05-29 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

When invalidating memory ranges, if we happen to hit the first
entry in a bucket we were never unmapping it. This was harmless
for foreign mappings but now that we're looking to reuse the
mapcache for transient grant mappings, we must unmap entries
when invalidated.

Signed-off-by: Edgar E. Iglesias 
Reviewed-by: Stefano Stabellini 
---
 hw/xen/xen-mapcache.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
index bc860f4373..ec95445696 100644
--- a/hw/xen/xen-mapcache.c
+++ b/hw/xen/xen-mapcache.c
@@ -491,18 +491,23 @@ static void 
xen_invalidate_map_cache_entry_unlocked(MapCache *mc,
 return;
 }
 entry->lock--;
-if (entry->lock > 0 || pentry == NULL) {
+if (entry->lock > 0) {
 return;
 }
 
-pentry->next = entry->next;
 ram_block_notify_remove(entry->vaddr_base, entry->size, entry->size);
 if (munmap(entry->vaddr_base, entry->size) != 0) {
 perror("unmap fails");
 exit(-1);
 }
+
 g_free(entry->valid_mapping);
-g_free(entry);
+if (pentry) {
+pentry->next = entry->next;
+g_free(entry);
+} else {
+memset(entry, 0, sizeof *entry);
+}
 }
 
 typedef struct XenMapCacheData {
-- 
2.40.1




Re: [PATCH v7 3/8] xen: Add xen_mr_is_memory()

2024-05-29 Thread Edgar E. Iglesias
On Mon, May 27, 2024 at 6:25 PM Philippe Mathieu-Daudé 
wrote:

> Hi Edgar,
>
> On 24/5/24 12:51, Edgar E. Iglesias wrote:
> > From: "Edgar E. Iglesias" 
> >
> > Add xen_mr_is_memory() to abstract away tests for the
> > xen_memory MR.
> >
> > No functional changes.
> >
> > Signed-off-by: Edgar E. Iglesias 
> > Reviewed-by: Stefano Stabellini 
> > Acked-by: David Hildenbrand 
> > ---
> >   hw/xen/xen-hvm-common.c | 10 --
> >   include/sysemu/xen.h|  8 
> >   2 files changed, 16 insertions(+), 2 deletions(-)
>
> To consolidate we could add:
>
>static MemoryRegion xen_memory;
>
>MemoryRegion *xen_mr_memory_init(uint64_t block_len)
>{
>   assert(!xen_memory.size);
>   memory_region_init_ram(_memory, NULL, "xen.ram", block_len,
> _fatal);
>   return _memory;
>}
>
> and remove the extern declaration.
>

Thanks,

We have a future patch series in the workings that will add a PVH machine
for x86, I'll keep this in mind for then!


>
> > diff --git a/include/sysemu/xen.h b/include/sysemu/xen.h
> > index 754ec2e6cb..dc72f83bcb 100644
> > --- a/include/sysemu/xen.h
> > +++ b/include/sysemu/xen.h
> > @@ -34,6 +34,8 @@ void xen_hvm_modified_memory(ram_addr_t start,
> ram_addr_t length);
> >   void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size,
> >  struct MemoryRegion *mr, Error **errp);
> >
> > +bool xen_mr_is_memory(MemoryRegion *mr);
> > +
> >   #else /* !CONFIG_XEN_IS_POSSIBLE */
> >
> >   #define xen_enabled() 0
> > @@ -47,6 +49,12 @@ static inline void xen_ram_alloc(ram_addr_t ram_addr,
> ram_addr_t size,
> >   g_assert_not_reached();
> >   }
> >
> > +static inline bool xen_mr_is_memory(MemoryRegion *mr)
> > +{
> > +g_assert_not_reached();
> > +return false;
>
> No need for the stub, just always declare xen_mr_is_memory() ...
> > +}
> > +
> >   #endif /* CONFIG_XEN_IS_POSSIBLE */
>
> ... here.
>
> >   #endif
>
> Removing the stub:
> Reviewed-by: Philippe Mathieu-Daudé 
>
>
Thanks Philippe, will remove the stubs in v8.

Cheers,
Edgar


[PATCH v7 6/8] xen: mapcache: Pass the ram_addr offset to xen_map_cache()

2024-05-24 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Pass the ram_addr offset to xen_map_cache.
This is in preparation for adding grant mappings that need
to compute the address within the RAMBlock.

No functional changes.

Signed-off-by: Edgar E. Iglesias 
Reviewed-by: David Hildenbrand 
Reviewed-by: Stefano Stabellini 
---
 hw/xen/xen-mapcache.c | 16 +++-
 include/sysemu/xen-mapcache.h |  2 ++
 system/physmem.c  |  9 +
 3 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
index ec95445696..a07c47b0b1 100644
--- a/hw/xen/xen-mapcache.c
+++ b/hw/xen/xen-mapcache.c
@@ -167,7 +167,8 @@ static void xen_remap_bucket(MapCache *mc,
  void *vaddr,
  hwaddr size,
  hwaddr address_index,
- bool dummy)
+ bool dummy,
+ ram_addr_t ram_offset)
 {
 uint8_t *vaddr_base;
 xen_pfn_t *pfns;
@@ -266,6 +267,7 @@ static void xen_remap_bucket(MapCache *mc,
 
 static uint8_t *xen_map_cache_unlocked(MapCache *mc,
hwaddr phys_addr, hwaddr size,
+   ram_addr_t ram_offset,
uint8_t lock, bool dma, bool is_write)
 {
 MapCacheEntry *entry, *pentry = NULL,
@@ -337,14 +339,16 @@ tryagain:
 if (!entry) {
 entry = g_new0(MapCacheEntry, 1);
 pentry->next = entry;
-xen_remap_bucket(mc, entry, NULL, cache_size, address_index, dummy);
+xen_remap_bucket(mc, entry, NULL, cache_size, address_index, dummy,
+ ram_offset);
 } else if (!entry->lock) {
 if (!entry->vaddr_base || entry->paddr_index != address_index ||
 entry->size != cache_size ||
 !test_bits(address_offset >> XC_PAGE_SHIFT,
 test_bit_size >> XC_PAGE_SHIFT,
 entry->valid_mapping)) {
-xen_remap_bucket(mc, entry, NULL, cache_size, address_index, 
dummy);
+xen_remap_bucket(mc, entry, NULL, cache_size, address_index, dummy,
+ ram_offset);
 }
 }
 
@@ -391,13 +395,15 @@ tryagain:
 
 uint8_t *xen_map_cache(MemoryRegion *mr,
hwaddr phys_addr, hwaddr size,
+   ram_addr_t ram_addr_offset,
uint8_t lock, bool dma,
bool is_write)
 {
 uint8_t *p;
 
 mapcache_lock(mapcache);
-p = xen_map_cache_unlocked(mapcache, phys_addr, size, lock, dma, is_write);
+p = xen_map_cache_unlocked(mapcache, phys_addr, size, ram_addr_offset,
+   lock, dma, is_write);
 mapcache_unlock(mapcache);
 return p;
 }
@@ -632,7 +638,7 @@ static uint8_t *xen_replace_cache_entry_unlocked(MapCache 
*mc,
 trace_xen_replace_cache_entry_dummy(old_phys_addr, new_phys_addr);
 
 xen_remap_bucket(mc, entry, entry->vaddr_base,
- cache_size, address_index, false);
+ cache_size, address_index, false, old_phys_addr);
 if (!test_bits(address_offset >> XC_PAGE_SHIFT,
 test_bit_size >> XC_PAGE_SHIFT,
 entry->valid_mapping)) {
diff --git a/include/sysemu/xen-mapcache.h b/include/sysemu/xen-mapcache.h
index 1ec9e66752..b5e3ea1bc0 100644
--- a/include/sysemu/xen-mapcache.h
+++ b/include/sysemu/xen-mapcache.h
@@ -19,6 +19,7 @@ typedef hwaddr (*phys_offset_to_gaddr_t)(hwaddr phys_offset,
 void xen_map_cache_init(phys_offset_to_gaddr_t f,
 void *opaque);
 uint8_t *xen_map_cache(MemoryRegion *mr, hwaddr phys_addr, hwaddr size,
+   ram_addr_t ram_addr_offset,
uint8_t lock, bool dma,
bool is_write);
 ram_addr_t xen_ram_addr_from_mapcache(void *ptr);
@@ -37,6 +38,7 @@ static inline void xen_map_cache_init(phys_offset_to_gaddr_t 
f,
 static inline uint8_t *xen_map_cache(MemoryRegion *mr,
  hwaddr phys_addr,
  hwaddr size,
+ ram_addr_t ram_addr_offset,
  uint8_t lock,
  bool dma,
  bool is_write)
diff --git a/system/physmem.c b/system/physmem.c
index b7847db1a2..33d09f7571 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -2231,13 +2231,14 @@ static void *qemu_ram_ptr_length(RAMBlock *block, 
ram_addr_t addr,
  */
 if (xen_mr_is_memory(block->mr)) {
 return xen_map_cache(block->mr, block->offset + addr,
- len, lock, lock,
- is_write);
+ len, block->offset,
+ 

[PATCH v7 2/8] xen: mapcache: Unmap first entries in buckets

2024-05-24 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

When invalidating memory ranges, if we happen to hit the first
entry in a bucket we were never unmapping it. This was harmless
for foreign mappings but now that we're looking to reuse the
mapcache for transient grant mappings, we must unmap entries
when invalidated.

Signed-off-by: Edgar E. Iglesias 
Reviewed-by: Stefano Stabellini 
---
 hw/xen/xen-mapcache.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
index bc860f4373..ec95445696 100644
--- a/hw/xen/xen-mapcache.c
+++ b/hw/xen/xen-mapcache.c
@@ -491,18 +491,23 @@ static void 
xen_invalidate_map_cache_entry_unlocked(MapCache *mc,
 return;
 }
 entry->lock--;
-if (entry->lock > 0 || pentry == NULL) {
+if (entry->lock > 0) {
 return;
 }
 
-pentry->next = entry->next;
 ram_block_notify_remove(entry->vaddr_base, entry->size, entry->size);
 if (munmap(entry->vaddr_base, entry->size) != 0) {
 perror("unmap fails");
 exit(-1);
 }
+
 g_free(entry->valid_mapping);
-g_free(entry);
+if (pentry) {
+pentry->next = entry->next;
+g_free(entry);
+} else {
+memset(entry, 0, sizeof *entry);
+}
 }
 
 typedef struct XenMapCacheData {
-- 
2.40.1




[PATCH v7 7/8] xen: mapcache: Add support for grant mappings

2024-05-24 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Add a second mapcache for grant mappings. The mapcache for
grants needs to work with XC_PAGE_SIZE granularity since
we can't map larger ranges than what has been granted to us.

Like with foreign mappings (xen_memory), machines using grants
are expected to initialize the xen_grants MR and map it
into their address-map accordingly.

CC: Manos Pitsidianakis 
Signed-off-by: Edgar E. Iglesias 
Reviewed-by: Stefano Stabellini 
---
 hw/xen/xen-hvm-common.c |  12 ++-
 hw/xen/xen-mapcache.c   | 165 +---
 include/hw/xen/xen-hvm-common.h |   3 +
 include/sysemu/xen.h|   7 ++
 4 files changed, 150 insertions(+), 37 deletions(-)

diff --git a/hw/xen/xen-hvm-common.c b/hw/xen/xen-hvm-common.c
index a0a0252da0..b8ace1c368 100644
--- a/hw/xen/xen-hvm-common.c
+++ b/hw/xen/xen-hvm-common.c
@@ -10,12 +10,18 @@
 #include "hw/boards.h"
 #include "hw/xen/arch_hvm.h"
 
-MemoryRegion xen_memory;
+MemoryRegion xen_memory, xen_grants;
 
-/* Check for xen memory.  */
+/* Check for any kind of xen memory, foreign mappings or grants.  */
 bool xen_mr_is_memory(MemoryRegion *mr)
 {
-return mr == _memory;
+return mr == _memory || mr == _grants;
+}
+
+/* Check specifically for grants.  */
+bool xen_mr_is_grants(MemoryRegion *mr)
+{
+return mr == _grants;
 }
 
 void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr,
diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
index a07c47b0b1..5f23b0adbe 100644
--- a/hw/xen/xen-mapcache.c
+++ b/hw/xen/xen-mapcache.c
@@ -14,6 +14,7 @@
 
 #include 
 
+#include "hw/xen/xen-hvm-common.h"
 #include "hw/xen/xen_native.h"
 #include "qemu/bitmap.h"
 
@@ -21,6 +22,8 @@
 #include "sysemu/xen-mapcache.h"
 #include "trace.h"
 
+#include 
+#include 
 
 #if HOST_LONG_BITS == 32
 #  define MCACHE_MAX_SIZE (1UL<<31) /* 2GB Cap */
@@ -41,6 +44,7 @@ typedef struct MapCacheEntry {
 unsigned long *valid_mapping;
 uint32_t lock;
 #define XEN_MAPCACHE_ENTRY_DUMMY (1 << 0)
+#define XEN_MAPCACHE_ENTRY_GRANT (1 << 1)
 uint8_t flags;
 hwaddr size;
 struct MapCacheEntry *next;
@@ -71,6 +75,8 @@ typedef struct MapCache {
 } MapCache;
 
 static MapCache *mapcache;
+static MapCache *mapcache_grants;
+static xengnttab_handle *xen_region_gnttabdev;
 
 static inline void mapcache_lock(MapCache *mc)
 {
@@ -131,6 +137,12 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f, void 
*opaque)
 unsigned long max_mcache_size;
 unsigned int bucket_shift;
 
+xen_region_gnttabdev = xengnttab_open(NULL, 0);
+if (xen_region_gnttabdev == NULL) {
+error_report("mapcache: Failed to open gnttab device");
+exit(EXIT_FAILURE);
+}
+
 if (HOST_LONG_BITS == 32) {
 bucket_shift = 16;
 } else {
@@ -159,6 +171,15 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f, void 
*opaque)
 mapcache = xen_map_cache_init_single(f, opaque,
  bucket_shift,
  max_mcache_size);
+
+/*
+ * Grant mappings must use XC_PAGE_SIZE granularity since we can't
+ * map anything beyond the number of pages granted to us.
+ */
+mapcache_grants = xen_map_cache_init_single(f, opaque,
+XC_PAGE_SHIFT,
+max_mcache_size);
+
 setrlimit(RLIMIT_AS, _as);
 }
 
@@ -168,17 +189,24 @@ static void xen_remap_bucket(MapCache *mc,
  hwaddr size,
  hwaddr address_index,
  bool dummy,
+ bool grant,
+ bool is_write,
  ram_addr_t ram_offset)
 {
 uint8_t *vaddr_base;
-xen_pfn_t *pfns;
-int *err;
+g_autofree uint32_t *refs = NULL;
+g_autofree xen_pfn_t *pfns = NULL;
+g_autofree int *err;
 unsigned int i;
 hwaddr nb_pfn = size >> XC_PAGE_SHIFT;
 
 trace_xen_remap_bucket(address_index);
 
-pfns = g_new0(xen_pfn_t, nb_pfn);
+if (grant) {
+refs = g_new0(uint32_t, nb_pfn);
+} else {
+pfns = g_new0(xen_pfn_t, nb_pfn);
+}
 err = g_new0(int, nb_pfn);
 
 if (entry->vaddr_base != NULL) {
@@ -207,21 +235,51 @@ static void xen_remap_bucket(MapCache *mc,
 g_free(entry->valid_mapping);
 entry->valid_mapping = NULL;
 
-for (i = 0; i < nb_pfn; i++) {
-pfns[i] = (address_index << (mc->bucket_shift - XC_PAGE_SHIFT)) + i;
+if (grant) {
+hwaddr grant_base = address_index - (ram_offset >> XC_PAGE_SHIFT);
+
+for (i = 0; i < nb_pfn; i++) {
+refs[i] = grant_base + i;
+}
+} else {
+for (i = 0; i < nb_pfn; i++) {
+pfns[i] = (address_index << (mc->bucket_shift 

[PATCH v7 3/8] xen: Add xen_mr_is_memory()

2024-05-24 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Add xen_mr_is_memory() to abstract away tests for the
xen_memory MR.

No functional changes.

Signed-off-by: Edgar E. Iglesias 
Reviewed-by: Stefano Stabellini 
Acked-by: David Hildenbrand 
---
 hw/xen/xen-hvm-common.c | 10 --
 include/sysemu/xen.h|  8 
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/hw/xen/xen-hvm-common.c b/hw/xen/xen-hvm-common.c
index 2d1b032121..a0a0252da0 100644
--- a/hw/xen/xen-hvm-common.c
+++ b/hw/xen/xen-hvm-common.c
@@ -12,6 +12,12 @@
 
 MemoryRegion xen_memory;
 
+/* Check for xen memory.  */
+bool xen_mr_is_memory(MemoryRegion *mr)
+{
+return mr == _memory;
+}
+
 void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr,
Error **errp)
 {
@@ -28,7 +34,7 @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, 
MemoryRegion *mr,
 return;
 }
 
-if (mr == _memory) {
+if (xen_mr_is_memory(mr)) {
 return;
 }
 
@@ -55,7 +61,7 @@ static void xen_set_memory(struct MemoryListener *listener,
 {
 XenIOState *state = container_of(listener, XenIOState, memory_listener);
 
-if (section->mr == _memory) {
+if (xen_mr_is_memory(section->mr)) {
 return;
 } else {
 if (add) {
diff --git a/include/sysemu/xen.h b/include/sysemu/xen.h
index 754ec2e6cb..dc72f83bcb 100644
--- a/include/sysemu/xen.h
+++ b/include/sysemu/xen.h
@@ -34,6 +34,8 @@ void xen_hvm_modified_memory(ram_addr_t start, ram_addr_t 
length);
 void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size,
struct MemoryRegion *mr, Error **errp);
 
+bool xen_mr_is_memory(MemoryRegion *mr);
+
 #else /* !CONFIG_XEN_IS_POSSIBLE */
 
 #define xen_enabled() 0
@@ -47,6 +49,12 @@ static inline void xen_ram_alloc(ram_addr_t ram_addr, 
ram_addr_t size,
 g_assert_not_reached();
 }
 
+static inline bool xen_mr_is_memory(MemoryRegion *mr)
+{
+g_assert_not_reached();
+return false;
+}
+
 #endif /* CONFIG_XEN_IS_POSSIBLE */
 
 #endif
-- 
2.40.1




[PATCH v7 1/8] xen: mapcache: Make MCACHE_BUCKET_SHIFT runtime configurable

2024-05-24 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Make MCACHE_BUCKET_SHIFT runtime configurable per cache instance.

Signed-off-by: Edgar E. Iglesias 
Reviewed-by: Stefano Stabellini 
---
 hw/xen/xen-mapcache.c | 54 ++-
 1 file changed, 33 insertions(+), 21 deletions(-)

diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
index fa6813b1ad..bc860f4373 100644
--- a/hw/xen/xen-mapcache.c
+++ b/hw/xen/xen-mapcache.c
@@ -23,13 +23,10 @@
 
 
 #if HOST_LONG_BITS == 32
-#  define MCACHE_BUCKET_SHIFT 16
 #  define MCACHE_MAX_SIZE (1UL<<31) /* 2GB Cap */
 #else
-#  define MCACHE_BUCKET_SHIFT 20
 #  define MCACHE_MAX_SIZE (1UL<<35) /* 32GB Cap */
 #endif
-#define MCACHE_BUCKET_SIZE (1UL << MCACHE_BUCKET_SHIFT)
 
 /* This is the size of the virtual address space reserve to QEMU that will not
  * be use by MapCache.
@@ -65,7 +62,8 @@ typedef struct MapCache {
 /* For most cases (>99.9%), the page address is the same. */
 MapCacheEntry *last_entry;
 unsigned long max_mcache_size;
-unsigned int mcache_bucket_shift;
+unsigned int bucket_shift;
+unsigned long bucket_size;
 
 phys_offset_to_gaddr_t phys_offset_to_gaddr;
 QemuMutex lock;
@@ -95,11 +93,14 @@ static inline int test_bits(int nr, int size, const 
unsigned long *addr)
 
 static MapCache *xen_map_cache_init_single(phys_offset_to_gaddr_t f,
void *opaque,
+   unsigned int bucket_shift,
unsigned long max_size)
 {
 unsigned long size;
 MapCache *mc;
 
+assert(bucket_shift >= XC_PAGE_SHIFT);
+
 mc = g_new0(MapCache, 1);
 
 mc->phys_offset_to_gaddr = f;
@@ -108,12 +109,14 @@ static MapCache 
*xen_map_cache_init_single(phys_offset_to_gaddr_t f,
 
 QTAILQ_INIT(>locked_entries);
 
+mc->bucket_shift = bucket_shift;
+mc->bucket_size = 1UL << bucket_shift;
 mc->max_mcache_size = max_size;
 
 mc->nr_buckets =
 (((mc->max_mcache_size >> XC_PAGE_SHIFT) +
-  (1UL << (MCACHE_BUCKET_SHIFT - XC_PAGE_SHIFT)) - 1) >>
- (MCACHE_BUCKET_SHIFT - XC_PAGE_SHIFT));
+  (1UL << (bucket_shift - XC_PAGE_SHIFT)) - 1) >>
+ (bucket_shift - XC_PAGE_SHIFT));
 
 size = mc->nr_buckets * sizeof(MapCacheEntry);
 size = (size + XC_PAGE_SIZE - 1) & ~(XC_PAGE_SIZE - 1);
@@ -126,6 +129,13 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f, void 
*opaque)
 {
 struct rlimit rlimit_as;
 unsigned long max_mcache_size;
+unsigned int bucket_shift;
+
+if (HOST_LONG_BITS == 32) {
+bucket_shift = 16;
+} else {
+bucket_shift = 20;
+}
 
 if (geteuid() == 0) {
 rlimit_as.rlim_cur = RLIM_INFINITY;
@@ -146,7 +156,9 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f, void 
*opaque)
 }
 }
 
-mapcache = xen_map_cache_init_single(f, opaque, max_mcache_size);
+mapcache = xen_map_cache_init_single(f, opaque,
+ bucket_shift,
+ max_mcache_size);
 setrlimit(RLIMIT_AS, _as);
 }
 
@@ -195,7 +207,7 @@ static void xen_remap_bucket(MapCache *mc,
 entry->valid_mapping = NULL;
 
 for (i = 0; i < nb_pfn; i++) {
-pfns[i] = (address_index << (MCACHE_BUCKET_SHIFT-XC_PAGE_SHIFT)) + i;
+pfns[i] = (address_index << (mc->bucket_shift - XC_PAGE_SHIFT)) + i;
 }
 
 /*
@@ -266,8 +278,8 @@ static uint8_t *xen_map_cache_unlocked(MapCache *mc,
 bool dummy = false;
 
 tryagain:
-address_index  = phys_addr >> MCACHE_BUCKET_SHIFT;
-address_offset = phys_addr & (MCACHE_BUCKET_SIZE - 1);
+address_index  = phys_addr >> mc->bucket_shift;
+address_offset = phys_addr & (mc->bucket_size - 1);
 
 trace_xen_map_cache(phys_addr);
 
@@ -294,14 +306,14 @@ tryagain:
 return mc->last_entry->vaddr_base + address_offset;
 }
 
-/* size is always a multiple of MCACHE_BUCKET_SIZE */
+/* size is always a multiple of mc->bucket_size */
 if (size) {
 cache_size = size + address_offset;
-if (cache_size % MCACHE_BUCKET_SIZE) {
-cache_size += MCACHE_BUCKET_SIZE - (cache_size % 
MCACHE_BUCKET_SIZE);
+if (cache_size % mc->bucket_size) {
+cache_size += mc->bucket_size - (cache_size % mc->bucket_size);
 }
 } else {
-cache_size = MCACHE_BUCKET_SIZE;
+cache_size = mc->bucket_size;
 }
 
 entry = >entry[address_index % mc->nr_buckets];
@@ -422,7 +434,7 @@ static ram_addr_t 
xen_ram_addr_from_mapcache_single(MapCache *mc, void *ptr)
 trace_xen_ram_addr_from_mapcache_not_in_cache(ptr);
 raddr = RAM_ADDR_INVALID;
 } else {
-raddr = (reventry->paddr_index << MCACHE_BUCKET_SHIFT) +
+   

[PATCH v1 0/1] xen/arm: smmuv3: Mark more init-only functions with __init

2024-05-23 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

I was scanning for code that we could potentially move from the
.text section into .init.text and found a few candidates.

I'm not sure if this makes sense, perhaps we don't want to mark
these functions for other reasons but my scripts found this chain
of SMMUv3 init functions as only reachable by .inittext code.
Perhaps it's a little late in the release cycle to consider this...

Best regards,
Edgar


Edgar E. Iglesias (1):
  xen/arm: smmuv3: Mark more init-only functions with __init

 xen/drivers/passthrough/arm/smmu-v3.c | 17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

-- 
2.40.1




[PATCH v1 1/1] xen/arm: smmuv3: Mark more init-only functions with __init

2024-05-23 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Move more functions that are only called at init to
the .init.text section.

Signed-off-by: Edgar E. Iglesias 
---
 xen/drivers/passthrough/arm/smmu-v3.c | 17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/xen/drivers/passthrough/arm/smmu-v3.c 
b/xen/drivers/passthrough/arm/smmu-v3.c
index 6904962467..cee5724022 100644
--- a/xen/drivers/passthrough/arm/smmu-v3.c
+++ b/xen/drivers/passthrough/arm/smmu-v3.c
@@ -1545,7 +1545,7 @@ static int arm_smmu_dt_xlate(struct device *dev,
 }
 
 /* Probing and initialisation functions */
-static int arm_smmu_init_one_queue(struct arm_smmu_device *smmu,
+static int __init arm_smmu_init_one_queue(struct arm_smmu_device *smmu,
   struct arm_smmu_queue *q,
   void __iomem *page,
   unsigned long prod_off,
@@ -1588,7 +1588,7 @@ static int arm_smmu_init_one_queue(struct arm_smmu_device 
*smmu,
return 0;
 }
 
-static int arm_smmu_init_queues(struct arm_smmu_device *smmu)
+static int __init arm_smmu_init_queues(struct arm_smmu_device *smmu)
 {
int ret;
 
@@ -1724,7 +1724,7 @@ static int arm_smmu_init_strtab(struct arm_smmu_device 
*smmu)
return 0;
 }
 
-static int arm_smmu_init_structures(struct arm_smmu_device *smmu)
+static int __init arm_smmu_init_structures(struct arm_smmu_device *smmu)
 {
int ret;
 
@@ -1746,7 +1746,8 @@ static int arm_smmu_write_reg_sync(struct arm_smmu_device 
*smmu, u32 val,
 }
 
 /* GBPA is "special" */
-static int arm_smmu_update_gbpa(struct arm_smmu_device *smmu, u32 set, u32 clr)
+static int __init arm_smmu_update_gbpa(struct arm_smmu_device *smmu,
+   u32 set, u32 clr)
 {
int ret;
u32 reg, __iomem *gbpa = smmu->base + ARM_SMMU_GBPA;
@@ -1842,7 +1843,7 @@ static void arm_smmu_setup_msis(struct arm_smmu_device 
*smmu)
 static inline void arm_smmu_setup_msis(struct arm_smmu_device *smmu) { }
 #endif /* CONFIG_MSI */
 
-static void arm_smmu_free_irqs(struct arm_smmu_device *smmu)
+static void __init arm_smmu_free_irqs(struct arm_smmu_device *smmu)
 {
int irq;
 
@@ -1926,7 +1927,7 @@ err_free_evtq_irq:
return ret;
 }
 
-static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu)
+static int __init arm_smmu_setup_irqs(struct arm_smmu_device *smmu)
 {
int ret, irq;
u32 irqen_flags = IRQ_CTRL_EVTQ_IRQEN | IRQ_CTRL_GERROR_IRQEN;
@@ -1988,7 +1989,7 @@ static int arm_smmu_device_disable(struct arm_smmu_device 
*smmu)
return ret;
 }
 
-static int arm_smmu_device_reset(struct arm_smmu_device *smmu)
+static int __init arm_smmu_device_reset(struct arm_smmu_device *smmu)
 {
int ret;
u32 reg, enables;
@@ -2405,7 +2406,7 @@ static void arm_smmu_free_structures(struct 
arm_smmu_device *smmu)
xfree(smmu->strtab_cfg.l1_desc);
 }
 
-static int arm_smmu_device_probe(struct platform_device *pdev)
+static int __init arm_smmu_device_probe(struct platform_device *pdev)
 {
int irq, ret;
paddr_t ioaddr, iosize;
-- 
2.40.1




Re: [PATCH v6 7/8] xen: mapcache: Add support for grant mappings

2024-05-23 Thread Edgar E. Iglesias
On Thu, May 23, 2024 at 9:47 AM Manos Pitsidianakis <
manos.pitsidiana...@linaro.org> wrote:

> On Thu, 16 May 2024 18:48, "Edgar E. Iglesias" 
> wrote:
> >From: "Edgar E. Iglesias" 
> >
> >Add a second mapcache for grant mappings. The mapcache for
> >grants needs to work with XC_PAGE_SIZE granularity since
> >we can't map larger ranges than what has been granted to us.
> >
> >Like with foreign mappings (xen_memory), machines using grants
> >are expected to initialize the xen_grants MR and map it
> >into their address-map accordingly.
> >
> >Signed-off-by: Edgar E. Iglesias 
> >Reviewed-by: Stefano Stabellini 
> >---
> > hw/xen/xen-hvm-common.c |  12 ++-
> > hw/xen/xen-mapcache.c   | 163 ++--
> > include/hw/xen/xen-hvm-common.h |   3 +
> > include/sysemu/xen.h|   7 ++
> > 4 files changed, 152 insertions(+), 33 deletions(-)
> >
> >diff --git a/hw/xen/xen-hvm-common.c b/hw/xen/xen-hvm-common.c
> >index a0a0252da0..b8ace1c368 100644
> >--- a/hw/xen/xen-hvm-common.c
> >+++ b/hw/xen/xen-hvm-common.c
> >@@ -10,12 +10,18 @@
> > #include "hw/boards.h"
> > #include "hw/xen/arch_hvm.h"
> >
> >-MemoryRegion xen_memory;
> >+MemoryRegion xen_memory, xen_grants;
> >
> >-/* Check for xen memory.  */
> >+/* Check for any kind of xen memory, foreign mappings or grants.  */
> > bool xen_mr_is_memory(MemoryRegion *mr)
> > {
> >-return mr == _memory;
> >+return mr == _memory || mr == _grants;
> >+}
> >+
> >+/* Check specifically for grants.  */
> >+bool xen_mr_is_grants(MemoryRegion *mr)
> >+{
> >+return mr == _grants;
> > }
> >
> > void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion
> *mr,
> >diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
> >index a07c47b0b1..1cbc2aeaa9 100644
> >--- a/hw/xen/xen-mapcache.c
> >+++ b/hw/xen/xen-mapcache.c
> >@@ -14,6 +14,7 @@
> >
> > #include 
> >
> >+#include "hw/xen/xen-hvm-common.h"
> > #include "hw/xen/xen_native.h"
> > #include "qemu/bitmap.h"
> >
> >@@ -21,6 +22,8 @@
> > #include "sysemu/xen-mapcache.h"
> > #include "trace.h"
> >
> >+#include 
> >+#include 
> >
> > #if HOST_LONG_BITS == 32
> > #  define MCACHE_MAX_SIZE (1UL<<31) /* 2GB Cap */
> >@@ -41,6 +44,7 @@ typedef struct MapCacheEntry {
> > unsigned long *valid_mapping;
> > uint32_t lock;
> > #define XEN_MAPCACHE_ENTRY_DUMMY (1 << 0)
> >+#define XEN_MAPCACHE_ENTRY_GRANT (1 << 1)
>
> Might we get more entry kinds in the future? (for example foreign maps).
> Maybe this could be an enum.
>
>
Perhaps. Foreign mappings are already supported, this flag separates
ordinary foreign mappings from grant foreign mappings.
IMO, since this is not an external interface it's probably better to change
it once we have a concrete use-case at hand.



> > uint8_t flags;
> > hwaddr size;
> > struct MapCacheEntry *next;
> >@@ -71,6 +75,8 @@ typedef struct MapCache {
> > } MapCache;
> >
> > static MapCache *mapcache;
> >+static MapCache *mapcache_grants;
> >+static xengnttab_handle *xen_region_gnttabdev;
> >
> > static inline void mapcache_lock(MapCache *mc)
> > {
> >@@ -131,6 +137,12 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f,
> void *opaque)
> > unsigned long max_mcache_size;
> > unsigned int bucket_shift;
> >
> >+xen_region_gnttabdev = xengnttab_open(NULL, 0);
> >+if (xen_region_gnttabdev == NULL) {
> >+error_report("mapcache: Failed to open gnttab device");
> >+exit(EXIT_FAILURE);
> >+}
> >+
> > if (HOST_LONG_BITS == 32) {
> > bucket_shift = 16;
> > } else {
> >@@ -159,6 +171,15 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f,
> void *opaque)
> > mapcache = xen_map_cache_init_single(f, opaque,
> >  bucket_shift,
> >  max_mcache_size);
> >+
> >+/*
> >+ * Grant mappings must use XC_PAGE_SIZE granularity since we can't
> >+ * map anything beyond the number of pages granted to us.
> >+ */
> >+mapcache_grants = xen_map_cache_init_single(f, opaque,
> >+XC_PAGE_SHIFT,
> >+max_mcache_siz

[PATCH v6 2/8] xen: mapcache: Unmap first entries in buckets

2024-05-16 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

When invalidating memory ranges, if we happen to hit the first
entry in a bucket we were never unmapping it. This was harmless
for foreign mappings but now that we're looking to reuse the
mapcache for transient grant mappings, we must unmap entries
when invalidated.

Signed-off-by: Edgar E. Iglesias 
Reviewed-by: Stefano Stabellini 
---
 hw/xen/xen-mapcache.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
index bc860f4373..ec95445696 100644
--- a/hw/xen/xen-mapcache.c
+++ b/hw/xen/xen-mapcache.c
@@ -491,18 +491,23 @@ static void 
xen_invalidate_map_cache_entry_unlocked(MapCache *mc,
 return;
 }
 entry->lock--;
-if (entry->lock > 0 || pentry == NULL) {
+if (entry->lock > 0) {
 return;
 }
 
-pentry->next = entry->next;
 ram_block_notify_remove(entry->vaddr_base, entry->size, entry->size);
 if (munmap(entry->vaddr_base, entry->size) != 0) {
 perror("unmap fails");
 exit(-1);
 }
+
 g_free(entry->valid_mapping);
-g_free(entry);
+if (pentry) {
+pentry->next = entry->next;
+g_free(entry);
+} else {
+memset(entry, 0, sizeof *entry);
+}
 }
 
 typedef struct XenMapCacheData {
-- 
2.40.1




[PATCH v6 6/8] xen: mapcache: Pass the ram_addr offset to xen_map_cache()

2024-05-16 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Pass the ram_addr offset to xen_map_cache.
This is in preparation for adding grant mappings that need
to compute the address within the RAMBlock.

No functional changes.

Signed-off-by: Edgar E. Iglesias 
---
 hw/xen/xen-mapcache.c | 16 +++-
 include/sysemu/xen-mapcache.h |  2 ++
 system/physmem.c  |  9 +
 3 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
index ec95445696..a07c47b0b1 100644
--- a/hw/xen/xen-mapcache.c
+++ b/hw/xen/xen-mapcache.c
@@ -167,7 +167,8 @@ static void xen_remap_bucket(MapCache *mc,
  void *vaddr,
  hwaddr size,
  hwaddr address_index,
- bool dummy)
+ bool dummy,
+ ram_addr_t ram_offset)
 {
 uint8_t *vaddr_base;
 xen_pfn_t *pfns;
@@ -266,6 +267,7 @@ static void xen_remap_bucket(MapCache *mc,
 
 static uint8_t *xen_map_cache_unlocked(MapCache *mc,
hwaddr phys_addr, hwaddr size,
+   ram_addr_t ram_offset,
uint8_t lock, bool dma, bool is_write)
 {
 MapCacheEntry *entry, *pentry = NULL,
@@ -337,14 +339,16 @@ tryagain:
 if (!entry) {
 entry = g_new0(MapCacheEntry, 1);
 pentry->next = entry;
-xen_remap_bucket(mc, entry, NULL, cache_size, address_index, dummy);
+xen_remap_bucket(mc, entry, NULL, cache_size, address_index, dummy,
+ ram_offset);
 } else if (!entry->lock) {
 if (!entry->vaddr_base || entry->paddr_index != address_index ||
 entry->size != cache_size ||
 !test_bits(address_offset >> XC_PAGE_SHIFT,
 test_bit_size >> XC_PAGE_SHIFT,
 entry->valid_mapping)) {
-xen_remap_bucket(mc, entry, NULL, cache_size, address_index, 
dummy);
+xen_remap_bucket(mc, entry, NULL, cache_size, address_index, dummy,
+ ram_offset);
 }
 }
 
@@ -391,13 +395,15 @@ tryagain:
 
 uint8_t *xen_map_cache(MemoryRegion *mr,
hwaddr phys_addr, hwaddr size,
+   ram_addr_t ram_addr_offset,
uint8_t lock, bool dma,
bool is_write)
 {
 uint8_t *p;
 
 mapcache_lock(mapcache);
-p = xen_map_cache_unlocked(mapcache, phys_addr, size, lock, dma, is_write);
+p = xen_map_cache_unlocked(mapcache, phys_addr, size, ram_addr_offset,
+   lock, dma, is_write);
 mapcache_unlock(mapcache);
 return p;
 }
@@ -632,7 +638,7 @@ static uint8_t *xen_replace_cache_entry_unlocked(MapCache 
*mc,
 trace_xen_replace_cache_entry_dummy(old_phys_addr, new_phys_addr);
 
 xen_remap_bucket(mc, entry, entry->vaddr_base,
- cache_size, address_index, false);
+ cache_size, address_index, false, old_phys_addr);
 if (!test_bits(address_offset >> XC_PAGE_SHIFT,
 test_bit_size >> XC_PAGE_SHIFT,
 entry->valid_mapping)) {
diff --git a/include/sysemu/xen-mapcache.h b/include/sysemu/xen-mapcache.h
index 1ec9e66752..b5e3ea1bc0 100644
--- a/include/sysemu/xen-mapcache.h
+++ b/include/sysemu/xen-mapcache.h
@@ -19,6 +19,7 @@ typedef hwaddr (*phys_offset_to_gaddr_t)(hwaddr phys_offset,
 void xen_map_cache_init(phys_offset_to_gaddr_t f,
 void *opaque);
 uint8_t *xen_map_cache(MemoryRegion *mr, hwaddr phys_addr, hwaddr size,
+   ram_addr_t ram_addr_offset,
uint8_t lock, bool dma,
bool is_write);
 ram_addr_t xen_ram_addr_from_mapcache(void *ptr);
@@ -37,6 +38,7 @@ static inline void xen_map_cache_init(phys_offset_to_gaddr_t 
f,
 static inline uint8_t *xen_map_cache(MemoryRegion *mr,
  hwaddr phys_addr,
  hwaddr size,
+ ram_addr_t ram_addr_offset,
  uint8_t lock,
  bool dma,
  bool is_write)
diff --git a/system/physmem.c b/system/physmem.c
index b7847db1a2..33d09f7571 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -2231,13 +2231,14 @@ static void *qemu_ram_ptr_length(RAMBlock *block, 
ram_addr_t addr,
  */
 if (xen_mr_is_memory(block->mr)) {
 return xen_map_cache(block->mr, block->offset + addr,
- len, lock, lock,
- is_write);
+ len, block->offset,
+ lock, lock, is_write);

[PATCH v6 7/8] xen: mapcache: Add support for grant mappings

2024-05-16 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Add a second mapcache for grant mappings. The mapcache for
grants needs to work with XC_PAGE_SIZE granularity since
we can't map larger ranges than what has been granted to us.

Like with foreign mappings (xen_memory), machines using grants
are expected to initialize the xen_grants MR and map it
into their address-map accordingly.

Signed-off-by: Edgar E. Iglesias 
Reviewed-by: Stefano Stabellini 
---
 hw/xen/xen-hvm-common.c |  12 ++-
 hw/xen/xen-mapcache.c   | 163 ++--
 include/hw/xen/xen-hvm-common.h |   3 +
 include/sysemu/xen.h|   7 ++
 4 files changed, 152 insertions(+), 33 deletions(-)

diff --git a/hw/xen/xen-hvm-common.c b/hw/xen/xen-hvm-common.c
index a0a0252da0..b8ace1c368 100644
--- a/hw/xen/xen-hvm-common.c
+++ b/hw/xen/xen-hvm-common.c
@@ -10,12 +10,18 @@
 #include "hw/boards.h"
 #include "hw/xen/arch_hvm.h"
 
-MemoryRegion xen_memory;
+MemoryRegion xen_memory, xen_grants;
 
-/* Check for xen memory.  */
+/* Check for any kind of xen memory, foreign mappings or grants.  */
 bool xen_mr_is_memory(MemoryRegion *mr)
 {
-return mr == _memory;
+return mr == _memory || mr == _grants;
+}
+
+/* Check specifically for grants.  */
+bool xen_mr_is_grants(MemoryRegion *mr)
+{
+return mr == _grants;
 }
 
 void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr,
diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
index a07c47b0b1..1cbc2aeaa9 100644
--- a/hw/xen/xen-mapcache.c
+++ b/hw/xen/xen-mapcache.c
@@ -14,6 +14,7 @@
 
 #include 
 
+#include "hw/xen/xen-hvm-common.h"
 #include "hw/xen/xen_native.h"
 #include "qemu/bitmap.h"
 
@@ -21,6 +22,8 @@
 #include "sysemu/xen-mapcache.h"
 #include "trace.h"
 
+#include 
+#include 
 
 #if HOST_LONG_BITS == 32
 #  define MCACHE_MAX_SIZE (1UL<<31) /* 2GB Cap */
@@ -41,6 +44,7 @@ typedef struct MapCacheEntry {
 unsigned long *valid_mapping;
 uint32_t lock;
 #define XEN_MAPCACHE_ENTRY_DUMMY (1 << 0)
+#define XEN_MAPCACHE_ENTRY_GRANT (1 << 1)
 uint8_t flags;
 hwaddr size;
 struct MapCacheEntry *next;
@@ -71,6 +75,8 @@ typedef struct MapCache {
 } MapCache;
 
 static MapCache *mapcache;
+static MapCache *mapcache_grants;
+static xengnttab_handle *xen_region_gnttabdev;
 
 static inline void mapcache_lock(MapCache *mc)
 {
@@ -131,6 +137,12 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f, void 
*opaque)
 unsigned long max_mcache_size;
 unsigned int bucket_shift;
 
+xen_region_gnttabdev = xengnttab_open(NULL, 0);
+if (xen_region_gnttabdev == NULL) {
+error_report("mapcache: Failed to open gnttab device");
+exit(EXIT_FAILURE);
+}
+
 if (HOST_LONG_BITS == 32) {
 bucket_shift = 16;
 } else {
@@ -159,6 +171,15 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f, void 
*opaque)
 mapcache = xen_map_cache_init_single(f, opaque,
  bucket_shift,
  max_mcache_size);
+
+/*
+ * Grant mappings must use XC_PAGE_SIZE granularity since we can't
+ * map anything beyond the number of pages granted to us.
+ */
+mapcache_grants = xen_map_cache_init_single(f, opaque,
+XC_PAGE_SHIFT,
+max_mcache_size);
+
 setrlimit(RLIMIT_AS, _as);
 }
 
@@ -168,17 +189,24 @@ static void xen_remap_bucket(MapCache *mc,
  hwaddr size,
  hwaddr address_index,
  bool dummy,
+ bool grant,
+ bool is_write,
  ram_addr_t ram_offset)
 {
 uint8_t *vaddr_base;
-xen_pfn_t *pfns;
+uint32_t *refs = NULL;
+xen_pfn_t *pfns = NULL;
 int *err;
 unsigned int i;
 hwaddr nb_pfn = size >> XC_PAGE_SHIFT;
 
 trace_xen_remap_bucket(address_index);
 
-pfns = g_new0(xen_pfn_t, nb_pfn);
+if (grant) {
+refs = g_new0(uint32_t, nb_pfn);
+} else {
+pfns = g_new0(xen_pfn_t, nb_pfn);
+}
 err = g_new0(int, nb_pfn);
 
 if (entry->vaddr_base != NULL) {
@@ -207,21 +235,51 @@ static void xen_remap_bucket(MapCache *mc,
 g_free(entry->valid_mapping);
 entry->valid_mapping = NULL;
 
-for (i = 0; i < nb_pfn; i++) {
-pfns[i] = (address_index << (mc->bucket_shift - XC_PAGE_SHIFT)) + i;
+if (grant) {
+hwaddr grant_base = address_index - (ram_offset >> XC_PAGE_SHIFT);
+
+for (i = 0; i < nb_pfn; i++) {
+refs[i] = grant_base + i;
+}
+} else {
+for (i = 0; i < nb_pfn; i++) {
+pfns[i] = (address_index << (mc->bucket_shift - XC_PAGE_SHIFT)) + 
i;
+}
 }
 
-/*
- * If the cal

[PATCH v6 3/8] xen: Add xen_mr_is_memory()

2024-05-16 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Add xen_mr_is_memory() to abstract away tests for the
xen_memory MR.

No functional changes.

Signed-off-by: Edgar E. Iglesias 
Reviewed-by: Stefano Stabellini 
Acked-by: David Hildenbrand 
---
 hw/xen/xen-hvm-common.c | 10 --
 include/sysemu/xen.h|  8 
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/hw/xen/xen-hvm-common.c b/hw/xen/xen-hvm-common.c
index 2d1b032121..a0a0252da0 100644
--- a/hw/xen/xen-hvm-common.c
+++ b/hw/xen/xen-hvm-common.c
@@ -12,6 +12,12 @@
 
 MemoryRegion xen_memory;
 
+/* Check for xen memory.  */
+bool xen_mr_is_memory(MemoryRegion *mr)
+{
+return mr == _memory;
+}
+
 void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr,
Error **errp)
 {
@@ -28,7 +34,7 @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, 
MemoryRegion *mr,
 return;
 }
 
-if (mr == _memory) {
+if (xen_mr_is_memory(mr)) {
 return;
 }
 
@@ -55,7 +61,7 @@ static void xen_set_memory(struct MemoryListener *listener,
 {
 XenIOState *state = container_of(listener, XenIOState, memory_listener);
 
-if (section->mr == _memory) {
+if (xen_mr_is_memory(section->mr)) {
 return;
 } else {
 if (add) {
diff --git a/include/sysemu/xen.h b/include/sysemu/xen.h
index 754ec2e6cb..dc72f83bcb 100644
--- a/include/sysemu/xen.h
+++ b/include/sysemu/xen.h
@@ -34,6 +34,8 @@ void xen_hvm_modified_memory(ram_addr_t start, ram_addr_t 
length);
 void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size,
struct MemoryRegion *mr, Error **errp);
 
+bool xen_mr_is_memory(MemoryRegion *mr);
+
 #else /* !CONFIG_XEN_IS_POSSIBLE */
 
 #define xen_enabled() 0
@@ -47,6 +49,12 @@ static inline void xen_ram_alloc(ram_addr_t ram_addr, 
ram_addr_t size,
 g_assert_not_reached();
 }
 
+static inline bool xen_mr_is_memory(MemoryRegion *mr)
+{
+g_assert_not_reached();
+return false;
+}
+
 #endif /* CONFIG_XEN_IS_POSSIBLE */
 
 #endif
-- 
2.40.1




[PATCH v6 1/8] xen: mapcache: Make MCACHE_BUCKET_SHIFT runtime configurable

2024-05-16 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Make MCACHE_BUCKET_SHIFT runtime configurable per cache instance.

Signed-off-by: Edgar E. Iglesias 
Reviewed-by: Stefano Stabellini 
---
 hw/xen/xen-mapcache.c | 54 ++-
 1 file changed, 33 insertions(+), 21 deletions(-)

diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
index fa6813b1ad..bc860f4373 100644
--- a/hw/xen/xen-mapcache.c
+++ b/hw/xen/xen-mapcache.c
@@ -23,13 +23,10 @@
 
 
 #if HOST_LONG_BITS == 32
-#  define MCACHE_BUCKET_SHIFT 16
 #  define MCACHE_MAX_SIZE (1UL<<31) /* 2GB Cap */
 #else
-#  define MCACHE_BUCKET_SHIFT 20
 #  define MCACHE_MAX_SIZE (1UL<<35) /* 32GB Cap */
 #endif
-#define MCACHE_BUCKET_SIZE (1UL << MCACHE_BUCKET_SHIFT)
 
 /* This is the size of the virtual address space reserve to QEMU that will not
  * be use by MapCache.
@@ -65,7 +62,8 @@ typedef struct MapCache {
 /* For most cases (>99.9%), the page address is the same. */
 MapCacheEntry *last_entry;
 unsigned long max_mcache_size;
-unsigned int mcache_bucket_shift;
+unsigned int bucket_shift;
+unsigned long bucket_size;
 
 phys_offset_to_gaddr_t phys_offset_to_gaddr;
 QemuMutex lock;
@@ -95,11 +93,14 @@ static inline int test_bits(int nr, int size, const 
unsigned long *addr)
 
 static MapCache *xen_map_cache_init_single(phys_offset_to_gaddr_t f,
void *opaque,
+   unsigned int bucket_shift,
unsigned long max_size)
 {
 unsigned long size;
 MapCache *mc;
 
+assert(bucket_shift >= XC_PAGE_SHIFT);
+
 mc = g_new0(MapCache, 1);
 
 mc->phys_offset_to_gaddr = f;
@@ -108,12 +109,14 @@ static MapCache 
*xen_map_cache_init_single(phys_offset_to_gaddr_t f,
 
 QTAILQ_INIT(>locked_entries);
 
+mc->bucket_shift = bucket_shift;
+mc->bucket_size = 1UL << bucket_shift;
 mc->max_mcache_size = max_size;
 
 mc->nr_buckets =
 (((mc->max_mcache_size >> XC_PAGE_SHIFT) +
-  (1UL << (MCACHE_BUCKET_SHIFT - XC_PAGE_SHIFT)) - 1) >>
- (MCACHE_BUCKET_SHIFT - XC_PAGE_SHIFT));
+  (1UL << (bucket_shift - XC_PAGE_SHIFT)) - 1) >>
+ (bucket_shift - XC_PAGE_SHIFT));
 
 size = mc->nr_buckets * sizeof(MapCacheEntry);
 size = (size + XC_PAGE_SIZE - 1) & ~(XC_PAGE_SIZE - 1);
@@ -126,6 +129,13 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f, void 
*opaque)
 {
 struct rlimit rlimit_as;
 unsigned long max_mcache_size;
+unsigned int bucket_shift;
+
+if (HOST_LONG_BITS == 32) {
+bucket_shift = 16;
+} else {
+bucket_shift = 20;
+}
 
 if (geteuid() == 0) {
 rlimit_as.rlim_cur = RLIM_INFINITY;
@@ -146,7 +156,9 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f, void 
*opaque)
 }
 }
 
-mapcache = xen_map_cache_init_single(f, opaque, max_mcache_size);
+mapcache = xen_map_cache_init_single(f, opaque,
+ bucket_shift,
+ max_mcache_size);
 setrlimit(RLIMIT_AS, _as);
 }
 
@@ -195,7 +207,7 @@ static void xen_remap_bucket(MapCache *mc,
 entry->valid_mapping = NULL;
 
 for (i = 0; i < nb_pfn; i++) {
-pfns[i] = (address_index << (MCACHE_BUCKET_SHIFT-XC_PAGE_SHIFT)) + i;
+pfns[i] = (address_index << (mc->bucket_shift - XC_PAGE_SHIFT)) + i;
 }
 
 /*
@@ -266,8 +278,8 @@ static uint8_t *xen_map_cache_unlocked(MapCache *mc,
 bool dummy = false;
 
 tryagain:
-address_index  = phys_addr >> MCACHE_BUCKET_SHIFT;
-address_offset = phys_addr & (MCACHE_BUCKET_SIZE - 1);
+address_index  = phys_addr >> mc->bucket_shift;
+address_offset = phys_addr & (mc->bucket_size - 1);
 
 trace_xen_map_cache(phys_addr);
 
@@ -294,14 +306,14 @@ tryagain:
 return mc->last_entry->vaddr_base + address_offset;
 }
 
-/* size is always a multiple of MCACHE_BUCKET_SIZE */
+/* size is always a multiple of mc->bucket_size */
 if (size) {
 cache_size = size + address_offset;
-if (cache_size % MCACHE_BUCKET_SIZE) {
-cache_size += MCACHE_BUCKET_SIZE - (cache_size % 
MCACHE_BUCKET_SIZE);
+if (cache_size % mc->bucket_size) {
+cache_size += mc->bucket_size - (cache_size % mc->bucket_size);
 }
 } else {
-cache_size = MCACHE_BUCKET_SIZE;
+cache_size = mc->bucket_size;
 }
 
 entry = >entry[address_index % mc->nr_buckets];
@@ -422,7 +434,7 @@ static ram_addr_t 
xen_ram_addr_from_mapcache_single(MapCache *mc, void *ptr)
 trace_xen_ram_addr_from_mapcache_not_in_cache(ptr);
 raddr = RAM_ADDR_INVALID;
 } else {
-raddr = (reventry->paddr_index << MCACHE_BUCKET_SHIFT) +
+   

Re: [PATCH v5 6/8] xen: mapcache: Pass the ram_addr offset to xen_map_cache()

2024-05-16 Thread Edgar E. Iglesias
On Thu, May 16, 2024 at 1:08 AM Stefano Stabellini
 wrote:
>
> On Fri, 3 May 2024, Edgar E. Iglesias wrote:
> > From: "Edgar E. Iglesias" 
> >
> > Pass the ram_addr offset to xen_map_cache.
> > This is in preparation for adding grant mappings that need
> > to compute the address within the RAMBlock.
> >
> > No functional changes.
> >
> > Signed-off-by: Edgar E. Iglesias 
> > ---
> >  hw/xen/xen-mapcache.c | 16 +++-
> >  include/sysemu/xen-mapcache.h |  2 ++
> >  system/physmem.c  |  9 +
> >  3 files changed, 18 insertions(+), 9 deletions(-)
> >
> > diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
> > index ec95445696..26bc38a9e3 100644
> > --- a/hw/xen/xen-mapcache.c
> > +++ b/hw/xen/xen-mapcache.c
> > @@ -167,7 +167,8 @@ static void xen_remap_bucket(MapCache *mc,
> >   void *vaddr,
> >   hwaddr size,
> >   hwaddr address_index,
> > - bool dummy)
> > + bool dummy,
> > + ram_addr_t ram_offset)
> >  {
> >  uint8_t *vaddr_base;
> >  xen_pfn_t *pfns;
> > @@ -266,6 +267,7 @@ static void xen_remap_bucket(MapCache *mc,
> >
> >  static uint8_t *xen_map_cache_unlocked(MapCache *mc,
> > hwaddr phys_addr, hwaddr size,
> > +   ram_addr_t ram_offset,
> > uint8_t lock, bool dma, bool 
> > is_write)
> >  {
> >  MapCacheEntry *entry, *pentry = NULL,
> > @@ -337,14 +339,16 @@ tryagain:
> >  if (!entry) {
> >  entry = g_new0(MapCacheEntry, 1);
> >  pentry->next = entry;
> > -xen_remap_bucket(mc, entry, NULL, cache_size, address_index, 
> > dummy);
> > +xen_remap_bucket(mc, entry, NULL, cache_size, address_index, dummy,
> > + ram_offset);
> >  } else if (!entry->lock) {
> >  if (!entry->vaddr_base || entry->paddr_index != address_index ||
> >  entry->size != cache_size ||
> >  !test_bits(address_offset >> XC_PAGE_SHIFT,
> >  test_bit_size >> XC_PAGE_SHIFT,
> >  entry->valid_mapping)) {
> > -xen_remap_bucket(mc, entry, NULL, cache_size, address_index, 
> > dummy);
> > +xen_remap_bucket(mc, entry, NULL, cache_size, address_index, 
> > dummy,
> > + ram_offset);
> >  }
> >  }
> >
> > @@ -391,13 +395,15 @@ tryagain:
> >
> >  uint8_t *xen_map_cache(MemoryRegion *mr,
> > hwaddr phys_addr, hwaddr size,
> > +   ram_addr_t ram_addr_offset,
> > uint8_t lock, bool dma,
> > bool is_write)
> >  {
> >  uint8_t *p;
> >
> >  mapcache_lock(mapcache);
> > -p = xen_map_cache_unlocked(mapcache, phys_addr, size, lock, dma, 
> > is_write);
> > +p = xen_map_cache_unlocked(mapcache, phys_addr, size, ram_addr_offset,
> > +   lock, dma, is_write);
> >  mapcache_unlock(mapcache);
> >  return p;
> >  }
> > @@ -632,7 +638,7 @@ static uint8_t 
> > *xen_replace_cache_entry_unlocked(MapCache *mc,
> >  trace_xen_replace_cache_entry_dummy(old_phys_addr, new_phys_addr);
> >
> >  xen_remap_bucket(mc, entry, entry->vaddr_base,
> > - cache_size, address_index, false);
> > + cache_size, address_index, false, new_phys_addr);
>
> Everything else makes sense, but I don't understand how can it be that
> new_phys_addr is the block->offset here?
>

Agreed, this should be old_phys_addr propagated via phys_offset from
xen_add_to_physmap().
The reason this didn't have an effect here is that we currently only
use the ram_addr offset for grants,
and xen_replace_cache_entry is never called for grants. Anyway, I'll
fix this in the next version!




>
> >  if (!test_bits(address_offset >> XC_PAGE_SHIFT,
> >  test_bit_size >> XC_PAGE_SHIFT,
> >  entry->valid_mapping)) {
> > diff --git a/include/sysemu/xen-mapcache.h b/include/sysemu/xen-mapcache.h
> > index 1ec9e66752..b5e3ea1bc0 100644
> > --- a/include/sysemu/xen-mapcache.h
> > +++ b/include/sysemu/x

[PATCH v4 6/9] xen/arm64: bpi: Add missing code symbol annotations

2024-05-14 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Use the generic xen/linkage.h macros to annotate code symbols
and add missing annotations.

Signed-off-by: Edgar E. Iglesias 
---
 xen/arch/arm/arm64/bpi.S | 20 
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/xen/arch/arm/arm64/bpi.S b/xen/arch/arm/arm64/bpi.S
index 4e63825220..d6b8defb80 100644
--- a/xen/arch/arm/arm64/bpi.S
+++ b/xen/arch/arm/arm64/bpi.S
@@ -52,14 +52,15 @@
  * micro-architectures in a system.
  */
 .align 11
-ENTRY(__bp_harden_hyp_vecs_start)
+FUNC(__bp_harden_hyp_vecs_start)
 .rept 4
 vectors hyp_traps_vector
 .endr
-ENTRY(__bp_harden_hyp_vecs_end)
+LABEL(__bp_harden_hyp_vecs_end)
+END(__bp_harden_hyp_vecs_start)
 
 .macro mitigate_spectre_bhb_loop count
-ENTRY(__mitigate_spectre_bhb_loop_start_\count)
+FUNC(__mitigate_spectre_bhb_loop_start_\count)
 stp x0, x1, [sp, #-16]!
 mov x0, \count
 .Lspectre_bhb_loop\@:
@@ -68,11 +69,12 @@ ENTRY(__mitigate_spectre_bhb_loop_start_\count)
 b.ne.Lspectre_bhb_loop\@
 sb
 ldp x0, x1, [sp], #16
-ENTRY(__mitigate_spectre_bhb_loop_end_\count)
+LABEL(__mitigate_spectre_bhb_loop_end_\count)
+END(__mitigate_spectre_bhb_loop_start_\count)
 .endm
 
 .macro smccc_workaround num smcc_id
-ENTRY(__smccc_workaround_smc_start_\num)
+FUNC(__smccc_workaround_smc_start_\num)
 sub sp, sp, #(8 * 4)
 stp x0, x1, [sp, #(8 * 2)]
 stp x2, x3, [sp, #(8 * 0)]
@@ -81,13 +83,15 @@ ENTRY(__smccc_workaround_smc_start_\num)
 ldp x2, x3, [sp, #(8 * 0)]
 ldp x0, x1, [sp, #(8 * 2)]
 add sp, sp, #(8 * 4)
-ENTRY(__smccc_workaround_smc_end_\num)
+LABEL(__smccc_workaround_smc_end_\num)
+END(__smccc_workaround_smc_start_\num)
 .endm
 
-ENTRY(__mitigate_spectre_bhb_clear_insn_start)
+FUNC(__mitigate_spectre_bhb_clear_insn_start)
 clearbhb
 isb
-ENTRY(__mitigate_spectre_bhb_clear_insn_end)
+LABEL(__mitigate_spectre_bhb_clear_insn_end)
+END(__mitigate_spectre_bhb_clear_insn_start)
 
 mitigate_spectre_bhb_loop 8
 mitigate_spectre_bhb_loop 24
-- 
2.40.1




[PATCH v4 2/9] xen/arm64: smc: Add missing code symbol annotations

2024-05-14 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Use the generic xen/linkage.h macros to annotate code symbols
and add missing annotations.

Signed-off-by: Edgar E. Iglesias 
Reviewed-by: Stefano Stabellini 
---
 xen/arch/arm/arm64/smc.S | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/xen/arch/arm/arm64/smc.S b/xen/arch/arm/arm64/smc.S
index fc6b676e2e..68b05e8ddd 100644
--- a/xen/arch/arm/arm64/smc.S
+++ b/xen/arch/arm/arm64/smc.S
@@ -19,7 +19,7 @@
  *  register_t a6, register_t a7,
  *  struct arm_smccc_res *res)
  */
-ENTRY(__arm_smccc_1_0_smc)
+FUNC(__arm_smccc_1_0_smc)
 smc #0
 ldr x4, [sp]
 cbz x4, 1f  /* No need to store the result */
@@ -27,12 +27,13 @@ ENTRY(__arm_smccc_1_0_smc)
 stp x2, x3, [x4, #SMCCC_RES_a2]
 1:
 ret
+END(__arm_smccc_1_0_smc)
 
 /*
  * void arm_smccc_1_2_smc(const struct arm_smccc_1_2_regs *args,
  *struct arm_smccc_1_2_regs *res)
  */
-ENTRY(arm_smccc_1_2_smc)
+FUNC(arm_smccc_1_2_smc)
 /* Save `res` and free a GPR that won't be clobbered by SMC call */
 stp x1, x19, [sp, #-16]!
 
@@ -69,3 +70,4 @@ ENTRY(arm_smccc_1_2_smc)
 /* Restore original x19 */
 ldp xzr, x19, [sp], #16
 ret
+END(arm_smccc_1_2_smc)
-- 
2.40.1




[PATCH v4 8/9] xen/arm64: cache: Use the generic xen/linkage.h macros

2024-05-14 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Use the generic xen/linkage.h macros to annotate code symbols.

Signed-off-by: Edgar E. Iglesias 
Reviewed-by: Stefano Stabellini 
---
 xen/arch/arm/arm64/cache.S | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/xen/arch/arm/arm64/cache.S b/xen/arch/arm/arm64/cache.S
index 9a88a2b497..66ed85f735 100644
--- a/xen/arch/arm/arm64/cache.S
+++ b/xen/arch/arm/arm64/cache.S
@@ -40,7 +40,7 @@
  * - kaddr   - kernel address
  * - size- size in question
  */
-ENTRY(__flush_dcache_area)
+FUNC(__flush_dcache_area)
dcache_line_size x2, x3
add x1, x0, x1
sub x3, x2, #1
@@ -51,4 +51,4 @@ ENTRY(__flush_dcache_area)
b.lo1b
dsb sy
ret
-ENDPROC(__flush_dcache_area)
+END(__flush_dcache_area)
-- 
2.40.1




[PATCH v4 1/9] xen/arm64: entry: Add missing code symbol annotations

2024-05-14 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Use the generic xen/linkage.h macros to annotate code symbols
and add missing annotations.

Signed-off-by: Edgar E. Iglesias 
---
 xen/arch/arm/arm64/entry.S | 78 --
 1 file changed, 50 insertions(+), 28 deletions(-)

diff --git a/xen/arch/arm/arm64/entry.S b/xen/arch/arm/arm64/entry.S
index f963c923bb..6251135ebd 100644
--- a/xen/arch/arm/arm64/entry.S
+++ b/xen/arch/arm/arm64/entry.S
@@ -289,21 +289,25 @@
 b   do_bad_mode
 .endm
 
-hyp_sync_invalid:
+FUNC_LOCAL(hyp_sync_invalid)
 entry   hyp=1
 invalid BAD_SYNC
+END(hyp_sync_invalid)
 
-hyp_irq_invalid:
+FUNC_LOCAL(hyp_irq_invalid)
 entry   hyp=1
 invalid BAD_IRQ
+END(hyp_irq_invalid)
 
-hyp_fiq_invalid:
+FUNC_LOCAL(hyp_fiq_invalid)
 entry   hyp=1
 invalid BAD_FIQ
+END(hyp_fiq_invalid)
 
-hyp_error_invalid:
+FUNC_LOCAL(hyp_error_invalid)
 entry   hyp=1
 invalid BAD_ERROR
+END(hyp_error_invalid)
 
 /*
  * SError received while running in the hypervisor mode.
@@ -313,11 +317,12 @@ hyp_error_invalid:
  * simplicity, as SError should be rare and potentially fatal,
  * all interrupts are kept masked.
  */
-hyp_error:
+FUNC_LOCAL(hyp_error)
 entry   hyp=1
 mov x0, sp
 bl  do_trap_hyp_serror
 exithyp=1
+END(hyp_error)
 
 /*
  * Synchronous exception received while running in the hypervisor mode.
@@ -327,7 +332,7 @@ hyp_error:
  * some of them. So we want to inherit the state from the interrupted
  * context.
  */
-hyp_sync:
+FUNC_LOCAL(hyp_sync)
 entry   hyp=1
 
 /* Inherit interrupts */
@@ -338,6 +343,7 @@ hyp_sync:
 mov x0, sp
 bl  do_trap_hyp_sync
 exithyp=1
+END(hyp_sync)
 
 /*
  * IRQ received while running in the hypervisor mode.
@@ -352,7 +358,7 @@ hyp_sync:
  * would require some rework in some paths (e.g. panic, livepatch) to
  * ensure the ordering is enforced everywhere.
  */
-hyp_irq:
+FUNC_LOCAL(hyp_irq)
 entry   hyp=1
 
 /* Inherit D, A, F interrupts and keep I masked */
@@ -365,8 +371,9 @@ hyp_irq:
 mov x0, sp
 bl  do_trap_irq
 exithyp=1
+END(hyp_irq)
 
-guest_sync:
+FUNC_LOCAL(guest_sync)
 /*
  * Save x0, x1 in advance
  */
@@ -413,8 +420,9 @@ fastpath_out_workaround:
 mov x1, xzr
 eret
 sb
+END(guest_sync)
 
-wa2_ssbd:
+FUNC_LOCAL(wa2_ssbd)
 #ifdef CONFIG_ARM_SSBD
 alternative_cb arm_enable_wa2_handling
 b   wa2_end
@@ -450,42 +458,55 @@ wa2_end:
 mov x0, xzr
 eret
 sb
-guest_sync_slowpath:
+END(wa2_ssbd)
+
+FUNC_LOCAL(guest_sync_slowpath)
 /*
  * x0/x1 may have been scratch by the fast path above, so avoid
  * to save them.
  */
 guest_vector compat=0, iflags=IFLAGS__AI_, trap=guest_sync, 
save_x0_x1=0
+END(guest_sync_slowpath)
 
-guest_irq:
+FUNC_LOCAL(guest_irq)
 guest_vector compat=0, iflags=IFLAGS__A__, trap=irq
+END(guest_irq)
 
-guest_fiq_invalid:
+FUNC_LOCAL(guest_fiq_invalid)
 entry   hyp=0, compat=0
 invalid BAD_FIQ
+END(guest_fiq_invalid)
 
-guest_error:
+FUNC_LOCAL(guest_error)
 guest_vector compat=0, iflags=IFLAGS__AI_, trap=guest_serror
+END(guest_error)
 
-guest_sync_compat:
+FUNC_LOCAL(guest_sync_compat)
 guest_vector compat=1, iflags=IFLAGS__AI_, trap=guest_sync
+END(guest_sync_compat)
 
-guest_irq_compat:
+FUNC_LOCAL(guest_irq_compat)
 guest_vector compat=1, iflags=IFLAGS__A__, trap=irq
+END(guest_irq_compat)
 
-guest_fiq_invalid_compat:
+FUNC_LOCAL(guest_fiq_invalid_compat)
 entry   hyp=0, compat=1
 invalid BAD_FIQ
+END(guest_fiq_invalid_compat)
 
-guest_error_compat:
+FUNC_LOCAL(guest_error_compat)
 guest_vector compat=1, iflags=IFLAGS__AI_, trap=guest_serror
+END(guest_error_compat)
 
-ENTRY(return_to_new_vcpu32)
+FUNC(return_to_new_vcpu32)
 exithyp=0, compat=1
-ENTRY(return_to_new_vcpu64)
+END(return_to_new_vcpu32)
+
+FUNC(return_to_new_vcpu64)
 exithyp=0, compat=0
+END(return_to_new_vcpu64)
 
-return_from_trap:
+FUNC_LOCAL(return_from_trap)
 msr daifset, #IFLAGS___I_ /* Mask interrupts */
 
 ldr x21, [sp, #UREGS_PC]/* load ELR */
@@ -524,6 +545,7 @@ return_from_trap:
 
 eret
 sb
+END(return_from_trap)
 
 /*
  * Consume pending SError generated by the guest if any.
@@ -536,7 +558,7 @@ return_from_trap:
  * it. So the function will unmask SError exception for a small window and
  * then mask it again.
  */
-check_pending_guest_serror:
+FUNC_LOCAL(check_pending_guest_serror)
 /*
  * Save elr_el2 to check whether the pending SError exception takes
  * place while we are doing this sync exception.
@@ -562,13 +584,11 @@ check_pending_guest_serror:
  * exception handler, and the elr_el2 w

[PATCH v4 4/9] xen/arm64: head: Add missing code symbol annotations

2024-05-14 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Use the generic xen/linkage.h macros to annotate code symbols
and add missing annotations.

Signed-off-by: Edgar E. Iglesias 
---
 xen/arch/arm/arm64/head.S | 51 +--
 1 file changed, 27 insertions(+), 24 deletions(-)

diff --git a/xen/arch/arm/arm64/head.S b/xen/arch/arm/arm64/head.S
index fb297e9eb5..2fa07dc3a0 100644
--- a/xen/arch/arm/arm64/head.S
+++ b/xen/arch/arm/arm64/head.S
@@ -90,7 +90,7 @@
  * 4K-aligned address.
  */
 
-GLOBAL(start)
+FUNC(start)
 /*
  * DO NOT MODIFY. Image header expected by Linux boot-loaders.
  */
@@ -102,6 +102,7 @@ efi_head:
  */
 add x13, x18, #0x16
 b   real_start   /* branch to kernel start */
+END(start)
 .quad   0/* Image load offset from start of RAM */
 .quad   _end - start /* Effective size of kernel image, 
little-endian */
 .quad   __HEAD_FLAGS /* Informative flags, little-endian */
@@ -223,7 +224,7 @@ section_table:
 .align  5
 #endif /* CONFIG_ARM_EFI */
 
-real_start:
+FUNC_LOCAL(real_start)
 /* BSS should be zeroed when booting without EFI */
 mov   x26, #0/* x26 := skip_zero_bss */
 
@@ -263,9 +264,9 @@ primary_switched:
 mov   x1, x21/* x1 := paddr(FDT) */
 ldr   x2, =start_xen
 b launch
-ENDPROC(real_start)
+END(real_start)
 
-GLOBAL(init_secondary)
+FUNC(init_secondary)
 msr   DAIFSet, 0xf   /* Disable all interrupts */
 
 /* Find out where we are */
@@ -304,7 +305,7 @@ secondary_switched:
 /* Jump to C world */
 ldr   x2, =start_secondary
 b launch
-ENDPROC(init_secondary)
+END(init_secondary)
 
 /*
  * Check if the CPU has been booted in Hypervisor mode.
@@ -313,7 +314,7 @@ ENDPROC(init_secondary)
  *
  * Clobbers x0 - x5
  */
-check_cpu_mode:
+FUNC_LOCAL(check_cpu_mode)
 PRINT_ID("- Current EL ")
 mrs   x5, CurrentEL
 print_reg x5
@@ -329,7 +330,7 @@ check_cpu_mode:
 PRINT_ID("- Xen must be entered in NS EL2 mode -\r\n")
 PRINT_ID("- Please update the bootloader -\r\n")
 b fail
-ENDPROC(check_cpu_mode)
+END(check_cpu_mode)
 
 /*
  * Zero BSS
@@ -339,7 +340,7 @@ ENDPROC(check_cpu_mode)
  *
  * Clobbers x0 - x3
  */
-zero_bss:
+FUNC_LOCAL(zero_bss)
 /* Zero BSS only when requested */
 cbnz  x26, skip_bss
 
@@ -353,14 +354,14 @@ zero_bss:
 
 skip_bss:
 ret
-ENDPROC(zero_bss)
+END(zero_bss)
 
 /*
  * Initialize the processor for turning the MMU on.
  *
  * Clobbers x0 - x3
  */
-cpu_init:
+FUNC_LOCAL(cpu_init)
 PRINT_ID("- Initialize CPU -\r\n")
 
 /* Set up memory attribute type tables */
@@ -399,7 +400,7 @@ cpu_init:
  */
 msr spsel, #1
 ret
-ENDPROC(cpu_init)
+END(cpu_init)
 
 /*
  * Setup the initial stack and jump to the C world
@@ -411,7 +412,7 @@ ENDPROC(cpu_init)
  *
  * Clobbers x3
  */
-launch:
+FUNC_LOCAL(launch)
 ldr   x3, =init_data
 add   x3, x3, #INITINFO_stack /* Find the boot-time stack */
 ldr   x3, [x3]
@@ -421,13 +422,14 @@ launch:
 
 /* Jump to C world */
 brx2
-ENDPROC(launch)
+END(launch)
 
 /* Fail-stop */
-fail:   PRINT_ID("- Boot failed -\r\n")
+FUNC_LOCAL(fail)
+PRINT_ID("- Boot failed -\r\n")
 1:  wfe
 b 1b
-ENDPROC(fail)
+END(fail)
 
 #ifdef CONFIG_EARLY_PRINTK
 /*
@@ -438,14 +440,14 @@ ENDPROC(fail)
  *
  * Clobbers x0 - x1
  */
-init_uart:
+FUNC_LOCAL(init_uart)
 ldr   x23, =CONFIG_EARLY_UART_BASE_ADDRESS
 #ifdef CONFIG_EARLY_UART_INIT
 early_uart_init x23, 0
 #endif
 PRINT("- UART enabled -\r\n")
 ret
-ENDPROC(init_uart)
+END(init_uart)
 
 /*
  * Print early debug messages.
@@ -454,7 +456,7 @@ ENDPROC(init_uart)
  * x23: Early UART base address
  * Clobbers x0-x1
  */
-ENTRY(asm_puts)
+FUNC(asm_puts)
 early_uart_ready x23, 1
 ldrb  w1, [x0], #1   /* Load next char */
 cbz   w1, 1f /* Exit on nul */
@@ -462,7 +464,7 @@ ENTRY(asm_puts)
 b asm_puts
 1:
 ret
-ENDPROC(asm_puts)
+END(asm_puts)
 
 /*
  * Print a 64-bit number in hex.
@@ -471,7 +473,7 @@ ENDPROC(asm_puts)
  * x23: Early UART base address
  * Clobbers x0-x3
  */
-ENTRY(asm_putn)
+FUNC(asm_putn)
 adr_l x1, hex
 mov   x3, #16
 1:
@@ -484,7 +486,7 @@ ENTRY(asm_putn)
 subs  x3, x3, #1
 b.ne  1b
 ret
-ENDPROC(asm_putn)
+END(asm_putn)
 
 RODATA_SECT(.rodata.idmap, hex, "0123456789abcdef")
 
@@ -493,16 +495,17 @@ RODATA_SECT(.rodata.idmap, hex, "0123456789abcdef")
 /* This provides a C-API version of __lookup_processor_type
  * TODO: For now, the implementation return NULL every time
  */
-ENTRY(lookup_processor_type)
+FUNC(lookup_pr

[PATCH v4 9/9] xen/arm64: lib: Use the generic xen/linkage.h macros

2024-05-14 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Use the generic xen/linkage.h macros to annotate code symbols.

Signed-off-by: Edgar E. Iglesias 
Reviewed-by: Stefano Stabellini 
---
 xen/arch/arm/arm64/lib/memchr.S  | 4 ++--
 xen/arch/arm/arm64/lib/memcmp.S  | 4 ++--
 xen/arch/arm/arm64/lib/memcpy.S  | 4 ++--
 xen/arch/arm/arm64/lib/memmove.S | 4 ++--
 xen/arch/arm/arm64/lib/memset.S  | 4 ++--
 xen/arch/arm/arm64/lib/strchr.S  | 4 ++--
 xen/arch/arm/arm64/lib/strcmp.S  | 4 ++--
 xen/arch/arm/arm64/lib/strlen.S  | 4 ++--
 xen/arch/arm/arm64/lib/strncmp.S | 4 ++--
 xen/arch/arm/arm64/lib/strnlen.S | 4 ++--
 xen/arch/arm/arm64/lib/strrchr.S | 4 ++--
 11 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/xen/arch/arm/arm64/lib/memchr.S b/xen/arch/arm/arm64/lib/memchr.S
index 81f113bb1c..3d8aeca3ca 100644
--- a/xen/arch/arm/arm64/lib/memchr.S
+++ b/xen/arch/arm/arm64/lib/memchr.S
@@ -29,7 +29,7 @@
  * Returns:
  * x0 - address of first occurrence of 'c' or 0
  */
-ENTRY(memchr)
+FUNC(memchr)
and w1, w1, #0xff
 1: subsx2, x2, #1
b.mi2f
@@ -40,4 +40,4 @@ ENTRY(memchr)
ret
 2: mov x0, #0
ret
-ENDPROC(memchr)
+END(memchr)
diff --git a/xen/arch/arm/arm64/lib/memcmp.S b/xen/arch/arm/arm64/lib/memcmp.S
index 87c2537ffe..d77dd4ce52 100644
--- a/xen/arch/arm/arm64/lib/memcmp.S
+++ b/xen/arch/arm/arm64/lib/memcmp.S
@@ -57,7 +57,7 @@ pos   .reqx11
 limit_wd   .reqx12
 mask   .reqx13
 
-ENTRY(memcmp)
+FUNC(memcmp)
cbz limit, .Lret0
eor tmp1, src1, src2
tst tmp1, #7
@@ -254,4 +254,4 @@ CPU_LE( rev data2, data2 )
 .Lret0:
mov result, #0
ret
-ENDPROC(memcmp)
+END(memcmp)
diff --git a/xen/arch/arm/arm64/lib/memcpy.S b/xen/arch/arm/arm64/lib/memcpy.S
index d90d20ef3e..1e04b79010 100644
--- a/xen/arch/arm/arm64/lib/memcpy.S
+++ b/xen/arch/arm/arm64/lib/memcpy.S
@@ -55,7 +55,7 @@ C_h   .reqx12
 D_l.reqx13
 D_h.reqx14
 
-ENTRY(memcpy)
+FUNC(memcpy)
mov dst, dstin
cmp count, #16
/*When memory length is less than 16, the accessed are not aligned.*/
@@ -197,4 +197,4 @@ ENTRY(memcpy)
tst count, #0x3f
b.ne.Ltail63
ret
-ENDPROC(memcpy)
+END(memcpy)
diff --git a/xen/arch/arm/arm64/lib/memmove.S b/xen/arch/arm/arm64/lib/memmove.S
index a49de845d0..14438dbe9c 100644
--- a/xen/arch/arm/arm64/lib/memmove.S
+++ b/xen/arch/arm/arm64/lib/memmove.S
@@ -56,7 +56,7 @@ C_h   .reqx12
 D_l.reqx13
 D_h.reqx14
 
-ENTRY(memmove)
+FUNC(memmove)
cmp dstin, src
b.lomemcpy
add tmp1, src, count
@@ -193,4 +193,4 @@ ENTRY(memmove)
tst count, #0x3f
b.ne.Ltail63
ret
-ENDPROC(memmove)
+END(memmove)
diff --git a/xen/arch/arm/arm64/lib/memset.S b/xen/arch/arm/arm64/lib/memset.S
index 5bf751521b..367fa60175 100644
--- a/xen/arch/arm/arm64/lib/memset.S
+++ b/xen/arch/arm/arm64/lib/memset.S
@@ -53,7 +53,7 @@ dst   .reqx8
 tmp3w  .reqw9
 tmp3   .reqx9
 
-ENTRY(memset)
+FUNC(memset)
mov dst, dstin  /* Preserve return value.  */
and A_lw, val, #255
orr A_lw, A_lw, A_lw, lsl #8
@@ -212,4 +212,4 @@ ENTRY(memset)
andscount, count, zva_bits_x
b.ne.Ltail_maybe_long
ret
-ENDPROC(memset)
+END(memset)
diff --git a/xen/arch/arm/arm64/lib/strchr.S b/xen/arch/arm/arm64/lib/strchr.S
index 0506b0ff7f..83fd81e8ef 100644
--- a/xen/arch/arm/arm64/lib/strchr.S
+++ b/xen/arch/arm/arm64/lib/strchr.S
@@ -27,7 +27,7 @@
  * Returns:
  * x0 - address of first occurrence of 'c' or 0
  */
-ENTRY(strchr)
+FUNC(strchr)
and w1, w1, #0xff
 1: ldrbw2, [x0], #1
cmp w2, w1
@@ -37,4 +37,4 @@ ENTRY(strchr)
cmp w2, w1
cselx0, x0, xzr, eq
ret
-ENDPROC(strchr)
+END(strchr)
diff --git a/xen/arch/arm/arm64/lib/strcmp.S b/xen/arch/arm/arm64/lib/strcmp.S
index c6f42dd255..7677108e26 100644
--- a/xen/arch/arm/arm64/lib/strcmp.S
+++ b/xen/arch/arm/arm64/lib/strcmp.S
@@ -59,7 +59,7 @@ tmp3  .reqx9
 zeroones   .reqx10
 pos.reqx11
 
-ENTRY(strcmp)
+FUNC(strcmp)
eor tmp1, src1, src2
mov zeroones, #REP8_01
tst tmp1, #7
@@ -230,4 +230,4 @@ CPU_BE( orr syndrome, diff, has_nul )
lsr data1, data1, #56
sub result, data1, data2, lsr #56
ret
-ENDPROC(strcmp)
+END(strcmp)
diff --git a/xen/arch/arm/arm64/lib/strlen.S b/xen/arch/arm/arm64/lib/strlen.S
index fb6aaf1a6a..10feedaf81 100644
--- a/xen/arch/arm/arm64/lib/strlen.S
+++ b/xen/arch/arm/arm64/lib/strlen.S
@@ -56,7 +56,7 @@ pos   .reqx12
 #define REP8_7f 0x7f7f7f7f7f7f7f7f
 #define REP8_80 0x8080808080808080
 
-ENTRY(strlen)
+FUNC(strlen)
mov zeroones, #REP8_01
bic src, srcin, #15
andstmp1, srcin, #15
@@ -123,4 +123,4 @@ C

[PATCH v4 7/9] xen/arm64: mmu/head: Add missing code symbol annotations

2024-05-14 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Use the generic xen/linkage.h macros to annotate code symbols
and add missing annotations.

Signed-off-by: Edgar E. Iglesias 
---
 xen/arch/arm/arm64/mmu/head.S | 29 +++--
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/xen/arch/arm/arm64/mmu/head.S b/xen/arch/arm/arm64/mmu/head.S
index fa40b696dd..665a51a337 100644
--- a/xen/arch/arm/arm64/mmu/head.S
+++ b/xen/arch/arm/arm64/mmu/head.S
@@ -138,7 +138,7 @@
  *
  * Clobbers x0 - x4
  */
-create_page_tables:
+FUNC_LOCAL(create_page_tables)
 /* Prepare the page-tables for mapping Xen */
 ldr   x0, =XEN_VIRT_START
 create_table_entry boot_pgtable, boot_first, x0, 0, x1, x2, x3
@@ -260,7 +260,7 @@ virtphys_clash:
 /* Identity map clashes with boot_third, which we cannot handle yet */
 PRINT("- Unable to build boot page tables - virt and phys addresses 
clash. -\r\n")
 b fail
-ENDPROC(create_page_tables)
+END(create_page_tables)
 
 /*
  * Turn on the Data Cache and the MMU. The function will return on the 1:1
@@ -273,7 +273,7 @@ ENDPROC(create_page_tables)
  *
  * Clobbers x0 - x5
  */
-enable_mmu:
+FUNC_LOCAL(enable_mmu)
 mov   x4, x0
 mov   x5, x1
 PRINT_ID("- Turning on paging -\r\n")
@@ -304,7 +304,7 @@ enable_mmu:
 PRINT_ID("- Paging turned on -\r\n")
 
 ret
-ENDPROC(enable_mmu)
+END(enable_mmu)
 
 /*
  * Enable mm (turn on the data cache and the MMU) for secondary CPUs.
@@ -316,7 +316,7 @@ ENDPROC(enable_mmu)
  *
  * Clobbers x0 - x6
  */
-ENTRY(enable_secondary_cpu_mm)
+FUNC(enable_secondary_cpu_mm)
 mov   x6, lr
 
 load_paddr x0, init_ttbr
@@ -328,7 +328,7 @@ ENTRY(enable_secondary_cpu_mm)
 
 /* Return to the virtual address requested by the caller. */
 ret
-ENDPROC(enable_secondary_cpu_mm)
+END(enable_secondary_cpu_mm)
 
 /*
  * Enable mm (turn on the data cache and the MMU) for the boot CPU.
@@ -340,7 +340,7 @@ ENDPROC(enable_secondary_cpu_mm)
  *
  * Clobbers x0 - x6
  */
-ENTRY(enable_boot_cpu_mm)
+FUNC(enable_boot_cpu_mm)
 mov   x6, lr
 
 blcreate_page_tables
@@ -365,7 +365,7 @@ ENTRY(enable_boot_cpu_mm)
  * by the caller.
  */
 b remove_identity_mapping
-ENDPROC(enable_boot_cpu_mm)
+END(enable_boot_cpu_mm)
 
 /*
  * Remove the 1:1 map from the page-tables. It is not easy to keep track
@@ -377,7 +377,7 @@ ENDPROC(enable_boot_cpu_mm)
  *
  * Clobbers x0 - x1
  */
-remove_identity_mapping:
+FUNC_LOCAL(remove_identity_mapping)
 /*
  * Find the zeroeth slot used. Remove the entry from zeroeth
  * table if the slot is not XEN_ZEROETH_SLOT.
@@ -419,20 +419,21 @@ identity_mapping_removed:
 flush_xen_tlb_local
 
 ret
-ENDPROC(remove_identity_mapping)
+END(remove_identity_mapping)
 
 /* Fail-stop */
-fail:   PRINT("- Boot failed -\r\n")
+FUNC_LOCAL(fail)
+PRINT("- Boot failed -\r\n")
 1:  wfe
 b 1b
-ENDPROC(fail)
+END(fail)
 
 /*
  * Switch TTBR
  *
  * x0ttbr
  */
-ENTRY(switch_ttbr_id)
+FUNC(switch_ttbr_id)
 /* 1) Ensure any previous read/write have completed */
 dsbish
 isb
@@ -464,7 +465,7 @@ ENTRY(switch_ttbr_id)
 isb
 
 ret
-ENDPROC(switch_ttbr_id)
+END(switch_ttbr_id)
 
 /*
  * Local variables:
-- 
2.40.1




[PATCH v4 3/9] xen/arm64: sve: Add missing code symbol annotations

2024-05-14 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Use the generic xen/linkage.h macros to annotate code symbols
and add missing annotations.

Signed-off-by: Edgar E. Iglesias 
Reviewed-by: Stefano Stabellini 
---
 xen/arch/arm/arm64/sve-asm.S | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/xen/arch/arm/arm64/sve-asm.S b/xen/arch/arm/arm64/sve-asm.S
index 59dbefbbb2..2d8b895f07 100644
--- a/xen/arch/arm/arm64/sve-asm.S
+++ b/xen/arch/arm/arm64/sve-asm.S
@@ -161,9 +161,10 @@
 .endm
 
 /* Gets the current vector register size in bytes */
-GLOBAL(sve_get_hw_vl)
+FUNC(sve_get_hw_vl)
 _sve_rdvl 0, 1
 ret
+END(sve_get_hw_vl)
 
 /*
  * Save the SVE context
@@ -172,9 +173,10 @@ GLOBAL(sve_get_hw_vl)
  * x1 - pointer to buffer for P0-15
  * x2 - Save FFR if non-zero
  */
-GLOBAL(sve_save_ctx)
+FUNC(sve_save_ctx)
 sve_save 0, 1, x2
 ret
+END(sve_save_ctx)
 
 /*
  * Load the SVE context
@@ -183,9 +185,10 @@ GLOBAL(sve_save_ctx)
  * x1 - pointer to buffer for P0-15
  * x2 - Restore FFR if non-zero
  */
-GLOBAL(sve_load_ctx)
+FUNC(sve_load_ctx)
 sve_load 0, 1, x2
 ret
+END(sve_load_ctx)
 
 /*
  * Local variables:
-- 
2.40.1




[PATCH v4 0/9] xen/arm: arm64: Annotate code symbols

2024-05-14 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

On the way towards Xen safety certification we're evaluating the use
of tools to collect code-coverage/profiling information from execution
traces. Some tools rely on ELF symbols for code being declared with
type FUNC and having a symbol size.

We currently annotate some symbols but not all. Also, there seems to be
different ways to do the annotation.

This series now converts all the .S files under xen/arm/arm64 to use
the macros from xen/linkage.h and also adds missing code symbol
annotations for global symbols. There are still some local labels that
are left unmodified.

Best regards,
Edgar

ChangeLog:

v3 -> v4:
* Add newline between FUNC_LOCAL and PRINT_ID.
* Use LABEL instead of GLOBAL in bpi.S.
* Changed .global -> LABEL in entry.S (dropped Stefanos RB tag).

v2 -> v3:
* Convert and add annotations for all of xen/arm/arm64.
* Fix commit message for entry.S.

v1 -> v2:
* Drop RFC.
* Squash into a single patch to avoid confusion.


Edgar E. Iglesias (9):
  xen/arm64: entry: Add missing code symbol annotations
  xen/arm64: smc: Add missing code symbol annotations
  xen/arm64: sve: Add missing code symbol annotations
  xen/arm64: head: Add missing code symbol annotations
  xen/arm64: debug: Add missing code symbol annotations
  xen/arm64: bpi: Add missing code symbol annotations
  xen/arm64: mmu/head: Add missing code symbol annotations
  xen/arm64: cache: Use the generic xen/linkage.h macros
  xen/arm64: lib: Use the generic xen/linkage.h macros

 xen/arch/arm/arm64/bpi.S | 20 
 xen/arch/arm/arm64/cache.S   |  4 +-
 xen/arch/arm/arm64/debug.S   |  6 ++-
 xen/arch/arm/arm64/entry.S   | 78 
 xen/arch/arm/arm64/head.S| 51 +++--
 xen/arch/arm/arm64/lib/memchr.S  |  4 +-
 xen/arch/arm/arm64/lib/memcmp.S  |  4 +-
 xen/arch/arm/arm64/lib/memcpy.S  |  4 +-
 xen/arch/arm/arm64/lib/memmove.S |  4 +-
 xen/arch/arm/arm64/lib/memset.S  |  4 +-
 xen/arch/arm/arm64/lib/strchr.S  |  4 +-
 xen/arch/arm/arm64/lib/strcmp.S  |  4 +-
 xen/arch/arm/arm64/lib/strlen.S  |  4 +-
 xen/arch/arm/arm64/lib/strncmp.S |  4 +-
 xen/arch/arm/arm64/lib/strnlen.S |  4 +-
 xen/arch/arm/arm64/lib/strrchr.S |  4 +-
 xen/arch/arm/arm64/mmu/head.S| 29 ++--
 xen/arch/arm/arm64/smc.S |  6 ++-
 xen/arch/arm/arm64/sve-asm.S |  9 ++--
 19 files changed, 142 insertions(+), 105 deletions(-)

-- 
2.40.1




[PATCH v4 5/9] xen/arm64: debug: Add missing code symbol annotations

2024-05-14 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Use the generic xen/linkage.h macros to annotate code symbols
and add missing annotations.

Signed-off-by: Edgar E. Iglesias 
Reviewed-by: Stefano Stabellini 
---
 xen/arch/arm/arm64/debug.S | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/xen/arch/arm/arm64/debug.S b/xen/arch/arm/arm64/debug.S
index 71cad9d762..c3d02c33d7 100644
--- a/xen/arch/arm/arm64/debug.S
+++ b/xen/arch/arm/arm64/debug.S
@@ -27,17 +27,19 @@
  * Print a character on the UART - this function is called by C
  * x0: character to print
  */
-GLOBAL(early_putch)
+FUNC(early_putch)
 ldr   x15, =EARLY_UART_VIRTUAL_ADDRESS
 early_uart_ready x15, 1
 early_uart_transmit x15, w0
 ret
+END(early_putch)
 
 /* Flush the UART - this function is called by C */
-GLOBAL(early_flush)
+FUNC(early_flush)
 ldr   x15, =EARLY_UART_VIRTUAL_ADDRESS  /* x15 := VA UART base address 
*/
 early_uart_ready x15, 1
 ret
+END(early_flush)
 
 /*
  * Local variables:
-- 
2.40.1




Re: [PATCH v3 6/9] xen/arm64: bpi: Add missing code symbol annotations

2024-05-10 Thread Edgar E. Iglesias
On Tue, May 7, 2024 at 7:37 PM Julien Grall  wrote:
>
>
>
> On 07/05/2024 17:55, Edgar E. Iglesias wrote:
> > On Tue, May 7, 2024 at 11:57 AM Julien Grall  wrote:
> > Hi Julien,
>
> Hi Edgar,
>
> >
> > The reason I choose FUNC for the start of the symbol is because these
> > symbols contain
> > executable code (not only a table of pointers to code somewhere else)
> > and the ELF spec
> > says that STT_FUNC means the symbol contains functions or other executable
> > code (not only callable functions IIUC):
> >
> > "STT_FUNC The symbol is associated with a function or other executable 
> > code."
> > https://refspecs.linuxbase.org/elf/elf.pdf
> > (Symbol Table 1-20).
>
> Thanks for the pointer. I originally did intend to suggest the change,
> but then I saw the use of LABEL in x86 (such as svm_stgi_label). There
> are a few others example with LABEL_LOCAL.
>
> AFAICT, this is also executable code which the only difference that it
> is not meant to be called by someone else. Furthermore, LABEL is using
> DO_CODE_ALIGN(...) for the alignment which imply that it is intended to
> be used by executable code. So I thought the only difference was whether
> the label was intended to be used as a function.
>

Thanks Julien, yes, good points.

> >
> > I think using LABEL instead of GLOBAL for the _end labels of these
> > code sequences makes sense.
> > I'm happy to change the _start labels to LABEL too if you guys feel
> > that's better.
>
> I have to admit I am little confused with the difference between LABEL
> vs FUNC. I think I will need some guidance from Jan (he introduced
> linkage.h).
>

Jan, do you have any guidance on this specific case using FUNC , LABEL
(or something else)?

Cheers,
Edgar



[PATCH v5 6/8] xen: mapcache: Pass the ram_addr offset to xen_map_cache()

2024-05-09 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Pass the ram_addr offset to xen_map_cache.
This is in preparation for adding grant mappings that need
to compute the address within the RAMBlock.

No functional changes.

Signed-off-by: Edgar E. Iglesias 
---
 hw/xen/xen-mapcache.c | 16 +++-
 include/sysemu/xen-mapcache.h |  2 ++
 system/physmem.c  |  9 +
 3 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
index ec95445696..26bc38a9e3 100644
--- a/hw/xen/xen-mapcache.c
+++ b/hw/xen/xen-mapcache.c
@@ -167,7 +167,8 @@ static void xen_remap_bucket(MapCache *mc,
  void *vaddr,
  hwaddr size,
  hwaddr address_index,
- bool dummy)
+ bool dummy,
+ ram_addr_t ram_offset)
 {
 uint8_t *vaddr_base;
 xen_pfn_t *pfns;
@@ -266,6 +267,7 @@ static void xen_remap_bucket(MapCache *mc,
 
 static uint8_t *xen_map_cache_unlocked(MapCache *mc,
hwaddr phys_addr, hwaddr size,
+   ram_addr_t ram_offset,
uint8_t lock, bool dma, bool is_write)
 {
 MapCacheEntry *entry, *pentry = NULL,
@@ -337,14 +339,16 @@ tryagain:
 if (!entry) {
 entry = g_new0(MapCacheEntry, 1);
 pentry->next = entry;
-xen_remap_bucket(mc, entry, NULL, cache_size, address_index, dummy);
+xen_remap_bucket(mc, entry, NULL, cache_size, address_index, dummy,
+ ram_offset);
 } else if (!entry->lock) {
 if (!entry->vaddr_base || entry->paddr_index != address_index ||
 entry->size != cache_size ||
 !test_bits(address_offset >> XC_PAGE_SHIFT,
 test_bit_size >> XC_PAGE_SHIFT,
 entry->valid_mapping)) {
-xen_remap_bucket(mc, entry, NULL, cache_size, address_index, 
dummy);
+xen_remap_bucket(mc, entry, NULL, cache_size, address_index, dummy,
+ ram_offset);
 }
 }
 
@@ -391,13 +395,15 @@ tryagain:
 
 uint8_t *xen_map_cache(MemoryRegion *mr,
hwaddr phys_addr, hwaddr size,
+   ram_addr_t ram_addr_offset,
uint8_t lock, bool dma,
bool is_write)
 {
 uint8_t *p;
 
 mapcache_lock(mapcache);
-p = xen_map_cache_unlocked(mapcache, phys_addr, size, lock, dma, is_write);
+p = xen_map_cache_unlocked(mapcache, phys_addr, size, ram_addr_offset,
+   lock, dma, is_write);
 mapcache_unlock(mapcache);
 return p;
 }
@@ -632,7 +638,7 @@ static uint8_t *xen_replace_cache_entry_unlocked(MapCache 
*mc,
 trace_xen_replace_cache_entry_dummy(old_phys_addr, new_phys_addr);
 
 xen_remap_bucket(mc, entry, entry->vaddr_base,
- cache_size, address_index, false);
+ cache_size, address_index, false, new_phys_addr);
 if (!test_bits(address_offset >> XC_PAGE_SHIFT,
 test_bit_size >> XC_PAGE_SHIFT,
 entry->valid_mapping)) {
diff --git a/include/sysemu/xen-mapcache.h b/include/sysemu/xen-mapcache.h
index 1ec9e66752..b5e3ea1bc0 100644
--- a/include/sysemu/xen-mapcache.h
+++ b/include/sysemu/xen-mapcache.h
@@ -19,6 +19,7 @@ typedef hwaddr (*phys_offset_to_gaddr_t)(hwaddr phys_offset,
 void xen_map_cache_init(phys_offset_to_gaddr_t f,
 void *opaque);
 uint8_t *xen_map_cache(MemoryRegion *mr, hwaddr phys_addr, hwaddr size,
+   ram_addr_t ram_addr_offset,
uint8_t lock, bool dma,
bool is_write);
 ram_addr_t xen_ram_addr_from_mapcache(void *ptr);
@@ -37,6 +38,7 @@ static inline void xen_map_cache_init(phys_offset_to_gaddr_t 
f,
 static inline uint8_t *xen_map_cache(MemoryRegion *mr,
  hwaddr phys_addr,
  hwaddr size,
+ ram_addr_t ram_addr_offset,
  uint8_t lock,
  bool dma,
  bool is_write)
diff --git a/system/physmem.c b/system/physmem.c
index b7847db1a2..33d09f7571 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -2231,13 +2231,14 @@ static void *qemu_ram_ptr_length(RAMBlock *block, 
ram_addr_t addr,
  */
 if (xen_mr_is_memory(block->mr)) {
 return xen_map_cache(block->mr, block->offset + addr,
- len, lock, lock,
- is_write);
+ len, block->offset,
+ lock, lock, is_write);

[PATCH v5 2/8] xen: mapcache: Unmap first entries in buckets

2024-05-09 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

When invalidating memory ranges, if we happen to hit the first
entry in a bucket we were never unmapping it. This was harmless
for foreign mappings but now that we're looking to reuse the
mapcache for transient grant mappings, we must unmap entries
when invalidated.

Signed-off-by: Edgar E. Iglesias 
Reviewed-by: Stefano Stabellini 
---
 hw/xen/xen-mapcache.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
index bc860f4373..ec95445696 100644
--- a/hw/xen/xen-mapcache.c
+++ b/hw/xen/xen-mapcache.c
@@ -491,18 +491,23 @@ static void 
xen_invalidate_map_cache_entry_unlocked(MapCache *mc,
 return;
 }
 entry->lock--;
-if (entry->lock > 0 || pentry == NULL) {
+if (entry->lock > 0) {
 return;
 }
 
-pentry->next = entry->next;
 ram_block_notify_remove(entry->vaddr_base, entry->size, entry->size);
 if (munmap(entry->vaddr_base, entry->size) != 0) {
 perror("unmap fails");
 exit(-1);
 }
+
 g_free(entry->valid_mapping);
-g_free(entry);
+if (pentry) {
+pentry->next = entry->next;
+g_free(entry);
+} else {
+memset(entry, 0, sizeof *entry);
+}
 }
 
 typedef struct XenMapCacheData {
-- 
2.40.1




[PATCH v5 7/8] xen: mapcache: Add support for grant mappings

2024-05-09 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Add a second mapcache for grant mappings. The mapcache for
grants needs to work with XC_PAGE_SIZE granularity since
we can't map larger ranges than what has been granted to us.

Like with foreign mappings (xen_memory), machines using grants
are expected to initialize the xen_grants MR and map it
into their address-map accordingly.

Signed-off-by: Edgar E. Iglesias 
---
 hw/xen/xen-hvm-common.c |  12 ++-
 hw/xen/xen-mapcache.c   | 163 ++--
 include/hw/xen/xen-hvm-common.h |   3 +
 include/sysemu/xen.h|   7 ++
 4 files changed, 152 insertions(+), 33 deletions(-)

diff --git a/hw/xen/xen-hvm-common.c b/hw/xen/xen-hvm-common.c
index c94f1990c5..7a1e2ce4b3 100644
--- a/hw/xen/xen-hvm-common.c
+++ b/hw/xen/xen-hvm-common.c
@@ -10,12 +10,18 @@
 #include "hw/boards.h"
 #include "hw/xen/arch_hvm.h"
 
-MemoryRegion xen_memory;
+MemoryRegion xen_memory, xen_grants;
 
-/* Check for xen memory.  */
+/* Check for any kind of xen memory, foreign mappings or grants.  */
 bool xen_mr_is_memory(MemoryRegion *mr)
 {
-return mr == _memory;
+return mr == _memory || mr == _grants;
+}
+
+/* Check specifically for grants.  */
+bool xen_mr_is_grants(MemoryRegion *mr)
+{
+return mr == _grants;
 }
 
 void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr,
diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
index 26bc38a9e3..25041ab02d 100644
--- a/hw/xen/xen-mapcache.c
+++ b/hw/xen/xen-mapcache.c
@@ -14,6 +14,7 @@
 
 #include 
 
+#include "hw/xen/xen-hvm-common.h"
 #include "hw/xen/xen_native.h"
 #include "qemu/bitmap.h"
 
@@ -21,6 +22,8 @@
 #include "sysemu/xen-mapcache.h"
 #include "trace.h"
 
+#include 
+#include 
 
 #if HOST_LONG_BITS == 32
 #  define MCACHE_MAX_SIZE (1UL<<31) /* 2GB Cap */
@@ -41,6 +44,7 @@ typedef struct MapCacheEntry {
 unsigned long *valid_mapping;
 uint32_t lock;
 #define XEN_MAPCACHE_ENTRY_DUMMY (1 << 0)
+#define XEN_MAPCACHE_ENTRY_GRANT (1 << 1)
 uint8_t flags;
 hwaddr size;
 struct MapCacheEntry *next;
@@ -71,6 +75,8 @@ typedef struct MapCache {
 } MapCache;
 
 static MapCache *mapcache;
+static MapCache *mapcache_grants;
+static xengnttab_handle *xen_region_gnttabdev;
 
 static inline void mapcache_lock(MapCache *mc)
 {
@@ -131,6 +137,12 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f, void 
*opaque)
 unsigned long max_mcache_size;
 unsigned int bucket_shift;
 
+xen_region_gnttabdev = xengnttab_open(NULL, 0);
+if (xen_region_gnttabdev == NULL) {
+error_report("mapcache: Failed to open gnttab device");
+exit(EXIT_FAILURE);
+}
+
 if (HOST_LONG_BITS == 32) {
 bucket_shift = 16;
 } else {
@@ -159,6 +171,15 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f, void 
*opaque)
 mapcache = xen_map_cache_init_single(f, opaque,
  bucket_shift,
  max_mcache_size);
+
+/*
+ * Grant mappings must use XC_PAGE_SIZE granularity since we can't
+ * map anything beyond the number of pages granted to us.
+ */
+mapcache_grants = xen_map_cache_init_single(f, opaque,
+XC_PAGE_SHIFT,
+max_mcache_size);
+
 setrlimit(RLIMIT_AS, _as);
 }
 
@@ -168,17 +189,24 @@ static void xen_remap_bucket(MapCache *mc,
  hwaddr size,
  hwaddr address_index,
  bool dummy,
+ bool grant,
+ bool is_write,
  ram_addr_t ram_offset)
 {
 uint8_t *vaddr_base;
-xen_pfn_t *pfns;
+uint32_t *refs = NULL;
+xen_pfn_t *pfns = NULL;
 int *err;
 unsigned int i;
 hwaddr nb_pfn = size >> XC_PAGE_SHIFT;
 
 trace_xen_remap_bucket(address_index);
 
-pfns = g_new0(xen_pfn_t, nb_pfn);
+if (grant) {
+refs = g_new0(uint32_t, nb_pfn);
+} else {
+pfns = g_new0(xen_pfn_t, nb_pfn);
+}
 err = g_new0(int, nb_pfn);
 
 if (entry->vaddr_base != NULL) {
@@ -207,21 +235,51 @@ static void xen_remap_bucket(MapCache *mc,
 g_free(entry->valid_mapping);
 entry->valid_mapping = NULL;
 
-for (i = 0; i < nb_pfn; i++) {
-pfns[i] = (address_index << (mc->bucket_shift - XC_PAGE_SHIFT)) + i;
+if (grant) {
+hwaddr grant_base = address_index - (ram_offset >> XC_PAGE_SHIFT);
+
+for (i = 0; i < nb_pfn; i++) {
+refs[i] = grant_base + i;
+}
+} else {
+for (i = 0; i < nb_pfn; i++) {
+pfns[i] = (address_index << (mc->bucket_shift - XC_PAGE_SHIFT)) + 
i;
+}
 }
 
-/*
- * If the caller has requested t

[PATCH v5 3/8] xen: Add xen_mr_is_memory()

2024-05-09 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Add xen_mr_is_memory() to abstract away tests for the
xen_memory MR.

No functional changes.

Signed-off-by: Edgar E. Iglesias 
Reviewed-by: Stefano Stabellini 
Acked-by: David Hildenbrand 
---
 hw/xen/xen-hvm-common.c | 10 --
 include/sysemu/xen.h|  8 
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/hw/xen/xen-hvm-common.c b/hw/xen/xen-hvm-common.c
index 1627da7398..c94f1990c5 100644
--- a/hw/xen/xen-hvm-common.c
+++ b/hw/xen/xen-hvm-common.c
@@ -12,6 +12,12 @@
 
 MemoryRegion xen_memory;
 
+/* Check for xen memory.  */
+bool xen_mr_is_memory(MemoryRegion *mr)
+{
+return mr == _memory;
+}
+
 void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr,
Error **errp)
 {
@@ -28,7 +34,7 @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, 
MemoryRegion *mr,
 return;
 }
 
-if (mr == _memory) {
+if (xen_mr_is_memory(mr)) {
 return;
 }
 
@@ -55,7 +61,7 @@ static void xen_set_memory(struct MemoryListener *listener,
 {
 XenIOState *state = container_of(listener, XenIOState, memory_listener);
 
-if (section->mr == _memory) {
+if (xen_mr_is_memory(section->mr)) {
 return;
 } else {
 if (add) {
diff --git a/include/sysemu/xen.h b/include/sysemu/xen.h
index 754ec2e6cb..dc72f83bcb 100644
--- a/include/sysemu/xen.h
+++ b/include/sysemu/xen.h
@@ -34,6 +34,8 @@ void xen_hvm_modified_memory(ram_addr_t start, ram_addr_t 
length);
 void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size,
struct MemoryRegion *mr, Error **errp);
 
+bool xen_mr_is_memory(MemoryRegion *mr);
+
 #else /* !CONFIG_XEN_IS_POSSIBLE */
 
 #define xen_enabled() 0
@@ -47,6 +49,12 @@ static inline void xen_ram_alloc(ram_addr_t ram_addr, 
ram_addr_t size,
 g_assert_not_reached();
 }
 
+static inline bool xen_mr_is_memory(MemoryRegion *mr)
+{
+g_assert_not_reached();
+return false;
+}
+
 #endif /* CONFIG_XEN_IS_POSSIBLE */
 
 #endif
-- 
2.40.1




[PATCH v5 1/8] xen: mapcache: Make MCACHE_BUCKET_SHIFT runtime configurable

2024-05-09 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Make MCACHE_BUCKET_SHIFT runtime configurable per cache instance.

Signed-off-by: Edgar E. Iglesias 
Reviewed-by: Stefano Stabellini 
---
 hw/xen/xen-mapcache.c | 54 ++-
 1 file changed, 33 insertions(+), 21 deletions(-)

diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
index fa6813b1ad..bc860f4373 100644
--- a/hw/xen/xen-mapcache.c
+++ b/hw/xen/xen-mapcache.c
@@ -23,13 +23,10 @@
 
 
 #if HOST_LONG_BITS == 32
-#  define MCACHE_BUCKET_SHIFT 16
 #  define MCACHE_MAX_SIZE (1UL<<31) /* 2GB Cap */
 #else
-#  define MCACHE_BUCKET_SHIFT 20
 #  define MCACHE_MAX_SIZE (1UL<<35) /* 32GB Cap */
 #endif
-#define MCACHE_BUCKET_SIZE (1UL << MCACHE_BUCKET_SHIFT)
 
 /* This is the size of the virtual address space reserve to QEMU that will not
  * be use by MapCache.
@@ -65,7 +62,8 @@ typedef struct MapCache {
 /* For most cases (>99.9%), the page address is the same. */
 MapCacheEntry *last_entry;
 unsigned long max_mcache_size;
-unsigned int mcache_bucket_shift;
+unsigned int bucket_shift;
+unsigned long bucket_size;
 
 phys_offset_to_gaddr_t phys_offset_to_gaddr;
 QemuMutex lock;
@@ -95,11 +93,14 @@ static inline int test_bits(int nr, int size, const 
unsigned long *addr)
 
 static MapCache *xen_map_cache_init_single(phys_offset_to_gaddr_t f,
void *opaque,
+   unsigned int bucket_shift,
unsigned long max_size)
 {
 unsigned long size;
 MapCache *mc;
 
+assert(bucket_shift >= XC_PAGE_SHIFT);
+
 mc = g_new0(MapCache, 1);
 
 mc->phys_offset_to_gaddr = f;
@@ -108,12 +109,14 @@ static MapCache 
*xen_map_cache_init_single(phys_offset_to_gaddr_t f,
 
 QTAILQ_INIT(>locked_entries);
 
+mc->bucket_shift = bucket_shift;
+mc->bucket_size = 1UL << bucket_shift;
 mc->max_mcache_size = max_size;
 
 mc->nr_buckets =
 (((mc->max_mcache_size >> XC_PAGE_SHIFT) +
-  (1UL << (MCACHE_BUCKET_SHIFT - XC_PAGE_SHIFT)) - 1) >>
- (MCACHE_BUCKET_SHIFT - XC_PAGE_SHIFT));
+  (1UL << (bucket_shift - XC_PAGE_SHIFT)) - 1) >>
+ (bucket_shift - XC_PAGE_SHIFT));
 
 size = mc->nr_buckets * sizeof(MapCacheEntry);
 size = (size + XC_PAGE_SIZE - 1) & ~(XC_PAGE_SIZE - 1);
@@ -126,6 +129,13 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f, void 
*opaque)
 {
 struct rlimit rlimit_as;
 unsigned long max_mcache_size;
+unsigned int bucket_shift;
+
+if (HOST_LONG_BITS == 32) {
+bucket_shift = 16;
+} else {
+bucket_shift = 20;
+}
 
 if (geteuid() == 0) {
 rlimit_as.rlim_cur = RLIM_INFINITY;
@@ -146,7 +156,9 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f, void 
*opaque)
 }
 }
 
-mapcache = xen_map_cache_init_single(f, opaque, max_mcache_size);
+mapcache = xen_map_cache_init_single(f, opaque,
+ bucket_shift,
+ max_mcache_size);
 setrlimit(RLIMIT_AS, _as);
 }
 
@@ -195,7 +207,7 @@ static void xen_remap_bucket(MapCache *mc,
 entry->valid_mapping = NULL;
 
 for (i = 0; i < nb_pfn; i++) {
-pfns[i] = (address_index << (MCACHE_BUCKET_SHIFT-XC_PAGE_SHIFT)) + i;
+pfns[i] = (address_index << (mc->bucket_shift - XC_PAGE_SHIFT)) + i;
 }
 
 /*
@@ -266,8 +278,8 @@ static uint8_t *xen_map_cache_unlocked(MapCache *mc,
 bool dummy = false;
 
 tryagain:
-address_index  = phys_addr >> MCACHE_BUCKET_SHIFT;
-address_offset = phys_addr & (MCACHE_BUCKET_SIZE - 1);
+address_index  = phys_addr >> mc->bucket_shift;
+address_offset = phys_addr & (mc->bucket_size - 1);
 
 trace_xen_map_cache(phys_addr);
 
@@ -294,14 +306,14 @@ tryagain:
 return mc->last_entry->vaddr_base + address_offset;
 }
 
-/* size is always a multiple of MCACHE_BUCKET_SIZE */
+/* size is always a multiple of mc->bucket_size */
 if (size) {
 cache_size = size + address_offset;
-if (cache_size % MCACHE_BUCKET_SIZE) {
-cache_size += MCACHE_BUCKET_SIZE - (cache_size % 
MCACHE_BUCKET_SIZE);
+if (cache_size % mc->bucket_size) {
+cache_size += mc->bucket_size - (cache_size % mc->bucket_size);
 }
 } else {
-cache_size = MCACHE_BUCKET_SIZE;
+cache_size = mc->bucket_size;
 }
 
 entry = >entry[address_index % mc->nr_buckets];
@@ -422,7 +434,7 @@ static ram_addr_t 
xen_ram_addr_from_mapcache_single(MapCache *mc, void *ptr)
 trace_xen_ram_addr_from_mapcache_not_in_cache(ptr);
 raddr = RAM_ADDR_INVALID;
 } else {
-raddr = (reventry->paddr_index << MCACHE_BUCKET_SHIFT) +
+   

Re: [PATCH v4 15/17] xen: mapcache: Remove assumption of RAMBlock with 0 offset

2024-05-07 Thread Edgar E. Iglesias
On Thu, May 2, 2024 at 10:02 PM Stefano Stabellini
 wrote:
>
> On Thu, 2 May 2024, Edgar E. Iglesias wrote:
> > On Thu, May 2, 2024 at 8:53 PM Stefano Stabellini
> >  wrote:
> > >
> > > +Xenia
> > >
> > > On Thu, 2 May 2024, Edgar E. Iglesias wrote:
> > > > On Wed, May 1, 2024 at 11:24 PM Stefano Stabellini
> > > >  wrote:
> > > > >
> > > > > On Tue, 30 Apr 2024, Edgar E. Iglesias wrote:
> > > > > > From: "Edgar E. Iglesias" 
> > > > > >
> > > > > > The current mapcache assumes that all memory is mapped
> > > > > > in a single RAM MR (the first one with offset 0). Remove
> > > > > > this assumption and propagate the offset to the mapcache
> > > > > > so it can do reverse mappings (from hostptr -> ram_addr).
> > > > > >
> > > > > > This is in preparation for adding grant mappings.
> > > > > >
> > > > > > Signed-off-by: Edgar E. Iglesias 
> > > > >
> > > > >
> > > > > Looking at xen_remap_bucket, it is only using address_index (without
> > > > > adding ram_offset) to map foreign memory. From xen_remap_bucket, I 
> > > > > would
> > > > > understand that address_index already includes the ram_offset.
> > > > >
> > > > > Meaning that if we want to map foreign mapping at address 0x5000, then
> > > > > address_index would be 0x5000, even if ram_offset is 0x1000.
> > > > >
> > > > > But then looking xen_ram_addr_from_mapcache_single ram_offset is added
> > > > > to paddr_index to calculate the physical address. So in that case we
> > > > > would want address_index to be 0x4000 and ram_offset to be 0x1000. But
> > > > > xen_remap_bucket would have to sum address_index and ram_offset to map
> > > > > foreign memory.
> > > > >
> > > > > So I am a bit confused, did I get it wrong? One more comment below.
> > > > >
> > > >
> > > > Thanks Stefano,
> > > >
> > > > I think the confusion is that this ram_addr_offset is not related to
> > > > guest address-space.
> > > > It's a QEMU internal thing and it shouldn't be included in the address
> > > > used to map foreign memory.
> > > > The mapcache can treat this ram_addr offset like a cookie that we keep
> > > > around to be able to do
> > > > reverse mappings from host pointers into ram_addr space
> > > > (xen_ram_addr_from_mapcache).
> > > >
> > > > The current mapcache implementation works because we've really only
> > > > been using foreign mappings
> > > > on RAMBlocks with offset 0. We're also creating RAM's such that the
> > > > offset into the RAM is also
> > > > the guest physical address, for x86 this is natural since RAM starts
> > > > at zero (for lowmem) but for
> > > > ARM we're creating larger than needed RAM's (GUEST_RAM0_BASE + 
> > > > ram-size) to
> > > > make this assumption true. Anyway, In this series I'm not addressing
> > > > this second assumption.
> > >
> > > Let's see if I understand correctly.
> > >
> > > The ram_addr space is an internal QEMU address space which is different
> > > from the guest physical address space and thus cannot and should not be
> > > used to do foreign mappings (foreign mapping hypercalls take a guest
> > > physical or a real physical address to map). Is that correct?
> > >
> > > If so, then I understand.
> > >
> >
> > Yes, that matches my understanding.
> >
> > >
> > >
> > > > There's a second call in physmem.c to xen_map_cache using the
> > > > block->offset as an address.
> > > > I was considering removing that second call since I can't see how it 
> > > > can work
> > > > (except perhaps in some specific use-case by luck?). Anyway, for now
> > > > I've left it unmodified.
> > >
> > > Yes, that code was written with the assumption that block->offset is an
> > > offset in the guest physical address space and could be used as a guest
> > > physical address. Actually, you might have spotted a real bug.
> > >
> > > The intent was for smaller regions (not the bit RAM region, things like
> > > a ROM region for instance) we could map 

Re: [PATCH v3 6/9] xen/arm64: bpi: Add missing code symbol annotations

2024-05-07 Thread Edgar E. Iglesias
On Tue, May 7, 2024 at 11:57 AM Julien Grall  wrote:
>
> Hi,
>
> On 06/05/2024 13:54, Edgar E. Iglesias wrote:
> > On Sat, May 4, 2024 at 2:14 AM Stefano Stabellini
> >  wrote:
> >>
> >> On Wed, 1 May 2024, Edgar E. Iglesias wrote:
> >>> From: "Edgar E. Iglesias" 
> >>>
> >>> Use the generic xen/linkage.h macros to annotate code symbols
> >>> and add missing annotations.
> >>>
> >>> Signed-off-by: Edgar E. Iglesias 
> >>> ---
> >>>   xen/arch/arm/arm64/bpi.S | 20 
> >>>   1 file changed, 12 insertions(+), 8 deletions(-)
> >>>
> >>> diff --git a/xen/arch/arm/arm64/bpi.S b/xen/arch/arm/arm64/bpi.S
> >>> index 4e63825220..b16e4d1e29 100644
> >>> --- a/xen/arch/arm/arm64/bpi.S
> >>> +++ b/xen/arch/arm/arm64/bpi.S
> >>> @@ -52,14 +52,15 @@
> >>>* micro-architectures in a system.
> >>>*/
> >>>   .align   11
> >>> -ENTRY(__bp_harden_hyp_vecs_start)
> >>> +FUNC(__bp_harden_hyp_vecs_start)
> >>>   .rept 4
> >>>   vectors hyp_traps_vector
> >>>   .endr
> >>> -ENTRY(__bp_harden_hyp_vecs_end)
> >>> +GLOBAL(__bp_harden_hyp_vecs_end)
> >>> +END(__bp_harden_hyp_vecs_start)
> >>
> >> Shouldn't GLOBAL be changed to FUNC as well?
> >>
> >
> > I was a bit unsure but went for GLOBAL since the _end labels point to
> > addresses after and outside of the code sequence.
> > But I don't have a strong opinion and am happy to change them to FUNC
> > if you feel that's better.
>
> I don't think it should be FUNC as this is not meant to be called
> directly. I am also under the impression, we were planning to get rid of
> GLOBAL() as well.
>
> Furthermore, __bp_harden_hyp_vec_start is not a function per say. It is
> a pointer to the vector table.
>
>  From the brief look, the same remarks would apply to the rest of bpi.S.
> So I think we want to switch all the ENTRY() to LABEL().

Hi Julien,

The reason I choose FUNC for the start of the symbol is because these
symbols contain
executable code (not only a table of pointers to code somewhere else)
and the ELF spec
says that STT_FUNC means the symbol contains functions or other executable
code (not only callable functions IIUC):

"STT_FUNC The symbol is associated with a function or other executable code."
https://refspecs.linuxbase.org/elf/elf.pdf
(Symbol Table 1-20).

I think using LABEL instead of GLOBAL for the _end labels of these
code sequences makes sense.
I'm happy to change the _start labels to LABEL too if you guys feel
that's better.

Cheers,
Edgar



Re: [PATCH v4 14/17] xen: Add xen_mr_is_memory()

2024-05-06 Thread Edgar E. Iglesias
On Mon, May 6, 2024 at 11:59 AM Philippe Mathieu-Daudé
 wrote:
>
> On 2/5/24 09:26, David Hildenbrand wrote:
> > On 30.04.24 18:49, Edgar E. Iglesias wrote:
> >> From: "Edgar E. Iglesias" 
> >>
> >> Add xen_mr_is_memory() to abstract away tests for the
> >> xen_memory MR.
> >>
> >> Signed-off-by: Edgar E. Iglesias 
> >> ---
> >
> > [...]
> >
> >>   #endif
> >> diff --git a/system/physmem.c b/system/physmem.c
> >> index ad7a8c7d95..1a5ffcba2a 100644
> >> --- a/system/physmem.c
> >> +++ b/system/physmem.c
> >> @@ -2227,7 +2227,7 @@ static void *qemu_ram_ptr_length(RAMBlock
> >> *block, ram_addr_t addr,
> >>* because we don't want to map the entire memory in QEMU.
> >>* In that case just map the requested area.
> >>*/
> >> -if (block->offset == 0) {
> >> +if (xen_mr_is_memory(block->mr)) {
> >>   return xen_map_cache(block->mr, addr, len, lock, lock,
> >>is_write);
> >>   }
> >
> > I'd have moved that into a separate patch, because this is not a simple
> > abstraction here.
>
> Yes please, maybe using Stefano review comment in the description.
>

Thanks, for v5 I've split out this particular change into a separate patch:

softmmu: Replace check for RAMBlock offset 0 with xen_mr_is_memory

    For xen, when checking for the first RAM (xen_memory), use
xen_mr_is_memory() rather than checking for a RAMBlock with
offset 0.

All Xen machines create xen_memory first so this has no
functional change for existing machines.

Signed-off-by: Edgar E. Iglesias 

diff --git a/system/physmem.c b/system/physmem.c
index ad7a8c7d95..1a5ffcba2a 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -2227,7 +2227,7 @@ static void *qemu_ram_ptr_length(RAMBlock
*block, ram_addr_t addr,
  * because we don't want to map the entire memory in QEMU.
  * In that case just map the requested area.
  */
-if (block->offset == 0) {
+if (xen_mr_is_memory(block->mr)) {
 return xen_map_cache(block->mr, addr, len, lock, lock,
  is_write);
 }



> >
> > Acked-by: David Hildenbrand 
> >
>



Re: [PATCH v3 6/9] xen/arm64: bpi: Add missing code symbol annotations

2024-05-06 Thread Edgar E. Iglesias
On Sat, May 4, 2024 at 2:14 AM Stefano Stabellini
 wrote:
>
> On Wed, 1 May 2024, Edgar E. Iglesias wrote:
> > From: "Edgar E. Iglesias" 
> >
> > Use the generic xen/linkage.h macros to annotate code symbols
> > and add missing annotations.
> >
> > Signed-off-by: Edgar E. Iglesias 
> > ---
> >  xen/arch/arm/arm64/bpi.S | 20 
> >  1 file changed, 12 insertions(+), 8 deletions(-)
> >
> > diff --git a/xen/arch/arm/arm64/bpi.S b/xen/arch/arm/arm64/bpi.S
> > index 4e63825220..b16e4d1e29 100644
> > --- a/xen/arch/arm/arm64/bpi.S
> > +++ b/xen/arch/arm/arm64/bpi.S
> > @@ -52,14 +52,15 @@
> >   * micro-architectures in a system.
> >   */
> >  .align   11
> > -ENTRY(__bp_harden_hyp_vecs_start)
> > +FUNC(__bp_harden_hyp_vecs_start)
> >  .rept 4
> >  vectors hyp_traps_vector
> >  .endr
> > -ENTRY(__bp_harden_hyp_vecs_end)
> > +GLOBAL(__bp_harden_hyp_vecs_end)
> > +END(__bp_harden_hyp_vecs_start)
>
> Shouldn't GLOBAL be changed to FUNC as well?
>

I was a bit unsure but went for GLOBAL since the _end labels point to
addresses after and outside of the code sequence.
But I don't have a strong opinion and am happy to change them to FUNC
if you feel that's better.

Cheers,
Edgar


>
> >  .macro mitigate_spectre_bhb_loop count
> > -ENTRY(__mitigate_spectre_bhb_loop_start_\count)
> > +FUNC(__mitigate_spectre_bhb_loop_start_\count)
> >  stp x0, x1, [sp, #-16]!
> >  mov x0, \count
> >  .Lspectre_bhb_loop\@:
> > @@ -68,11 +69,12 @@ ENTRY(__mitigate_spectre_bhb_loop_start_\count)
> >  b.ne.Lspectre_bhb_loop\@
> >  sb
> >  ldp x0, x1, [sp], #16
> > -ENTRY(__mitigate_spectre_bhb_loop_end_\count)
> > +GLOBAL(__mitigate_spectre_bhb_loop_end_\count)
>
> Also here?
>
>
> > +END(__mitigate_spectre_bhb_loop_start_\count)
> >  .endm
> >
> >  .macro smccc_workaround num smcc_id
> > -ENTRY(__smccc_workaround_smc_start_\num)
> > +FUNC(__smccc_workaround_smc_start_\num)
> >  sub sp, sp, #(8 * 4)
> >  stp x0, x1, [sp, #(8 * 2)]
> >  stp x2, x3, [sp, #(8 * 0)]
> > @@ -81,13 +83,15 @@ ENTRY(__smccc_workaround_smc_start_\num)
> >  ldp x2, x3, [sp, #(8 * 0)]
> >  ldp x0, x1, [sp, #(8 * 2)]
> >  add sp, sp, #(8 * 4)
> > -ENTRY(__smccc_workaround_smc_end_\num)
> > +GLOBAL(__smccc_workaround_smc_end_\num)
>
> And here?
>
>
> > +END(__smccc_workaround_smc_start_\num)
> >  .endm
> >
> > -ENTRY(__mitigate_spectre_bhb_clear_insn_start)
> > +FUNC(__mitigate_spectre_bhb_clear_insn_start)
> >  clearbhb
> >  isb
> > -ENTRY(__mitigate_spectre_bhb_clear_insn_end)
> > +GLOBAL(__mitigate_spectre_bhb_clear_insn_end)
>
> and here?
>
>
> > +END(__mitigate_spectre_bhb_clear_insn_start)
> >
> >  mitigate_spectre_bhb_loop 8
> >  mitigate_spectre_bhb_loop 24
> > --
> > 2.40.1
> >



Re: [PATCH v3 4/9] xen/arm64: head: Add missing code symbol annotations

2024-05-06 Thread Edgar E. Iglesias
On Sat, May 4, 2024 at 1:56 AM Stefano Stabellini
 wrote:
>
> On Wed, 1 May 2024, Edgar E. Iglesias wrote:
> > From: "Edgar E. Iglesias" 
> >
> > Use the generic xen/linkage.h macros to annotate code symbols
> > and add missing annotations.
> >
> > Signed-off-by: Edgar E. Iglesias 
> > ---
> >  xen/arch/arm/arm64/head.S | 50 ---
> >  1 file changed, 26 insertions(+), 24 deletions(-)
> >
> > diff --git a/xen/arch/arm/arm64/head.S b/xen/arch/arm/arm64/head.S
> > index fb297e9eb5..7acedb4f8f 100644
> > --- a/xen/arch/arm/arm64/head.S
> > +++ b/xen/arch/arm/arm64/head.S
> > @@ -90,7 +90,7 @@
> >   * 4K-aligned address.
> >   */
> >
> > -GLOBAL(start)
> > +FUNC(start)
> >  /*
> >   * DO NOT MODIFY. Image header expected by Linux boot-loaders.
> >   */
> > @@ -102,6 +102,7 @@ efi_head:
> >   */
> >  add x13, x18, #0x16
> >  b   real_start   /* branch to kernel start */
> > +END(start)
> >  .quad   0/* Image load offset from start of 
> > RAM */
> >  .quad   _end - start /* Effective size of kernel image, 
> > little-endian */
> >  .quad   __HEAD_FLAGS /* Informative flags, little-endian */
> > @@ -223,7 +224,7 @@ section_table:
> >  .align  5
> >  #endif /* CONFIG_ARM_EFI */
> >
> > -real_start:
> > +FUNC_LOCAL(real_start)
> >  /* BSS should be zeroed when booting without EFI */
> >  mov   x26, #0/* x26 := skip_zero_bss */
> >
> > @@ -263,9 +264,9 @@ primary_switched:
> >  mov   x1, x21/* x1 := paddr(FDT) */
> >  ldr   x2, =start_xen
> >  b launch
> > -ENDPROC(real_start)
> > +END(real_start)
> >
> > -GLOBAL(init_secondary)
> > +FUNC(init_secondary)
> >  msr   DAIFSet, 0xf   /* Disable all interrupts */
> >
> >  /* Find out where we are */
> > @@ -304,7 +305,7 @@ secondary_switched:
> >  /* Jump to C world */
> >  ldr   x2, =start_secondary
> >  b launch
> > -ENDPROC(init_secondary)
> > +END(init_secondary)
> >
> >  /*
> >   * Check if the CPU has been booted in Hypervisor mode.
> > @@ -313,7 +314,7 @@ ENDPROC(init_secondary)
> >   *
> >   * Clobbers x0 - x5
> >   */
> > -check_cpu_mode:
> > +FUNC_LOCAL(check_cpu_mode)
> >  PRINT_ID("- Current EL ")
> >  mrs   x5, CurrentEL
> >  print_reg x5
> > @@ -329,7 +330,7 @@ check_cpu_mode:
> >  PRINT_ID("- Xen must be entered in NS EL2 mode -\r\n")
> >  PRINT_ID("- Please update the bootloader -\r\n")
> >  b fail
> > -ENDPROC(check_cpu_mode)
> > +END(check_cpu_mode)
> >
> >  /*
> >   * Zero BSS
> > @@ -339,7 +340,7 @@ ENDPROC(check_cpu_mode)
> >   *
> >   * Clobbers x0 - x3
> >   */
> > -zero_bss:
> > +FUNC_LOCAL(zero_bss)
> >  /* Zero BSS only when requested */
> >  cbnz  x26, skip_bss
> >
> > @@ -353,14 +354,14 @@ zero_bss:
> >
> >  skip_bss:
> >  ret
> > -ENDPROC(zero_bss)
> > +END(zero_bss)
> >
> >  /*
> >   * Initialize the processor for turning the MMU on.
> >   *
> >   * Clobbers x0 - x3
> >   */
> > -cpu_init:
> > +FUNC_LOCAL(cpu_init)
> >  PRINT_ID("- Initialize CPU -\r\n")
> >
> >  /* Set up memory attribute type tables */
> > @@ -399,7 +400,7 @@ cpu_init:
> >   */
> >  msr spsel, #1
> >  ret
> > -ENDPROC(cpu_init)
> > +END(cpu_init)
> >
> >  /*
> >   * Setup the initial stack and jump to the C world
> > @@ -411,7 +412,7 @@ ENDPROC(cpu_init)
> >   *
> >   * Clobbers x3
> >   */
> > -launch:
> > +FUNC_LOCAL(launch)
> >  ldr   x3, =init_data
> >  add   x3, x3, #INITINFO_stack /* Find the boot-time stack */
> >  ldr   x3, [x3]
> > @@ -421,13 +422,13 @@ launch:
> >
> >  /* Jump to C world */
> >  brx2
> > -ENDPROC(launch)
> > +END(launch)
> >
> >  /* Fail-stop */
> > -fail:   PRINT_ID("- Boot failed -\r\n")
> > +FUNC_LOCAL(fail)   PRINT_ID("- Boot failed -\r\n")
>
> Maybe we should move PRINT_ID to a newline?
> I am not sure FUN

Re: [PATCH v4 16/17] xen: mapcache: Add support for grant mappings

2024-05-02 Thread Edgar E. Iglesias
On Thu, May 2, 2024 at 9:18 PM Stefano Stabellini
 wrote:
>
> On Tue, 30 Apr 2024, Edgar E. Iglesias wrote:
> > From: "Edgar E. Iglesias" 
> >
> > Add a second mapcache for grant mappings. The mapcache for
> > grants needs to work with XC_PAGE_SIZE granularity since
> > we can't map larger ranges than what has been granted to us.
> >
> > Like with foreign mappings (xen_memory), machines using grants
> > are expected to initialize the xen_grants MR and map it
> > into their address-map accordingly.
> >
> > Signed-off-by: Edgar E. Iglesias 
> > ---
> >  hw/xen/xen-hvm-common.c |  12 ++-
> >  hw/xen/xen-mapcache.c   | 158 +---
> >  include/hw/xen/xen-hvm-common.h |   3 +
> >  include/sysemu/xen.h|   7 ++
> >  4 files changed, 145 insertions(+), 35 deletions(-)
> >
> > diff --git a/hw/xen/xen-hvm-common.c b/hw/xen/xen-hvm-common.c
> > index 0267b88d26..fdec400491 100644
> > --- a/hw/xen/xen-hvm-common.c
> > +++ b/hw/xen/xen-hvm-common.c
> > @@ -10,12 +10,18 @@
> >  #include "hw/boards.h"
> >  #include "hw/xen/arch_hvm.h"
> >
> > -MemoryRegion xen_memory;
> > +MemoryRegion xen_memory, xen_grants;
> >
> > -/* Check for xen memory.  */
> > +/* Check for any kind of xen memory, foreign mappings or grants.  */
> >  bool xen_mr_is_memory(MemoryRegion *mr)
> >  {
> > -return mr == _memory;
> > +return mr == _memory || mr == _grants;
> > +}
> > +
> > +/* Check specifically for grants.  */
> > +bool xen_mr_is_grants(MemoryRegion *mr)
> > +{
> > +return mr == _grants;
> >  }
> >
> >  void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr,
> > diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
> > index 1b32d0c003..96cd68e28d 100644
> > --- a/hw/xen/xen-mapcache.c
> > +++ b/hw/xen/xen-mapcache.c
> > @@ -14,6 +14,7 @@
> >
> >  #include 
> >
> > +#include "hw/xen/xen-hvm-common.h"
> >  #include "hw/xen/xen_native.h"
> >  #include "qemu/bitmap.h"
> >
> > @@ -21,6 +22,8 @@
> >  #include "sysemu/xen-mapcache.h"
> >  #include "trace.h"
> >
> > +#include 
> > +#include 
> >
> >  #if HOST_LONG_BITS == 32
> >  #  define MCACHE_MAX_SIZE (1UL<<31) /* 2GB Cap */
> > @@ -41,6 +44,7 @@ typedef struct MapCacheEntry {
> >  unsigned long *valid_mapping;
> >  uint32_t lock;
> >  #define XEN_MAPCACHE_ENTRY_DUMMY (1 << 0)
> > +#define XEN_MAPCACHE_ENTRY_GRANT (1 << 1)
> >  uint8_t flags;
> >  hwaddr size;
> >
> > @@ -74,6 +78,8 @@ typedef struct MapCache {
> >  } MapCache;
> >
> >  static MapCache *mapcache;
> > +static MapCache *mapcache_grants;
> > +static xengnttab_handle *xen_region_gnttabdev;
> >
> >  static inline void mapcache_lock(MapCache *mc)
> >  {
> > @@ -132,6 +138,12 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f, void 
> > *opaque)
> >  unsigned long max_mcache_size;
> >  unsigned int bucket_shift;
> >
> > +xen_region_gnttabdev = xengnttab_open(NULL, 0);
> > +if (xen_region_gnttabdev == NULL) {
> > +error_report("mapcache: Failed to open gnttab device");
> > +exit(EXIT_FAILURE);
> > +}
> > +
> >  if (HOST_LONG_BITS == 32) {
> >  bucket_shift = 16;
> >  } else {
> > @@ -160,6 +172,15 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f, void 
> > *opaque)
> >  mapcache = xen_map_cache_init_single(f, opaque,
> >   bucket_shift,
> >   max_mcache_size);
> > +
> > +/*
> > + * Grant mappings must use XC_PAGE_SIZE granularity since we can't
> > + * map anything beyond the number of pages granted to us.
> > + */
> > +mapcache_grants = xen_map_cache_init_single(f, opaque,
> > +XC_PAGE_SHIFT,
> > +max_mcache_size);
> > +
> >  setrlimit(RLIMIT_AS, _as);
> >  }
> >
> > @@ -169,17 +190,25 @@ static void xen_remap_bucket(MapCache *mc,
> >   hwaddr size,
> >   hwaddr address_index,
> >   bool dummy,
> > + bool grant,
> > +   

Re: [PATCH v4 15/17] xen: mapcache: Remove assumption of RAMBlock with 0 offset

2024-05-02 Thread Edgar E. Iglesias
On Thu, May 2, 2024 at 8:53 PM Stefano Stabellini
 wrote:
>
> +Xenia
>
> On Thu, 2 May 2024, Edgar E. Iglesias wrote:
> > On Wed, May 1, 2024 at 11:24 PM Stefano Stabellini
> >  wrote:
> > >
> > > On Tue, 30 Apr 2024, Edgar E. Iglesias wrote:
> > > > From: "Edgar E. Iglesias" 
> > > >
> > > > The current mapcache assumes that all memory is mapped
> > > > in a single RAM MR (the first one with offset 0). Remove
> > > > this assumption and propagate the offset to the mapcache
> > > > so it can do reverse mappings (from hostptr -> ram_addr).
> > > >
> > > > This is in preparation for adding grant mappings.
> > > >
> > > > Signed-off-by: Edgar E. Iglesias 
> > >
> > >
> > > Looking at xen_remap_bucket, it is only using address_index (without
> > > adding ram_offset) to map foreign memory. From xen_remap_bucket, I would
> > > understand that address_index already includes the ram_offset.
> > >
> > > Meaning that if we want to map foreign mapping at address 0x5000, then
> > > address_index would be 0x5000, even if ram_offset is 0x1000.
> > >
> > > But then looking xen_ram_addr_from_mapcache_single ram_offset is added
> > > to paddr_index to calculate the physical address. So in that case we
> > > would want address_index to be 0x4000 and ram_offset to be 0x1000. But
> > > xen_remap_bucket would have to sum address_index and ram_offset to map
> > > foreign memory.
> > >
> > > So I am a bit confused, did I get it wrong? One more comment below.
> > >
> >
> > Thanks Stefano,
> >
> > I think the confusion is that this ram_addr_offset is not related to
> > guest address-space.
> > It's a QEMU internal thing and it shouldn't be included in the address
> > used to map foreign memory.
> > The mapcache can treat this ram_addr offset like a cookie that we keep
> > around to be able to do
> > reverse mappings from host pointers into ram_addr space
> > (xen_ram_addr_from_mapcache).
> >
> > The current mapcache implementation works because we've really only
> > been using foreign mappings
> > on RAMBlocks with offset 0. We're also creating RAM's such that the
> > offset into the RAM is also
> > the guest physical address, for x86 this is natural since RAM starts
> > at zero (for lowmem) but for
> > ARM we're creating larger than needed RAM's (GUEST_RAM0_BASE + ram-size) to
> > make this assumption true. Anyway, In this series I'm not addressing
> > this second assumption.
>
> Let's see if I understand correctly.
>
> The ram_addr space is an internal QEMU address space which is different
> from the guest physical address space and thus cannot and should not be
> used to do foreign mappings (foreign mapping hypercalls take a guest
> physical or a real physical address to map). Is that correct?
>
> If so, then I understand.
>

Yes, that matches my understanding.

>
>
> > There's a second call in physmem.c to xen_map_cache using the
> > block->offset as an address.
> > I was considering removing that second call since I can't see how it can 
> > work
> > (except perhaps in some specific use-case by luck?). Anyway, for now
> > I've left it unmodified.
>
> Yes, that code was written with the assumption that block->offset is an
> offset in the guest physical address space and could be used as a guest
> physical address. Actually, you might have spotted a real bug.
>
> The intent was for smaller regions (not the bit RAM region, things like
> a ROM region for instance) we could map them in full. So here we were
> trying to map the whole thing from start to finish using block->offset
> as start.
>
>
> > > > ---
> > > >  hw/xen/xen-mapcache.c | 25 ++---
> > > >  include/sysemu/xen-mapcache.h |  2 ++
> > > >  system/physmem.c  |  8 
> > > >  3 files changed, 24 insertions(+), 11 deletions(-)
> > > >
> > > > diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
> > > > index 09b5f36d9c..1b32d0c003 100644
> > > > --- a/hw/xen/xen-mapcache.c
> > > > +++ b/hw/xen/xen-mapcache.c
> > > > @@ -43,6 +43,9 @@ typedef struct MapCacheEntry {
> > > >  #define XEN_MAPCACHE_ENTRY_DUMMY (1 << 0)
> > > >  uint8_t flags;
> > > >  hwaddr size;
> > > > +
> > > > +/* Keep ram_addr offset for reverse mappings (hostptr -

[PATCH v3 5/9] xen/arm64: debug: Add missing code symbol annotations

2024-05-02 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Use the generic xen/linkage.h macros to annotate code symbols
and add missing annotations.

Signed-off-by: Edgar E. Iglesias 
---
 xen/arch/arm/arm64/debug.S | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/xen/arch/arm/arm64/debug.S b/xen/arch/arm/arm64/debug.S
index 71cad9d762..c3d02c33d7 100644
--- a/xen/arch/arm/arm64/debug.S
+++ b/xen/arch/arm/arm64/debug.S
@@ -27,17 +27,19 @@
  * Print a character on the UART - this function is called by C
  * x0: character to print
  */
-GLOBAL(early_putch)
+FUNC(early_putch)
 ldr   x15, =EARLY_UART_VIRTUAL_ADDRESS
 early_uart_ready x15, 1
 early_uart_transmit x15, w0
 ret
+END(early_putch)
 
 /* Flush the UART - this function is called by C */
-GLOBAL(early_flush)
+FUNC(early_flush)
 ldr   x15, =EARLY_UART_VIRTUAL_ADDRESS  /* x15 := VA UART base address 
*/
 early_uart_ready x15, 1
 ret
+END(early_flush)
 
 /*
  * Local variables:
-- 
2.40.1




[PATCH v3 8/9] xen/arm64: cache: Use the generic xen/linkage.h macros

2024-05-02 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Use the generic xen/linkage.h macros to annotate code symbols.

Signed-off-by: Edgar E. Iglesias 
---
 xen/arch/arm/arm64/cache.S | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/xen/arch/arm/arm64/cache.S b/xen/arch/arm/arm64/cache.S
index 9a88a2b497..66ed85f735 100644
--- a/xen/arch/arm/arm64/cache.S
+++ b/xen/arch/arm/arm64/cache.S
@@ -40,7 +40,7 @@
  * - kaddr   - kernel address
  * - size- size in question
  */
-ENTRY(__flush_dcache_area)
+FUNC(__flush_dcache_area)
dcache_line_size x2, x3
add x1, x0, x1
sub x3, x2, #1
@@ -51,4 +51,4 @@ ENTRY(__flush_dcache_area)
b.lo1b
dsb sy
ret
-ENDPROC(__flush_dcache_area)
+END(__flush_dcache_area)
-- 
2.40.1




[PATCH v3 1/9] xen/arm64: entry: Add missing code symbol annotations

2024-05-02 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Use the generic xen/linkage.h macros to annotate code symbols
and add missing annotations.

Signed-off-by: Edgar E. Iglesias 
Reviewed-by: Stefano Stabellini 
---
 xen/arch/arm/arm64/entry.S | 72 +-
 1 file changed, 48 insertions(+), 24 deletions(-)

diff --git a/xen/arch/arm/arm64/entry.S b/xen/arch/arm/arm64/entry.S
index f963c923bb..af9a592cae 100644
--- a/xen/arch/arm/arm64/entry.S
+++ b/xen/arch/arm/arm64/entry.S
@@ -289,21 +289,25 @@
 b   do_bad_mode
 .endm
 
-hyp_sync_invalid:
+FUNC_LOCAL(hyp_sync_invalid)
 entry   hyp=1
 invalid BAD_SYNC
+END(hyp_sync_invalid)
 
-hyp_irq_invalid:
+FUNC_LOCAL(hyp_irq_invalid)
 entry   hyp=1
 invalid BAD_IRQ
+END(hyp_irq_invalid)
 
-hyp_fiq_invalid:
+FUNC_LOCAL(hyp_fiq_invalid)
 entry   hyp=1
 invalid BAD_FIQ
+END(hyp_fiq_invalid)
 
-hyp_error_invalid:
+FUNC_LOCAL(hyp_error_invalid)
 entry   hyp=1
 invalid BAD_ERROR
+END(hyp_error_invalid)
 
 /*
  * SError received while running in the hypervisor mode.
@@ -313,11 +317,12 @@ hyp_error_invalid:
  * simplicity, as SError should be rare and potentially fatal,
  * all interrupts are kept masked.
  */
-hyp_error:
+FUNC_LOCAL(hyp_error)
 entry   hyp=1
 mov x0, sp
 bl  do_trap_hyp_serror
 exithyp=1
+END(hyp_error)
 
 /*
  * Synchronous exception received while running in the hypervisor mode.
@@ -327,7 +332,7 @@ hyp_error:
  * some of them. So we want to inherit the state from the interrupted
  * context.
  */
-hyp_sync:
+FUNC_LOCAL(hyp_sync)
 entry   hyp=1
 
 /* Inherit interrupts */
@@ -338,6 +343,7 @@ hyp_sync:
 mov x0, sp
 bl  do_trap_hyp_sync
 exithyp=1
+END(hyp_sync)
 
 /*
  * IRQ received while running in the hypervisor mode.
@@ -352,7 +358,7 @@ hyp_sync:
  * would require some rework in some paths (e.g. panic, livepatch) to
  * ensure the ordering is enforced everywhere.
  */
-hyp_irq:
+FUNC_LOCAL(hyp_irq)
 entry   hyp=1
 
 /* Inherit D, A, F interrupts and keep I masked */
@@ -365,8 +371,9 @@ hyp_irq:
 mov x0, sp
 bl  do_trap_irq
 exithyp=1
+END(hyp_irq)
 
-guest_sync:
+FUNC_LOCAL(guest_sync)
 /*
  * Save x0, x1 in advance
  */
@@ -413,8 +420,9 @@ fastpath_out_workaround:
 mov x1, xzr
 eret
 sb
+END(guest_sync)
 
-wa2_ssbd:
+FUNC_LOCAL(wa2_ssbd)
 #ifdef CONFIG_ARM_SSBD
 alternative_cb arm_enable_wa2_handling
 b   wa2_end
@@ -450,42 +458,55 @@ wa2_end:
 mov x0, xzr
 eret
 sb
-guest_sync_slowpath:
+END(wa2_ssbd)
+
+FUNC_LOCAL(guest_sync_slowpath)
 /*
  * x0/x1 may have been scratch by the fast path above, so avoid
  * to save them.
  */
 guest_vector compat=0, iflags=IFLAGS__AI_, trap=guest_sync, 
save_x0_x1=0
+END(guest_sync_slowpath)
 
-guest_irq:
+FUNC_LOCAL(guest_irq)
 guest_vector compat=0, iflags=IFLAGS__A__, trap=irq
+END(guest_irq)
 
-guest_fiq_invalid:
+FUNC_LOCAL(guest_fiq_invalid)
 entry   hyp=0, compat=0
 invalid BAD_FIQ
+END(guest_fiq_invalid)
 
-guest_error:
+FUNC_LOCAL(guest_error)
 guest_vector compat=0, iflags=IFLAGS__AI_, trap=guest_serror
+END(guest_error)
 
-guest_sync_compat:
+FUNC_LOCAL(guest_sync_compat)
 guest_vector compat=1, iflags=IFLAGS__AI_, trap=guest_sync
+END(guest_sync_compat)
 
-guest_irq_compat:
+FUNC_LOCAL(guest_irq_compat)
 guest_vector compat=1, iflags=IFLAGS__A__, trap=irq
+END(guest_irq_compat)
 
-guest_fiq_invalid_compat:
+FUNC_LOCAL(guest_fiq_invalid_compat)
 entry   hyp=0, compat=1
 invalid BAD_FIQ
+END(guest_fiq_invalid_compat)
 
-guest_error_compat:
+FUNC_LOCAL(guest_error_compat)
 guest_vector compat=1, iflags=IFLAGS__AI_, trap=guest_serror
+END(guest_error_compat)
 
-ENTRY(return_to_new_vcpu32)
+FUNC(return_to_new_vcpu32)
 exithyp=0, compat=1
-ENTRY(return_to_new_vcpu64)
+END(return_to_new_vcpu32)
+
+FUNC(return_to_new_vcpu64)
 exithyp=0, compat=0
+END(return_to_new_vcpu64)
 
-return_from_trap:
+FUNC_LOCAL(return_from_trap)
 msr daifset, #IFLAGS___I_ /* Mask interrupts */
 
 ldr x21, [sp, #UREGS_PC]/* load ELR */
@@ -524,6 +545,7 @@ return_from_trap:
 
 eret
 sb
+END(return_from_trap)
 
 /*
  * Consume pending SError generated by the guest if any.
@@ -536,7 +558,7 @@ return_from_trap:
  * it. So the function will unmask SError exception for a small window and
  * then mask it again.
  */
-check_pending_guest_serror:
+FUNC_LOCAL(check_pending_guest_serror)
 /*
  * Save elr_el2 to check whether the pending SError exception takes
  * place while we are doing this sync exception.
@@ -586,7 +608,7 @@ abort_guest_exit_end:
 csetx19, ne
 
 re

[PATCH v3 6/9] xen/arm64: bpi: Add missing code symbol annotations

2024-05-02 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Use the generic xen/linkage.h macros to annotate code symbols
and add missing annotations.

Signed-off-by: Edgar E. Iglesias 
---
 xen/arch/arm/arm64/bpi.S | 20 
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/xen/arch/arm/arm64/bpi.S b/xen/arch/arm/arm64/bpi.S
index 4e63825220..b16e4d1e29 100644
--- a/xen/arch/arm/arm64/bpi.S
+++ b/xen/arch/arm/arm64/bpi.S
@@ -52,14 +52,15 @@
  * micro-architectures in a system.
  */
 .align 11
-ENTRY(__bp_harden_hyp_vecs_start)
+FUNC(__bp_harden_hyp_vecs_start)
 .rept 4
 vectors hyp_traps_vector
 .endr
-ENTRY(__bp_harden_hyp_vecs_end)
+GLOBAL(__bp_harden_hyp_vecs_end)
+END(__bp_harden_hyp_vecs_start)
 
 .macro mitigate_spectre_bhb_loop count
-ENTRY(__mitigate_spectre_bhb_loop_start_\count)
+FUNC(__mitigate_spectre_bhb_loop_start_\count)
 stp x0, x1, [sp, #-16]!
 mov x0, \count
 .Lspectre_bhb_loop\@:
@@ -68,11 +69,12 @@ ENTRY(__mitigate_spectre_bhb_loop_start_\count)
 b.ne.Lspectre_bhb_loop\@
 sb
 ldp x0, x1, [sp], #16
-ENTRY(__mitigate_spectre_bhb_loop_end_\count)
+GLOBAL(__mitigate_spectre_bhb_loop_end_\count)
+END(__mitigate_spectre_bhb_loop_start_\count)
 .endm
 
 .macro smccc_workaround num smcc_id
-ENTRY(__smccc_workaround_smc_start_\num)
+FUNC(__smccc_workaround_smc_start_\num)
 sub sp, sp, #(8 * 4)
 stp x0, x1, [sp, #(8 * 2)]
 stp x2, x3, [sp, #(8 * 0)]
@@ -81,13 +83,15 @@ ENTRY(__smccc_workaround_smc_start_\num)
 ldp x2, x3, [sp, #(8 * 0)]
 ldp x0, x1, [sp, #(8 * 2)]
 add sp, sp, #(8 * 4)
-ENTRY(__smccc_workaround_smc_end_\num)
+GLOBAL(__smccc_workaround_smc_end_\num)
+END(__smccc_workaround_smc_start_\num)
 .endm
 
-ENTRY(__mitigate_spectre_bhb_clear_insn_start)
+FUNC(__mitigate_spectre_bhb_clear_insn_start)
 clearbhb
 isb
-ENTRY(__mitigate_spectre_bhb_clear_insn_end)
+GLOBAL(__mitigate_spectre_bhb_clear_insn_end)
+END(__mitigate_spectre_bhb_clear_insn_start)
 
 mitigate_spectre_bhb_loop 8
 mitigate_spectre_bhb_loop 24
-- 
2.40.1




[PATCH v3 2/9] xen/arm64: smc: Add missing code symbol annotations

2024-05-02 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Use the generic xen/linkage.h macros to annotate code symbols
and add missing annotations.

Signed-off-by: Edgar E. Iglesias 
---
 xen/arch/arm/arm64/smc.S | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/xen/arch/arm/arm64/smc.S b/xen/arch/arm/arm64/smc.S
index fc6b676e2e..68b05e8ddd 100644
--- a/xen/arch/arm/arm64/smc.S
+++ b/xen/arch/arm/arm64/smc.S
@@ -19,7 +19,7 @@
  *  register_t a6, register_t a7,
  *  struct arm_smccc_res *res)
  */
-ENTRY(__arm_smccc_1_0_smc)
+FUNC(__arm_smccc_1_0_smc)
 smc #0
 ldr x4, [sp]
 cbz x4, 1f  /* No need to store the result */
@@ -27,12 +27,13 @@ ENTRY(__arm_smccc_1_0_smc)
 stp x2, x3, [x4, #SMCCC_RES_a2]
 1:
 ret
+END(__arm_smccc_1_0_smc)
 
 /*
  * void arm_smccc_1_2_smc(const struct arm_smccc_1_2_regs *args,
  *struct arm_smccc_1_2_regs *res)
  */
-ENTRY(arm_smccc_1_2_smc)
+FUNC(arm_smccc_1_2_smc)
 /* Save `res` and free a GPR that won't be clobbered by SMC call */
 stp x1, x19, [sp, #-16]!
 
@@ -69,3 +70,4 @@ ENTRY(arm_smccc_1_2_smc)
 /* Restore original x19 */
 ldp xzr, x19, [sp], #16
 ret
+END(arm_smccc_1_2_smc)
-- 
2.40.1




[PATCH v3 7/9] xen/arm64: mmu/head: Add missing code symbol annotations

2024-05-02 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Use the generic xen/linkage.h macros to annotate code symbols
and add missing annotations.

Signed-off-by: Edgar E. Iglesias 
---
 xen/arch/arm/arm64/mmu/head.S | 28 ++--
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/xen/arch/arm/arm64/mmu/head.S b/xen/arch/arm/arm64/mmu/head.S
index fa40b696dd..7788bb95e5 100644
--- a/xen/arch/arm/arm64/mmu/head.S
+++ b/xen/arch/arm/arm64/mmu/head.S
@@ -138,7 +138,7 @@
  *
  * Clobbers x0 - x4
  */
-create_page_tables:
+FUNC_LOCAL(create_page_tables)
 /* Prepare the page-tables for mapping Xen */
 ldr   x0, =XEN_VIRT_START
 create_table_entry boot_pgtable, boot_first, x0, 0, x1, x2, x3
@@ -260,7 +260,7 @@ virtphys_clash:
 /* Identity map clashes with boot_third, which we cannot handle yet */
 PRINT("- Unable to build boot page tables - virt and phys addresses 
clash. -\r\n")
 b fail
-ENDPROC(create_page_tables)
+END(create_page_tables)
 
 /*
  * Turn on the Data Cache and the MMU. The function will return on the 1:1
@@ -273,7 +273,7 @@ ENDPROC(create_page_tables)
  *
  * Clobbers x0 - x5
  */
-enable_mmu:
+FUNC_LOCAL(enable_mmu)
 mov   x4, x0
 mov   x5, x1
 PRINT_ID("- Turning on paging -\r\n")
@@ -304,7 +304,7 @@ enable_mmu:
 PRINT_ID("- Paging turned on -\r\n")
 
 ret
-ENDPROC(enable_mmu)
+END(enable_mmu)
 
 /*
  * Enable mm (turn on the data cache and the MMU) for secondary CPUs.
@@ -316,7 +316,7 @@ ENDPROC(enable_mmu)
  *
  * Clobbers x0 - x6
  */
-ENTRY(enable_secondary_cpu_mm)
+FUNC(enable_secondary_cpu_mm)
 mov   x6, lr
 
 load_paddr x0, init_ttbr
@@ -328,7 +328,7 @@ ENTRY(enable_secondary_cpu_mm)
 
 /* Return to the virtual address requested by the caller. */
 ret
-ENDPROC(enable_secondary_cpu_mm)
+END(enable_secondary_cpu_mm)
 
 /*
  * Enable mm (turn on the data cache and the MMU) for the boot CPU.
@@ -340,7 +340,7 @@ ENDPROC(enable_secondary_cpu_mm)
  *
  * Clobbers x0 - x6
  */
-ENTRY(enable_boot_cpu_mm)
+FUNC(enable_boot_cpu_mm)
 mov   x6, lr
 
 blcreate_page_tables
@@ -365,7 +365,7 @@ ENTRY(enable_boot_cpu_mm)
  * by the caller.
  */
 b remove_identity_mapping
-ENDPROC(enable_boot_cpu_mm)
+END(enable_boot_cpu_mm)
 
 /*
  * Remove the 1:1 map from the page-tables. It is not easy to keep track
@@ -377,7 +377,7 @@ ENDPROC(enable_boot_cpu_mm)
  *
  * Clobbers x0 - x1
  */
-remove_identity_mapping:
+FUNC_LOCAL(remove_identity_mapping)
 /*
  * Find the zeroeth slot used. Remove the entry from zeroeth
  * table if the slot is not XEN_ZEROETH_SLOT.
@@ -419,20 +419,20 @@ identity_mapping_removed:
 flush_xen_tlb_local
 
 ret
-ENDPROC(remove_identity_mapping)
+END(remove_identity_mapping)
 
 /* Fail-stop */
-fail:   PRINT("- Boot failed -\r\n")
+FUNC_LOCAL(fail)   PRINT("- Boot failed -\r\n")
 1:  wfe
 b 1b
-ENDPROC(fail)
+END(fail)
 
 /*
  * Switch TTBR
  *
  * x0ttbr
  */
-ENTRY(switch_ttbr_id)
+FUNC(switch_ttbr_id)
 /* 1) Ensure any previous read/write have completed */
 dsbish
 isb
@@ -464,7 +464,7 @@ ENTRY(switch_ttbr_id)
 isb
 
 ret
-ENDPROC(switch_ttbr_id)
+END(switch_ttbr_id)
 
 /*
  * Local variables:
-- 
2.40.1




[PATCH v3 9/9] xen/arm64: lib: Use the generic xen/linkage.h macros

2024-05-02 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Use the generic xen/linkage.h macros to annotate code symbols.

Signed-off-by: Edgar E. Iglesias 
---
 xen/arch/arm/arm64/lib/memchr.S  | 4 ++--
 xen/arch/arm/arm64/lib/memcmp.S  | 4 ++--
 xen/arch/arm/arm64/lib/memcpy.S  | 4 ++--
 xen/arch/arm/arm64/lib/memmove.S | 4 ++--
 xen/arch/arm/arm64/lib/memset.S  | 4 ++--
 xen/arch/arm/arm64/lib/strchr.S  | 4 ++--
 xen/arch/arm/arm64/lib/strcmp.S  | 4 ++--
 xen/arch/arm/arm64/lib/strlen.S  | 4 ++--
 xen/arch/arm/arm64/lib/strncmp.S | 4 ++--
 xen/arch/arm/arm64/lib/strnlen.S | 4 ++--
 xen/arch/arm/arm64/lib/strrchr.S | 4 ++--
 11 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/xen/arch/arm/arm64/lib/memchr.S b/xen/arch/arm/arm64/lib/memchr.S
index 81f113bb1c..3d8aeca3ca 100644
--- a/xen/arch/arm/arm64/lib/memchr.S
+++ b/xen/arch/arm/arm64/lib/memchr.S
@@ -29,7 +29,7 @@
  * Returns:
  * x0 - address of first occurrence of 'c' or 0
  */
-ENTRY(memchr)
+FUNC(memchr)
and w1, w1, #0xff
 1: subsx2, x2, #1
b.mi2f
@@ -40,4 +40,4 @@ ENTRY(memchr)
ret
 2: mov x0, #0
ret
-ENDPROC(memchr)
+END(memchr)
diff --git a/xen/arch/arm/arm64/lib/memcmp.S b/xen/arch/arm/arm64/lib/memcmp.S
index 87c2537ffe..d77dd4ce52 100644
--- a/xen/arch/arm/arm64/lib/memcmp.S
+++ b/xen/arch/arm/arm64/lib/memcmp.S
@@ -57,7 +57,7 @@ pos   .reqx11
 limit_wd   .reqx12
 mask   .reqx13
 
-ENTRY(memcmp)
+FUNC(memcmp)
cbz limit, .Lret0
eor tmp1, src1, src2
tst tmp1, #7
@@ -254,4 +254,4 @@ CPU_LE( rev data2, data2 )
 .Lret0:
mov result, #0
ret
-ENDPROC(memcmp)
+END(memcmp)
diff --git a/xen/arch/arm/arm64/lib/memcpy.S b/xen/arch/arm/arm64/lib/memcpy.S
index d90d20ef3e..1e04b79010 100644
--- a/xen/arch/arm/arm64/lib/memcpy.S
+++ b/xen/arch/arm/arm64/lib/memcpy.S
@@ -55,7 +55,7 @@ C_h   .reqx12
 D_l.reqx13
 D_h.reqx14
 
-ENTRY(memcpy)
+FUNC(memcpy)
mov dst, dstin
cmp count, #16
/*When memory length is less than 16, the accessed are not aligned.*/
@@ -197,4 +197,4 @@ ENTRY(memcpy)
tst count, #0x3f
b.ne.Ltail63
ret
-ENDPROC(memcpy)
+END(memcpy)
diff --git a/xen/arch/arm/arm64/lib/memmove.S b/xen/arch/arm/arm64/lib/memmove.S
index a49de845d0..14438dbe9c 100644
--- a/xen/arch/arm/arm64/lib/memmove.S
+++ b/xen/arch/arm/arm64/lib/memmove.S
@@ -56,7 +56,7 @@ C_h   .reqx12
 D_l.reqx13
 D_h.reqx14
 
-ENTRY(memmove)
+FUNC(memmove)
cmp dstin, src
b.lomemcpy
add tmp1, src, count
@@ -193,4 +193,4 @@ ENTRY(memmove)
tst count, #0x3f
b.ne.Ltail63
ret
-ENDPROC(memmove)
+END(memmove)
diff --git a/xen/arch/arm/arm64/lib/memset.S b/xen/arch/arm/arm64/lib/memset.S
index 5bf751521b..367fa60175 100644
--- a/xen/arch/arm/arm64/lib/memset.S
+++ b/xen/arch/arm/arm64/lib/memset.S
@@ -53,7 +53,7 @@ dst   .reqx8
 tmp3w  .reqw9
 tmp3   .reqx9
 
-ENTRY(memset)
+FUNC(memset)
mov dst, dstin  /* Preserve return value.  */
and A_lw, val, #255
orr A_lw, A_lw, A_lw, lsl #8
@@ -212,4 +212,4 @@ ENTRY(memset)
andscount, count, zva_bits_x
b.ne.Ltail_maybe_long
ret
-ENDPROC(memset)
+END(memset)
diff --git a/xen/arch/arm/arm64/lib/strchr.S b/xen/arch/arm/arm64/lib/strchr.S
index 0506b0ff7f..83fd81e8ef 100644
--- a/xen/arch/arm/arm64/lib/strchr.S
+++ b/xen/arch/arm/arm64/lib/strchr.S
@@ -27,7 +27,7 @@
  * Returns:
  * x0 - address of first occurrence of 'c' or 0
  */
-ENTRY(strchr)
+FUNC(strchr)
and w1, w1, #0xff
 1: ldrbw2, [x0], #1
cmp w2, w1
@@ -37,4 +37,4 @@ ENTRY(strchr)
cmp w2, w1
cselx0, x0, xzr, eq
ret
-ENDPROC(strchr)
+END(strchr)
diff --git a/xen/arch/arm/arm64/lib/strcmp.S b/xen/arch/arm/arm64/lib/strcmp.S
index c6f42dd255..7677108e26 100644
--- a/xen/arch/arm/arm64/lib/strcmp.S
+++ b/xen/arch/arm/arm64/lib/strcmp.S
@@ -59,7 +59,7 @@ tmp3  .reqx9
 zeroones   .reqx10
 pos.reqx11
 
-ENTRY(strcmp)
+FUNC(strcmp)
eor tmp1, src1, src2
mov zeroones, #REP8_01
tst tmp1, #7
@@ -230,4 +230,4 @@ CPU_BE( orr syndrome, diff, has_nul )
lsr data1, data1, #56
sub result, data1, data2, lsr #56
ret
-ENDPROC(strcmp)
+END(strcmp)
diff --git a/xen/arch/arm/arm64/lib/strlen.S b/xen/arch/arm/arm64/lib/strlen.S
index fb6aaf1a6a..10feedaf81 100644
--- a/xen/arch/arm/arm64/lib/strlen.S
+++ b/xen/arch/arm/arm64/lib/strlen.S
@@ -56,7 +56,7 @@ pos   .reqx12
 #define REP8_7f 0x7f7f7f7f7f7f7f7f
 #define REP8_80 0x8080808080808080
 
-ENTRY(strlen)
+FUNC(strlen)
mov zeroones, #REP8_01
bic src, srcin, #15
andstmp1, srcin, #15
@@ -123,4 +123,4 @@ CPU_LE( lsr tmp2, tmp2, tmp1 )

[PATCH v3 3/9] xen/arm64: sve: Add missing code symbol annotations

2024-05-02 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Use the generic xen/linkage.h macros to annotate code symbols
and add missing annotations.

Signed-off-by: Edgar E. Iglesias 
---
 xen/arch/arm/arm64/sve-asm.S | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/xen/arch/arm/arm64/sve-asm.S b/xen/arch/arm/arm64/sve-asm.S
index 59dbefbbb2..2d8b895f07 100644
--- a/xen/arch/arm/arm64/sve-asm.S
+++ b/xen/arch/arm/arm64/sve-asm.S
@@ -161,9 +161,10 @@
 .endm
 
 /* Gets the current vector register size in bytes */
-GLOBAL(sve_get_hw_vl)
+FUNC(sve_get_hw_vl)
 _sve_rdvl 0, 1
 ret
+END(sve_get_hw_vl)
 
 /*
  * Save the SVE context
@@ -172,9 +173,10 @@ GLOBAL(sve_get_hw_vl)
  * x1 - pointer to buffer for P0-15
  * x2 - Save FFR if non-zero
  */
-GLOBAL(sve_save_ctx)
+FUNC(sve_save_ctx)
 sve_save 0, 1, x2
 ret
+END(sve_save_ctx)
 
 /*
  * Load the SVE context
@@ -183,9 +185,10 @@ GLOBAL(sve_save_ctx)
  * x1 - pointer to buffer for P0-15
  * x2 - Restore FFR if non-zero
  */
-GLOBAL(sve_load_ctx)
+FUNC(sve_load_ctx)
 sve_load 0, 1, x2
 ret
+END(sve_load_ctx)
 
 /*
  * Local variables:
-- 
2.40.1




[PATCH v3 4/9] xen/arm64: head: Add missing code symbol annotations

2024-05-02 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Use the generic xen/linkage.h macros to annotate code symbols
and add missing annotations.

Signed-off-by: Edgar E. Iglesias 
---
 xen/arch/arm/arm64/head.S | 50 ---
 1 file changed, 26 insertions(+), 24 deletions(-)

diff --git a/xen/arch/arm/arm64/head.S b/xen/arch/arm/arm64/head.S
index fb297e9eb5..7acedb4f8f 100644
--- a/xen/arch/arm/arm64/head.S
+++ b/xen/arch/arm/arm64/head.S
@@ -90,7 +90,7 @@
  * 4K-aligned address.
  */
 
-GLOBAL(start)
+FUNC(start)
 /*
  * DO NOT MODIFY. Image header expected by Linux boot-loaders.
  */
@@ -102,6 +102,7 @@ efi_head:
  */
 add x13, x18, #0x16
 b   real_start   /* branch to kernel start */
+END(start)
 .quad   0/* Image load offset from start of RAM */
 .quad   _end - start /* Effective size of kernel image, 
little-endian */
 .quad   __HEAD_FLAGS /* Informative flags, little-endian */
@@ -223,7 +224,7 @@ section_table:
 .align  5
 #endif /* CONFIG_ARM_EFI */
 
-real_start:
+FUNC_LOCAL(real_start)
 /* BSS should be zeroed when booting without EFI */
 mov   x26, #0/* x26 := skip_zero_bss */
 
@@ -263,9 +264,9 @@ primary_switched:
 mov   x1, x21/* x1 := paddr(FDT) */
 ldr   x2, =start_xen
 b launch
-ENDPROC(real_start)
+END(real_start)
 
-GLOBAL(init_secondary)
+FUNC(init_secondary)
 msr   DAIFSet, 0xf   /* Disable all interrupts */
 
 /* Find out where we are */
@@ -304,7 +305,7 @@ secondary_switched:
 /* Jump to C world */
 ldr   x2, =start_secondary
 b launch
-ENDPROC(init_secondary)
+END(init_secondary)
 
 /*
  * Check if the CPU has been booted in Hypervisor mode.
@@ -313,7 +314,7 @@ ENDPROC(init_secondary)
  *
  * Clobbers x0 - x5
  */
-check_cpu_mode:
+FUNC_LOCAL(check_cpu_mode)
 PRINT_ID("- Current EL ")
 mrs   x5, CurrentEL
 print_reg x5
@@ -329,7 +330,7 @@ check_cpu_mode:
 PRINT_ID("- Xen must be entered in NS EL2 mode -\r\n")
 PRINT_ID("- Please update the bootloader -\r\n")
 b fail
-ENDPROC(check_cpu_mode)
+END(check_cpu_mode)
 
 /*
  * Zero BSS
@@ -339,7 +340,7 @@ ENDPROC(check_cpu_mode)
  *
  * Clobbers x0 - x3
  */
-zero_bss:
+FUNC_LOCAL(zero_bss)
 /* Zero BSS only when requested */
 cbnz  x26, skip_bss
 
@@ -353,14 +354,14 @@ zero_bss:
 
 skip_bss:
 ret
-ENDPROC(zero_bss)
+END(zero_bss)
 
 /*
  * Initialize the processor for turning the MMU on.
  *
  * Clobbers x0 - x3
  */
-cpu_init:
+FUNC_LOCAL(cpu_init)
 PRINT_ID("- Initialize CPU -\r\n")
 
 /* Set up memory attribute type tables */
@@ -399,7 +400,7 @@ cpu_init:
  */
 msr spsel, #1
 ret
-ENDPROC(cpu_init)
+END(cpu_init)
 
 /*
  * Setup the initial stack and jump to the C world
@@ -411,7 +412,7 @@ ENDPROC(cpu_init)
  *
  * Clobbers x3
  */
-launch:
+FUNC_LOCAL(launch)
 ldr   x3, =init_data
 add   x3, x3, #INITINFO_stack /* Find the boot-time stack */
 ldr   x3, [x3]
@@ -421,13 +422,13 @@ launch:
 
 /* Jump to C world */
 brx2
-ENDPROC(launch)
+END(launch)
 
 /* Fail-stop */
-fail:   PRINT_ID("- Boot failed -\r\n")
+FUNC_LOCAL(fail)   PRINT_ID("- Boot failed -\r\n")
 1:  wfe
 b 1b
-ENDPROC(fail)
+END(fail)
 
 #ifdef CONFIG_EARLY_PRINTK
 /*
@@ -438,14 +439,14 @@ ENDPROC(fail)
  *
  * Clobbers x0 - x1
  */
-init_uart:
+FUNC_LOCAL(init_uart)
 ldr   x23, =CONFIG_EARLY_UART_BASE_ADDRESS
 #ifdef CONFIG_EARLY_UART_INIT
 early_uart_init x23, 0
 #endif
 PRINT("- UART enabled -\r\n")
 ret
-ENDPROC(init_uart)
+END(init_uart)
 
 /*
  * Print early debug messages.
@@ -454,7 +455,7 @@ ENDPROC(init_uart)
  * x23: Early UART base address
  * Clobbers x0-x1
  */
-ENTRY(asm_puts)
+FUNC(asm_puts)
 early_uart_ready x23, 1
 ldrb  w1, [x0], #1   /* Load next char */
 cbz   w1, 1f /* Exit on nul */
@@ -462,7 +463,7 @@ ENTRY(asm_puts)
 b asm_puts
 1:
 ret
-ENDPROC(asm_puts)
+END(asm_puts)
 
 /*
  * Print a 64-bit number in hex.
@@ -471,7 +472,7 @@ ENDPROC(asm_puts)
  * x23: Early UART base address
  * Clobbers x0-x3
  */
-ENTRY(asm_putn)
+FUNC(asm_putn)
 adr_l x1, hex
 mov   x3, #16
 1:
@@ -484,7 +485,7 @@ ENTRY(asm_putn)
 subs  x3, x3, #1
 b.ne  1b
 ret
-ENDPROC(asm_putn)
+END(asm_putn)
 
 RODATA_SECT(.rodata.idmap, hex, "0123456789abcdef")
 
@@ -493,16 +494,17 @@ RODATA_SECT(.rodata.idmap, hex, "0123456789abcdef")
 /* This provides a C-API version of __lookup_processor_type
  * TODO: For now, the implementation return NULL every time
  */
-ENTRY(lookup_processor_type)
+FUNC(lookup_pr

[PATCH v3 0/9] xen/arm: arm64: Annotate code symbols

2024-05-02 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

On the way towards Xen safety certification we're evaluating the use
of tools to collect code-coverage/profiling information from execution
traces. Some tools rely on ELF symbols for code being declared with
type FUNC and having a symbol size.

We currently annotate some symbols but not all. Also, there seems to be
different ways to do the annotation.

This series now converts all the .S files under xen/arm/arm64 to use
the macros from xen/linkage.h and also adds missing code symbol
annotations when appropriate.

Best regards,
Edgar

ChangeLog:

v2 -> v3:
* Convert and add annotations for all of xen/arm/arm64.
* Fix brain freeze in commit message for entry.S.

v1 -> v2:
* Drop RFC.
* Squash into a single patch to avoid confusion.



Edgar E. Iglesias (9):
  xen/arm64: entry: Add missing code symbol annotations
  xen/arm64: smc: Add missing code symbol annotations
  xen/arm64: sve: Add missing code symbol annotations
  xen/arm64: head: Add missing code symbol annotations
  xen/arm64: debug: Add missing code symbol annotations
  xen/arm64: bpi: Add missing code symbol annotations
  xen/arm64: mmu/head: Add missing code symbol annotations
  xen/arm64: cache: Use the generic xen/linkage.h macros
  xen/arm64: lib: Use the generic xen/linkage.h macros

 xen/arch/arm/arm64/bpi.S | 20 +
 xen/arch/arm/arm64/cache.S   |  4 +-
 xen/arch/arm/arm64/debug.S   |  6 ++-
 xen/arch/arm/arm64/entry.S   | 72 +---
 xen/arch/arm/arm64/head.S| 50 +++---
 xen/arch/arm/arm64/lib/memchr.S  |  4 +-
 xen/arch/arm/arm64/lib/memcmp.S  |  4 +-
 xen/arch/arm/arm64/lib/memcpy.S  |  4 +-
 xen/arch/arm/arm64/lib/memmove.S |  4 +-
 xen/arch/arm/arm64/lib/memset.S  |  4 +-
 xen/arch/arm/arm64/lib/strchr.S  |  4 +-
 xen/arch/arm/arm64/lib/strcmp.S  |  4 +-
 xen/arch/arm/arm64/lib/strlen.S  |  4 +-
 xen/arch/arm/arm64/lib/strncmp.S |  4 +-
 xen/arch/arm/arm64/lib/strnlen.S |  4 +-
 xen/arch/arm/arm64/lib/strrchr.S |  4 +-
 xen/arch/arm/arm64/mmu/head.S| 28 ++---
 xen/arch/arm/arm64/smc.S |  6 ++-
 xen/arch/arm/arm64/sve-asm.S |  9 ++--
 19 files changed, 138 insertions(+), 101 deletions(-)

-- 
2.40.1




Re: [PATCH v2 1/1] xen/arm64: entry: Add missing code symbol annotations

2024-05-02 Thread Edgar E. Iglesias
On Fri, Apr 26, 2024 at 1:14 AM Stefano Stabellini
 wrote:
>
> On Tue, 16 Apr 2024, Edgar E. Iglesias wrote:
> > From: "Edgar E. Iglesias" 
> >
> > Use the generic xen/linkage.h macros when and add missing
> ^ when what?
>
> > code symbol annotations.
> >
> > Signed-off-by: Edgar E. Iglesias 
>
> I am looking at the implementation of FUNC and as far as I can tell
> there is no change compared to ENTRY. So from that point of view we are
> good. I wonder if we should keep using "ENTRY" because it is nice to
> mark explicitely the entry points as such but at the same time I am also
> OK with this. I'll let the other ARM maintainers decide.
>
> On the other hand, FUNC_LOCAL does introduce a change: it adds a .align
> everywhere. Should not be harmful?
>
> With the commit message fixed:

Thanks Stefano, will fix the commit message in v3:

 "Use the generic xen/linkage.h macros to annotate code symbols
 and add missing annotations."

Cheers,
Edgar



>
> Reviewed-by: Stefano Stabellini 
>
>
> > ---
> >  xen/arch/arm/arm64/entry.S | 72 +-
> >  1 file changed, 48 insertions(+), 24 deletions(-)
> >
> > diff --git a/xen/arch/arm/arm64/entry.S b/xen/arch/arm/arm64/entry.S
> > index f963c923bb..af9a592cae 100644
> > --- a/xen/arch/arm/arm64/entry.S
> > +++ b/xen/arch/arm/arm64/entry.S
> > @@ -289,21 +289,25 @@
> >  b   do_bad_mode
> >  .endm
> >
> > -hyp_sync_invalid:
> > +FUNC_LOCAL(hyp_sync_invalid)
> >  entry   hyp=1
> >  invalid BAD_SYNC
> > +END(hyp_sync_invalid)
> >
> > -hyp_irq_invalid:
> > +FUNC_LOCAL(hyp_irq_invalid)
> >  entry   hyp=1
> >  invalid BAD_IRQ
> > +END(hyp_irq_invalid)
> >
> > -hyp_fiq_invalid:
> > +FUNC_LOCAL(hyp_fiq_invalid)
> >  entry   hyp=1
> >  invalid BAD_FIQ
> > +END(hyp_fiq_invalid)
> >
> > -hyp_error_invalid:
> > +FUNC_LOCAL(hyp_error_invalid)
> >  entry   hyp=1
> >  invalid BAD_ERROR
> > +END(hyp_error_invalid)
> >
> >  /*
> >   * SError received while running in the hypervisor mode.
> > @@ -313,11 +317,12 @@ hyp_error_invalid:
> >   * simplicity, as SError should be rare and potentially fatal,
> >   * all interrupts are kept masked.
> >   */
> > -hyp_error:
> > +FUNC_LOCAL(hyp_error)
> >  entry   hyp=1
> >  mov x0, sp
> >  bl  do_trap_hyp_serror
> >  exithyp=1
> > +END(hyp_error)
> >
> >  /*
> >   * Synchronous exception received while running in the hypervisor mode.
> > @@ -327,7 +332,7 @@ hyp_error:
> >   * some of them. So we want to inherit the state from the interrupted
> >   * context.
> >   */
> > -hyp_sync:
> > +FUNC_LOCAL(hyp_sync)
> >  entry   hyp=1
> >
> >  /* Inherit interrupts */
> > @@ -338,6 +343,7 @@ hyp_sync:
> >  mov x0, sp
> >  bl  do_trap_hyp_sync
> >  exithyp=1
> > +END(hyp_sync)
> >
> >  /*
> >   * IRQ received while running in the hypervisor mode.
> > @@ -352,7 +358,7 @@ hyp_sync:
> >   * would require some rework in some paths (e.g. panic, livepatch) to
> >   * ensure the ordering is enforced everywhere.
> >   */
> > -hyp_irq:
> > +FUNC_LOCAL(hyp_irq)
> >  entry   hyp=1
> >
> >  /* Inherit D, A, F interrupts and keep I masked */
> > @@ -365,8 +371,9 @@ hyp_irq:
> >  mov x0, sp
> >  bl  do_trap_irq
> >  exithyp=1
> > +END(hyp_irq)
> >
> > -guest_sync:
> > +FUNC_LOCAL(guest_sync)
> >  /*
> >   * Save x0, x1 in advance
> >   */
> > @@ -413,8 +420,9 @@ fastpath_out_workaround:
> >  mov x1, xzr
> >  eret
> >  sb
> > +END(guest_sync)
> >
> > -wa2_ssbd:
> > +FUNC_LOCAL(wa2_ssbd)
> >  #ifdef CONFIG_ARM_SSBD
> >  alternative_cb arm_enable_wa2_handling
> >  b   wa2_end
> > @@ -450,42 +458,55 @@ wa2_end:
> >  mov x0, xzr
> >  eret
> >  sb
> > -guest_sync_slowpath:
> > +END(wa2_ssbd)
> > +
> > +FUNC_LOCAL(guest_sync_slowpath)
> >  /*
> >   * x0/x1 may have been scratch by the fast path above, so avoid
> >   * to save them.
> >   */
> >  guest_vec

Re: [PATCH v4 12/17] xen: mapcache: Unmap first entries in buckets

2024-05-02 Thread Edgar E. Iglesias
On Tue, Apr 30, 2024 at 6:50 PM Edgar E. Iglesias
 wrote:
>
> From: "Edgar E. Iglesias" 
>
> When invalidating memory ranges, if we happen to hit the first
> entry in a bucket we were never unmapping it. This was harmless
> for foreign mappings but now that we're looking to reuse the
> mapcache for transient grant mappings, we must unmap entries
> when invalidated.
>
> Signed-off-by: Edgar E. Iglesias 
> ---
>  hw/xen/xen-mapcache.c | 12 
>  1 file changed, 8 insertions(+), 4 deletions(-)
>
> diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
> index 4f98d284dd..0365311788 100644
> --- a/hw/xen/xen-mapcache.c
> +++ b/hw/xen/xen-mapcache.c
> @@ -486,18 +486,22 @@ static void 
> xen_invalidate_map_cache_entry_unlocked(MapCache *mc,
>  return;
>  }
>  entry->lock--;
> -if (entry->lock > 0 || pentry == NULL) {
> +if (entry->lock > 0) {
>  return;
>  }
>
> -pentry->next = entry->next;
>  ram_block_notify_remove(entry->vaddr_base, entry->size, entry->size);
>  if (munmap(entry->vaddr_base, entry->size) != 0) {
>  perror("unmap fails");
>  exit(-1);
>  }
> -g_free(entry->valid_mapping);
> -g_free(entry);
> +if (pentry) {
> +pentry->next = entry->next;
> +g_free(entry->valid_mapping);
> +g_free(entry);
> +} else {
> +memset(entry, 0, sizeof *entry);

I noticed that we're leaking entry->valid_mapping here. I'll fix this for v5.

Cheers,
Edgar


> +}
>  }
>
>  typedef struct XenMapCacheData {
> --
> 2.40.1
>



Re: [PATCH v4 13/17] softmmu: Pass RAM MemoryRegion and is_write xen_map_cache()

2024-05-02 Thread Edgar E. Iglesias
On Thu, May 2, 2024 at 9:24 AM David Hildenbrand  wrote:
>
> On 30.04.24 18:49, Edgar E. Iglesias wrote:
> > From: "Edgar E. Iglesias" 
> >
> > Propagate MR and is_write to xen_map_cache().
>
> I'm pretty sure the patch subject is missing a "to" :)

Thanks David! I'll fix it in v5!

Cheers,
Edgar


>
> > This is in preparation for adding support for grant mappings.
> >
> > No functional change.
> >
>
> Reviewed-by: David Hildenbrand 
> --
> Cheers,
>
> David / dhildenb
>



Re: [PATCH v4 15/17] xen: mapcache: Remove assumption of RAMBlock with 0 offset

2024-05-02 Thread Edgar E. Iglesias
On Wed, May 1, 2024 at 11:24 PM Stefano Stabellini
 wrote:
>
> On Tue, 30 Apr 2024, Edgar E. Iglesias wrote:
> > From: "Edgar E. Iglesias" 
> >
> > The current mapcache assumes that all memory is mapped
> > in a single RAM MR (the first one with offset 0). Remove
> > this assumption and propagate the offset to the mapcache
> > so it can do reverse mappings (from hostptr -> ram_addr).
> >
> > This is in preparation for adding grant mappings.
> >
> > Signed-off-by: Edgar E. Iglesias 
>
>
> Looking at xen_remap_bucket, it is only using address_index (without
> adding ram_offset) to map foreign memory. From xen_remap_bucket, I would
> understand that address_index already includes the ram_offset.
>
> Meaning that if we want to map foreign mapping at address 0x5000, then
> address_index would be 0x5000, even if ram_offset is 0x1000.
>
> But then looking xen_ram_addr_from_mapcache_single ram_offset is added
> to paddr_index to calculate the physical address. So in that case we
> would want address_index to be 0x4000 and ram_offset to be 0x1000. But
> xen_remap_bucket would have to sum address_index and ram_offset to map
> foreign memory.
>
> So I am a bit confused, did I get it wrong? One more comment below.
>

Thanks Stefano,

I think the confusion is that this ram_addr_offset is not related to
guest address-space.
It's a QEMU internal thing and it shouldn't be included in the address
used to map foreign memory.
The mapcache can treat this ram_addr offset like a cookie that we keep
around to be able to do
reverse mappings from host pointers into ram_addr space
(xen_ram_addr_from_mapcache).

The current mapcache implementation works because we've really only
been using foreign mappings
on RAMBlocks with offset 0. We're also creating RAM's such that the
offset into the RAM is also
the guest physical address, for x86 this is natural since RAM starts
at zero (for lowmem) but for
ARM we're creating larger than needed RAM's (GUEST_RAM0_BASE + ram-size) to
make this assumption true. Anyway, In this series I'm not addressing
this second assumption.

There's a second call in physmem.c to xen_map_cache using the
block->offset as an address.
I was considering removing that second call since I can't see how it can work
(except perhaps in some specific use-case by luck?). Anyway, for now
I've left it unmodified.


>
> > ---
> >  hw/xen/xen-mapcache.c | 25 ++---
> >  include/sysemu/xen-mapcache.h |  2 ++
> >  system/physmem.c  |  8 
> >  3 files changed, 24 insertions(+), 11 deletions(-)
> >
> > diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
> > index 09b5f36d9c..1b32d0c003 100644
> > --- a/hw/xen/xen-mapcache.c
> > +++ b/hw/xen/xen-mapcache.c
> > @@ -43,6 +43,9 @@ typedef struct MapCacheEntry {
> >  #define XEN_MAPCACHE_ENTRY_DUMMY (1 << 0)
> >  uint8_t flags;
> >  hwaddr size;
> > +
> > +/* Keep ram_addr offset for reverse mappings (hostptr -> ram_addr).  */
> > +ram_addr_t ram_offset;
> >  struct MapCacheEntry *next;
> >  } MapCacheEntry;
> >
> > @@ -165,7 +168,8 @@ static void xen_remap_bucket(MapCache *mc,
> >   void *vaddr,
> >   hwaddr size,
> >   hwaddr address_index,
> > - bool dummy)
> > + bool dummy,
> > + ram_addr_t ram_offset)
> >  {
> >  uint8_t *vaddr_base;
> >  xen_pfn_t *pfns;
> > @@ -244,6 +248,7 @@ static void xen_remap_bucket(MapCache *mc,
> >  entry->size = size;
> >  entry->valid_mapping = g_new0(unsigned long,
> >BITS_TO_LONGS(size >> XC_PAGE_SHIFT));
> > +entry->ram_offset = ram_offset;
> >
> >  if (dummy) {
> >  entry->flags |= XEN_MAPCACHE_ENTRY_DUMMY;
> > @@ -264,6 +269,7 @@ static void xen_remap_bucket(MapCache *mc,
> >
> >  static uint8_t *xen_map_cache_unlocked(MapCache *mc,
> > hwaddr phys_addr, hwaddr size,
> > +   ram_addr_t ram_offset,
> > uint8_t lock, bool dma, bool 
> > is_write)
> >  {
> >  MapCacheEntry *entry, *pentry = NULL,
> > @@ -335,14 +341,16 @@ tryagain:
> >  if (!entry) {
> >  entry = g_new0(MapCacheEntry, 1);
> >  pentry->next = entry;
> > -xen_remap_bucket(mc, entry, NULL, cache_size, address_index, 
> > dummy);
> > +xen_re

Re: [PATCH v4 07/17] xen: mapcache: Refactor xen_replace_cache_entry_unlocked

2024-05-02 Thread Edgar E. Iglesias
On Wed, May 1, 2024 at 10:46 PM Stefano Stabellini
 wrote:
>
> On Tue, 30 Apr 2024, Edgar E. Iglesias wrote:
> > From: "Edgar E. Iglesias" 
> >
> > Add MapCache argument to xen_replace_cache_entry_unlocked in
> > preparation for supporting multiple map caches.
> >
> > No functional change.
> >
> > Signed-off-by: Edgar E. Iglesias 
> > ---
> >  hw/xen/xen-mapcache.c | 8 +---
> >  1 file changed, 5 insertions(+), 3 deletions(-)
> >
> > diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
> > index d2deff70c8..6e758eff94 100644
> > --- a/hw/xen/xen-mapcache.c
> > +++ b/hw/xen/xen-mapcache.c
> > @@ -556,7 +556,8 @@ void xen_invalidate_map_cache(void)
> >  mapcache_unlock(mapcache);
> >  }
> >
> > -static uint8_t *xen_replace_cache_entry_unlocked(hwaddr old_phys_addr,
> > +static uint8_t *xen_replace_cache_entry_unlocked(MapCache *mc,
> > + hwaddr old_phys_addr,
> >   hwaddr new_phys_addr,
> >   hwaddr size)
> >  {
> > @@ -578,7 +579,7 @@ static uint8_t *xen_replace_cache_entry_unlocked(hwaddr 
> > old_phys_addr,
> >  cache_size += MCACHE_BUCKET_SIZE - (cache_size % 
> > MCACHE_BUCKET_SIZE);
> >  }
> >
> > -entry = >entry[address_index % mapcache->nr_buckets];
> > +entry = >entry[address_index % mc->nr_buckets];
> >  while (entry && !(entry->paddr_index == address_index &&
> >entry->size == cache_size)) {
> >  entry = entry->next;
>
> There is still a global mapcache pointer in use in this function:
>
>   xen_remap_bucket(mapcache, entry, entry->vaddr_base,
>


Thanks! I had accidentally put the change to use mc in future patches.
Will fix in v5.

Cheers,
Edgar


>
> > @@ -614,7 +615,8 @@ uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
> >  uint8_t *p;
> >
> >  mapcache_lock(mapcache);
> > -p = xen_replace_cache_entry_unlocked(old_phys_addr, new_phys_addr, 
> > size);
> > +p = xen_replace_cache_entry_unlocked(mapcache, old_phys_addr,
> > + new_phys_addr, size);
> >  mapcache_unlock(mapcache);
> >  return p;
> >  }
> > --
> > 2.40.1
> >



[PATCH v4 13/17] softmmu: Pass RAM MemoryRegion and is_write xen_map_cache()

2024-04-30 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Propagate MR and is_write to xen_map_cache().
This is in preparation for adding support for grant mappings.

No functional change.

Signed-off-by: Edgar E. Iglesias 
---
 hw/xen/xen-mapcache.c | 10 ++
 include/sysemu/xen-mapcache.h | 11 +++
 system/physmem.c  | 31 +++
 3 files changed, 36 insertions(+), 16 deletions(-)

diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
index 0365311788..09b5f36d9c 100644
--- a/hw/xen/xen-mapcache.c
+++ b/hw/xen/xen-mapcache.c
@@ -264,7 +264,7 @@ static void xen_remap_bucket(MapCache *mc,
 
 static uint8_t *xen_map_cache_unlocked(MapCache *mc,
hwaddr phys_addr, hwaddr size,
-   uint8_t lock, bool dma)
+   uint8_t lock, bool dma, bool is_write)
 {
 MapCacheEntry *entry, *pentry = NULL,
   *free_entry = NULL, *free_pentry = NULL;
@@ -387,13 +387,15 @@ tryagain:
 return mc->last_entry->vaddr_base + address_offset;
 }
 
-uint8_t *xen_map_cache(hwaddr phys_addr, hwaddr size,
-   uint8_t lock, bool dma)
+uint8_t *xen_map_cache(MemoryRegion *mr,
+   hwaddr phys_addr, hwaddr size,
+   uint8_t lock, bool dma,
+   bool is_write)
 {
 uint8_t *p;
 
 mapcache_lock(mapcache);
-p = xen_map_cache_unlocked(mapcache, phys_addr, size, lock, dma);
+p = xen_map_cache_unlocked(mapcache, phys_addr, size, lock, dma, is_write);
 mapcache_unlock(mapcache);
 return p;
 }
diff --git a/include/sysemu/xen-mapcache.h b/include/sysemu/xen-mapcache.h
index 10c2e3082a..1ec9e66752 100644
--- a/include/sysemu/xen-mapcache.h
+++ b/include/sysemu/xen-mapcache.h
@@ -18,8 +18,9 @@ typedef hwaddr (*phys_offset_to_gaddr_t)(hwaddr phys_offset,
 
 void xen_map_cache_init(phys_offset_to_gaddr_t f,
 void *opaque);
-uint8_t *xen_map_cache(hwaddr phys_addr, hwaddr size,
-   uint8_t lock, bool dma);
+uint8_t *xen_map_cache(MemoryRegion *mr, hwaddr phys_addr, hwaddr size,
+   uint8_t lock, bool dma,
+   bool is_write);
 ram_addr_t xen_ram_addr_from_mapcache(void *ptr);
 void xen_invalidate_map_cache_entry(uint8_t *buffer);
 void xen_invalidate_map_cache(void);
@@ -33,10 +34,12 @@ static inline void 
xen_map_cache_init(phys_offset_to_gaddr_t f,
 {
 }
 
-static inline uint8_t *xen_map_cache(hwaddr phys_addr,
+static inline uint8_t *xen_map_cache(MemoryRegion *mr,
+ hwaddr phys_addr,
  hwaddr size,
  uint8_t lock,
- bool dma)
+ bool dma,
+ bool is_write)
 {
 abort();
 }
diff --git a/system/physmem.c b/system/physmem.c
index f114b972a5..ad7a8c7d95 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -2190,11 +2190,22 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length)
 
 /*
  * Return a host pointer to guest's ram.
+ * For Xen, foreign mappings get created if they don't already exist.
+ *
+ * @block: block for the RAM to lookup (optional and may be NULL).
+ * @addr: address within the memory region.
+ * @size: pointer to requested size (optional and may be NULL).
+ *size may get modified and return a value smaller than
+ *what was requested.
+ * @lock: wether to lock the mapping in xen-mapcache until invalidated.
+ * @is_write: hint wether to map RW or RO in the xen-mapcache.
+ *(optional and may always be set to true).
  *
  * Called within RCU critical section.
  */
 static void *qemu_ram_ptr_length(RAMBlock *block, ram_addr_t addr,
- hwaddr *size, bool lock)
+ hwaddr *size, bool lock,
+ bool is_write)
 {
 hwaddr len = 0;
 
@@ -2217,10 +2228,13 @@ static void *qemu_ram_ptr_length(RAMBlock *block, 
ram_addr_t addr,
  * In that case just map the requested area.
  */
 if (block->offset == 0) {
-return xen_map_cache(addr, len, lock, lock);
+return xen_map_cache(block->mr, addr, len, lock, lock,
+ is_write);
 }
 
-block->host = xen_map_cache(block->offset, block->max_length, 1, lock);
+block->host = xen_map_cache(block->mr, block->offset,
+block->max_length, 1,
+lock, is_write);
 }
 
 return ramblock_ptr(block, addr);
@@ -2236,7 +2250,7 @@ static void *qemu_ram_ptr_length(RAMBlock *block, 
ram_addr_t addr,
  */
 void *qemu_map_ram_ptr(RAMBlock *ram_block, ram_addr_t addr)
 {
-return qemu_ram_ptr_length(ram_block, addr, NULL, false)

[PATCH v4 09/17] xen: mapcache: Break out xen_invalidate_map_cache_single()

2024-04-30 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Break out xen_invalidate_map_cache_single().

No functional changes.

Signed-off-by: Edgar E. Iglesias 
---
 hw/xen/xen-mapcache.c | 25 +++--
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
index 34454da2f6..dd08cd296b 100644
--- a/hw/xen/xen-mapcache.c
+++ b/hw/xen/xen-mapcache.c
@@ -512,17 +512,14 @@ void coroutine_mixed_fn 
xen_invalidate_map_cache_entry(uint8_t *buffer)
 }
 }
 
-void xen_invalidate_map_cache(void)
+static void xen_invalidate_map_cache_single(MapCache *mc)
 {
 unsigned long i;
 MapCacheRev *reventry;
 
-/* Flush pending AIO before destroying the mapcache */
-bdrv_drain_all();
-
-mapcache_lock(mapcache);
+mapcache_lock(mc);
 
-QTAILQ_FOREACH(reventry, >locked_entries, next) {
+QTAILQ_FOREACH(reventry, >locked_entries, next) {
 if (!reventry->dma) {
 continue;
 }
@@ -530,8 +527,8 @@ void xen_invalidate_map_cache(void)
reventry->vaddr_req);
 }
 
-for (i = 0; i < mapcache->nr_buckets; i++) {
-MapCacheEntry *entry = >entry[i];
+for (i = 0; i < mc->nr_buckets; i++) {
+MapCacheEntry *entry = >entry[i];
 
 if (entry->vaddr_base == NULL) {
 continue;
@@ -552,9 +549,17 @@ void xen_invalidate_map_cache(void)
 entry->valid_mapping = NULL;
 }
 
-mapcache->last_entry = NULL;
+mc->last_entry = NULL;
 
-mapcache_unlock(mapcache);
+mapcache_unlock(mc);
+}
+
+void xen_invalidate_map_cache(void)
+{
+/* Flush pending AIO before destroying the mapcache */
+bdrv_drain_all();
+
+xen_invalidate_map_cache_single(mapcache);
 }
 
 static uint8_t *xen_replace_cache_entry_unlocked(MapCache *mc,
-- 
2.40.1




[PATCH v4 15/17] xen: mapcache: Remove assumption of RAMBlock with 0 offset

2024-04-30 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

The current mapcache assumes that all memory is mapped
in a single RAM MR (the first one with offset 0). Remove
this assumption and propagate the offset to the mapcache
so it can do reverse mappings (from hostptr -> ram_addr).

This is in preparation for adding grant mappings.

Signed-off-by: Edgar E. Iglesias 
---
 hw/xen/xen-mapcache.c | 25 ++---
 include/sysemu/xen-mapcache.h |  2 ++
 system/physmem.c  |  8 
 3 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
index 09b5f36d9c..1b32d0c003 100644
--- a/hw/xen/xen-mapcache.c
+++ b/hw/xen/xen-mapcache.c
@@ -43,6 +43,9 @@ typedef struct MapCacheEntry {
 #define XEN_MAPCACHE_ENTRY_DUMMY (1 << 0)
 uint8_t flags;
 hwaddr size;
+
+/* Keep ram_addr offset for reverse mappings (hostptr -> ram_addr).  */
+ram_addr_t ram_offset;
 struct MapCacheEntry *next;
 } MapCacheEntry;
 
@@ -165,7 +168,8 @@ static void xen_remap_bucket(MapCache *mc,
  void *vaddr,
  hwaddr size,
  hwaddr address_index,
- bool dummy)
+ bool dummy,
+ ram_addr_t ram_offset)
 {
 uint8_t *vaddr_base;
 xen_pfn_t *pfns;
@@ -244,6 +248,7 @@ static void xen_remap_bucket(MapCache *mc,
 entry->size = size;
 entry->valid_mapping = g_new0(unsigned long,
   BITS_TO_LONGS(size >> XC_PAGE_SHIFT));
+entry->ram_offset = ram_offset;
 
 if (dummy) {
 entry->flags |= XEN_MAPCACHE_ENTRY_DUMMY;
@@ -264,6 +269,7 @@ static void xen_remap_bucket(MapCache *mc,
 
 static uint8_t *xen_map_cache_unlocked(MapCache *mc,
hwaddr phys_addr, hwaddr size,
+   ram_addr_t ram_offset,
uint8_t lock, bool dma, bool is_write)
 {
 MapCacheEntry *entry, *pentry = NULL,
@@ -335,14 +341,16 @@ tryagain:
 if (!entry) {
 entry = g_new0(MapCacheEntry, 1);
 pentry->next = entry;
-xen_remap_bucket(mc, entry, NULL, cache_size, address_index, dummy);
+xen_remap_bucket(mc, entry, NULL, cache_size, address_index, dummy,
+ ram_offset);
 } else if (!entry->lock) {
 if (!entry->vaddr_base || entry->paddr_index != address_index ||
 entry->size != cache_size ||
 !test_bits(address_offset >> XC_PAGE_SHIFT,
 test_bit_size >> XC_PAGE_SHIFT,
 entry->valid_mapping)) {
-xen_remap_bucket(mc, entry, NULL, cache_size, address_index, 
dummy);
+xen_remap_bucket(mc, entry, NULL, cache_size, address_index, dummy,
+ ram_offset);
 }
 }
 
@@ -389,13 +397,15 @@ tryagain:
 
 uint8_t *xen_map_cache(MemoryRegion *mr,
hwaddr phys_addr, hwaddr size,
+   ram_addr_t ram_addr_offset,
uint8_t lock, bool dma,
bool is_write)
 {
 uint8_t *p;
 
 mapcache_lock(mapcache);
-p = xen_map_cache_unlocked(mapcache, phys_addr, size, lock, dma, is_write);
+p = xen_map_cache_unlocked(mapcache, phys_addr, size, ram_addr_offset,
+   lock, dma, is_write);
 mapcache_unlock(mapcache);
 return p;
 }
@@ -432,7 +442,8 @@ static ram_addr_t 
xen_ram_addr_from_mapcache_single(MapCache *mc, void *ptr)
 raddr = RAM_ADDR_INVALID;
 } else {
 raddr = (reventry->paddr_index << mc->bucket_shift) +
- ((unsigned long) ptr - (unsigned long) entry->vaddr_base);
+ ((unsigned long) ptr - (unsigned long) entry->vaddr_base) +
+ entry->ram_offset;
 }
 mapcache_unlock(mc);
 return raddr;
@@ -627,8 +638,8 @@ static uint8_t *xen_replace_cache_entry_unlocked(MapCache 
*mc,
 
 trace_xen_replace_cache_entry_dummy(old_phys_addr, new_phys_addr);
 
-xen_remap_bucket(mapcache, entry, entry->vaddr_base,
- cache_size, address_index, false);
+xen_remap_bucket(mc, entry, entry->vaddr_base,
+ cache_size, address_index, false, entry->ram_offset);
 if (!test_bits(address_offset >> XC_PAGE_SHIFT,
 test_bit_size >> XC_PAGE_SHIFT,
 entry->valid_mapping)) {
diff --git a/include/sysemu/xen-mapcache.h b/include/sysemu/xen-mapcache.h
index 1ec9e66752..b5e3ea1bc0 100644
--- a/include/sysemu/xen-mapcache.h
+++ b/include/sysemu/xen-mapcache.h
@@ -19,6 +19,7 @@ typedef hwaddr (*phys_offset_to_gaddr_t)(hwaddr phys_offset,
 void xen_map_cache_init(phys_offset_to_gaddr_t f,
 void *opaque);
 uint8_t

[PATCH v4 05/17] xen: mapcache: Refactor xen_remap_bucket for multi-instance

2024-04-30 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Add MapCache argument to xen_remap_bucket in preparation
to support multiple map caches.

No functional changes.

Signed-off-by: Edgar E. Iglesias 
---
 hw/xen/xen-mapcache.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
index 896021d86f..326a9b61ca 100644
--- a/hw/xen/xen-mapcache.c
+++ b/hw/xen/xen-mapcache.c
@@ -139,7 +139,8 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f, void 
*opaque)
 mapcache->entry = g_malloc0(size);
 }
 
-static void xen_remap_bucket(MapCacheEntry *entry,
+static void xen_remap_bucket(MapCache *mc,
+ MapCacheEntry *entry,
  void *vaddr,
  hwaddr size,
  hwaddr address_index,
@@ -313,14 +314,14 @@ tryagain:
 if (!entry) {
 entry = g_new0(MapCacheEntry, 1);
 pentry->next = entry;
-xen_remap_bucket(entry, NULL, cache_size, address_index, dummy);
+xen_remap_bucket(mc, entry, NULL, cache_size, address_index, dummy);
 } else if (!entry->lock) {
 if (!entry->vaddr_base || entry->paddr_index != address_index ||
 entry->size != cache_size ||
 !test_bits(address_offset >> XC_PAGE_SHIFT,
 test_bit_size >> XC_PAGE_SHIFT,
 entry->valid_mapping)) {
-xen_remap_bucket(entry, NULL, cache_size, address_index, dummy);
+xen_remap_bucket(mc, entry, NULL, cache_size, address_index, 
dummy);
 }
 }
 
@@ -587,7 +588,7 @@ static uint8_t *xen_replace_cache_entry_unlocked(hwaddr 
old_phys_addr,
 
 trace_xen_replace_cache_entry_dummy(old_phys_addr, new_phys_addr);
 
-xen_remap_bucket(entry, entry->vaddr_base,
+xen_remap_bucket(mapcache, entry, entry->vaddr_base,
  cache_size, address_index, false);
 if (!test_bits(address_offset >> XC_PAGE_SHIFT,
 test_bit_size >> XC_PAGE_SHIFT,
-- 
2.40.1




[PATCH v4 07/17] xen: mapcache: Refactor xen_replace_cache_entry_unlocked

2024-04-30 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Add MapCache argument to xen_replace_cache_entry_unlocked in
preparation for supporting multiple map caches.

No functional change.

Signed-off-by: Edgar E. Iglesias 
---
 hw/xen/xen-mapcache.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
index d2deff70c8..6e758eff94 100644
--- a/hw/xen/xen-mapcache.c
+++ b/hw/xen/xen-mapcache.c
@@ -556,7 +556,8 @@ void xen_invalidate_map_cache(void)
 mapcache_unlock(mapcache);
 }
 
-static uint8_t *xen_replace_cache_entry_unlocked(hwaddr old_phys_addr,
+static uint8_t *xen_replace_cache_entry_unlocked(MapCache *mc,
+ hwaddr old_phys_addr,
  hwaddr new_phys_addr,
  hwaddr size)
 {
@@ -578,7 +579,7 @@ static uint8_t *xen_replace_cache_entry_unlocked(hwaddr 
old_phys_addr,
 cache_size += MCACHE_BUCKET_SIZE - (cache_size % MCACHE_BUCKET_SIZE);
 }
 
-entry = >entry[address_index % mapcache->nr_buckets];
+entry = >entry[address_index % mc->nr_buckets];
 while (entry && !(entry->paddr_index == address_index &&
   entry->size == cache_size)) {
 entry = entry->next;
@@ -614,7 +615,8 @@ uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
 uint8_t *p;
 
 mapcache_lock(mapcache);
-p = xen_replace_cache_entry_unlocked(old_phys_addr, new_phys_addr, size);
+p = xen_replace_cache_entry_unlocked(mapcache, old_phys_addr,
+ new_phys_addr, size);
 mapcache_unlock(mapcache);
 return p;
 }
-- 
2.40.1




[PATCH v4 11/17] xen: mapcache: Make MCACHE_BUCKET_SHIFT runtime configurable

2024-04-30 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Make MCACHE_BUCKET_SHIFT runtime configurable per cache instance.

Signed-off-by: Edgar E. Iglesias 
---
 hw/xen/xen-mapcache.c | 52 ++-
 1 file changed, 31 insertions(+), 21 deletions(-)

diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
index 72a7e25e3e..4f98d284dd 100644
--- a/hw/xen/xen-mapcache.c
+++ b/hw/xen/xen-mapcache.c
@@ -23,13 +23,10 @@
 
 
 #if HOST_LONG_BITS == 32
-#  define MCACHE_BUCKET_SHIFT 16
 #  define MCACHE_MAX_SIZE (1UL<<31) /* 2GB Cap */
 #else
-#  define MCACHE_BUCKET_SHIFT 20
 #  define MCACHE_MAX_SIZE (1UL<<35) /* 32GB Cap */
 #endif
-#define MCACHE_BUCKET_SIZE (1UL << MCACHE_BUCKET_SHIFT)
 
 /* This is the size of the virtual address space reserve to QEMU that will not
  * be use by MapCache.
@@ -65,7 +62,8 @@ typedef struct MapCache {
 /* For most cases (>99.9%), the page address is the same. */
 MapCacheEntry *last_entry;
 unsigned long max_mcache_size;
-unsigned int mcache_bucket_shift;
+unsigned int bucket_shift;
+unsigned long bucket_size;
 
 phys_offset_to_gaddr_t phys_offset_to_gaddr;
 QemuMutex lock;
@@ -95,6 +93,7 @@ static inline int test_bits(int nr, int size, const unsigned 
long *addr)
 
 static MapCache *xen_map_cache_init_single(phys_offset_to_gaddr_t f,
void *opaque,
+   unsigned int bucket_shift,
unsigned long max_size)
 {
 unsigned long size;
@@ -108,12 +107,14 @@ static MapCache 
*xen_map_cache_init_single(phys_offset_to_gaddr_t f,
 
 QTAILQ_INIT(>locked_entries);
 
+mc->bucket_shift = bucket_shift;
+mc->bucket_size = 1UL << bucket_shift;
 mc->max_mcache_size = max_size;
 
 mc->nr_buckets =
 (((mc->max_mcache_size >> XC_PAGE_SHIFT) +
-  (1UL << (MCACHE_BUCKET_SHIFT - XC_PAGE_SHIFT)) - 1) >>
- (MCACHE_BUCKET_SHIFT - XC_PAGE_SHIFT));
+  (1UL << (bucket_shift - XC_PAGE_SHIFT)) - 1) >>
+ (bucket_shift - XC_PAGE_SHIFT));
 
 size = mc->nr_buckets * sizeof(MapCacheEntry);
 size = (size + XC_PAGE_SIZE - 1) & ~(XC_PAGE_SIZE - 1);
@@ -126,6 +127,13 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f, void 
*opaque)
 {
 struct rlimit rlimit_as;
 unsigned long max_mcache_size;
+unsigned int bucket_shift;
+
+if (HOST_LONG_BITS == 32) {
+bucket_shift = 16;
+} else {
+bucket_shift = 20;
+}
 
 if (geteuid() == 0) {
 rlimit_as.rlim_cur = RLIM_INFINITY;
@@ -146,7 +154,9 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f, void 
*opaque)
 }
 }
 
-mapcache = xen_map_cache_init_single(f, opaque, max_mcache_size);
+mapcache = xen_map_cache_init_single(f, opaque,
+ bucket_shift,
+ max_mcache_size);
 setrlimit(RLIMIT_AS, _as);
 }
 
@@ -195,7 +205,7 @@ static void xen_remap_bucket(MapCache *mc,
 entry->valid_mapping = NULL;
 
 for (i = 0; i < nb_pfn; i++) {
-pfns[i] = (address_index << (MCACHE_BUCKET_SHIFT-XC_PAGE_SHIFT)) + i;
+pfns[i] = (address_index << (mc->bucket_shift - XC_PAGE_SHIFT)) + i;
 }
 
 /*
@@ -266,8 +276,8 @@ static uint8_t *xen_map_cache_unlocked(MapCache *mc,
 bool dummy = false;
 
 tryagain:
-address_index  = phys_addr >> MCACHE_BUCKET_SHIFT;
-address_offset = phys_addr & (MCACHE_BUCKET_SIZE - 1);
+address_index  = phys_addr >> mc->bucket_shift;
+address_offset = phys_addr & (mc->bucket_size - 1);
 
 trace_xen_map_cache(phys_addr);
 
@@ -294,14 +304,14 @@ tryagain:
 return mc->last_entry->vaddr_base + address_offset;
 }
 
-/* size is always a multiple of MCACHE_BUCKET_SIZE */
+/* size is always a multiple of mc->bucket_size */
 if (size) {
 cache_size = size + address_offset;
-if (cache_size % MCACHE_BUCKET_SIZE) {
-cache_size += MCACHE_BUCKET_SIZE - (cache_size % 
MCACHE_BUCKET_SIZE);
+if (cache_size % mc->bucket_size) {
+cache_size += mc->bucket_size - (cache_size % mc->bucket_size);
 }
 } else {
-cache_size = MCACHE_BUCKET_SIZE;
+cache_size = mc->bucket_size;
 }
 
 entry = >entry[address_index % mc->nr_buckets];
@@ -419,7 +429,7 @@ static ram_addr_t 
xen_ram_addr_from_mapcache_single(MapCache *mc, void *ptr)
 trace_xen_ram_addr_from_mapcache_not_in_cache(ptr);
 raddr = RAM_ADDR_INVALID;
 } else {
-raddr = (reventry->paddr_index << MCACHE_BUCKET_SHIFT) +
+raddr = (reventry->paddr_index << mc->bucket_shift) +
  ((unsigned long) ptr - (unsigned long) entry->vaddr_base);
 }
 mapcache_unlock(mc);
@@ 

[PATCH v4 02/17] xen: let xen_ram_addr_from_mapcache() return -1 in case of not found entry

2024-04-30 Thread Edgar E. Iglesias
From: Juergen Gross 

Today xen_ram_addr_from_mapcache() will either abort() or return 0 in
case it can't find a matching entry for a pointer value. Both cases
are bad, so change that to return an invalid address instead.

Signed-off-by: Juergen Gross 
Signed-off-by: Edgar E. Iglesias 
Reviewed-by: Stefano Stabellini 
Reviewed-by: Alex Bennée 
Reviewed-by: Edgar E. Iglesias 
---
 hw/xen/xen-mapcache.c | 11 +++
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
index 7f59080ba7..b7cefb78f7 100644
--- a/hw/xen/xen-mapcache.c
+++ b/hw/xen/xen-mapcache.c
@@ -394,13 +394,8 @@ ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
 }
 }
 if (!found) {
-trace_xen_ram_addr_from_mapcache_not_found(ptr);
-QTAILQ_FOREACH(reventry, >locked_entries, next) {
-trace_xen_ram_addr_from_mapcache_found(reventry->paddr_index,
-   reventry->vaddr_req);
-}
-abort();
-return 0;
+mapcache_unlock();
+return RAM_ADDR_INVALID;
 }
 
 entry = >entry[paddr_index % mapcache->nr_buckets];
@@ -409,7 +404,7 @@ ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
 }
 if (!entry) {
 trace_xen_ram_addr_from_mapcache_not_in_cache(ptr);
-raddr = 0;
+raddr = RAM_ADDR_INVALID;
 } else {
 raddr = (reventry->paddr_index << MCACHE_BUCKET_SHIFT) +
  ((unsigned long) ptr - (unsigned long) entry->vaddr_base);
-- 
2.40.1




[PATCH v4 16/17] xen: mapcache: Add support for grant mappings

2024-04-30 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Add a second mapcache for grant mappings. The mapcache for
grants needs to work with XC_PAGE_SIZE granularity since
we can't map larger ranges than what has been granted to us.

Like with foreign mappings (xen_memory), machines using grants
are expected to initialize the xen_grants MR and map it
into their address-map accordingly.

Signed-off-by: Edgar E. Iglesias 
---
 hw/xen/xen-hvm-common.c |  12 ++-
 hw/xen/xen-mapcache.c   | 158 +---
 include/hw/xen/xen-hvm-common.h |   3 +
 include/sysemu/xen.h|   7 ++
 4 files changed, 145 insertions(+), 35 deletions(-)

diff --git a/hw/xen/xen-hvm-common.c b/hw/xen/xen-hvm-common.c
index 0267b88d26..fdec400491 100644
--- a/hw/xen/xen-hvm-common.c
+++ b/hw/xen/xen-hvm-common.c
@@ -10,12 +10,18 @@
 #include "hw/boards.h"
 #include "hw/xen/arch_hvm.h"
 
-MemoryRegion xen_memory;
+MemoryRegion xen_memory, xen_grants;
 
-/* Check for xen memory.  */
+/* Check for any kind of xen memory, foreign mappings or grants.  */
 bool xen_mr_is_memory(MemoryRegion *mr)
 {
-return mr == _memory;
+return mr == _memory || mr == _grants;
+}
+
+/* Check specifically for grants.  */
+bool xen_mr_is_grants(MemoryRegion *mr)
+{
+return mr == _grants;
 }
 
 void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr,
diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
index 1b32d0c003..96cd68e28d 100644
--- a/hw/xen/xen-mapcache.c
+++ b/hw/xen/xen-mapcache.c
@@ -14,6 +14,7 @@
 
 #include 
 
+#include "hw/xen/xen-hvm-common.h"
 #include "hw/xen/xen_native.h"
 #include "qemu/bitmap.h"
 
@@ -21,6 +22,8 @@
 #include "sysemu/xen-mapcache.h"
 #include "trace.h"
 
+#include 
+#include 
 
 #if HOST_LONG_BITS == 32
 #  define MCACHE_MAX_SIZE (1UL<<31) /* 2GB Cap */
@@ -41,6 +44,7 @@ typedef struct MapCacheEntry {
 unsigned long *valid_mapping;
 uint32_t lock;
 #define XEN_MAPCACHE_ENTRY_DUMMY (1 << 0)
+#define XEN_MAPCACHE_ENTRY_GRANT (1 << 1)
 uint8_t flags;
 hwaddr size;
 
@@ -74,6 +78,8 @@ typedef struct MapCache {
 } MapCache;
 
 static MapCache *mapcache;
+static MapCache *mapcache_grants;
+static xengnttab_handle *xen_region_gnttabdev;
 
 static inline void mapcache_lock(MapCache *mc)
 {
@@ -132,6 +138,12 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f, void 
*opaque)
 unsigned long max_mcache_size;
 unsigned int bucket_shift;
 
+xen_region_gnttabdev = xengnttab_open(NULL, 0);
+if (xen_region_gnttabdev == NULL) {
+error_report("mapcache: Failed to open gnttab device");
+exit(EXIT_FAILURE);
+}
+
 if (HOST_LONG_BITS == 32) {
 bucket_shift = 16;
 } else {
@@ -160,6 +172,15 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f, void 
*opaque)
 mapcache = xen_map_cache_init_single(f, opaque,
  bucket_shift,
  max_mcache_size);
+
+/*
+ * Grant mappings must use XC_PAGE_SIZE granularity since we can't
+ * map anything beyond the number of pages granted to us.
+ */
+mapcache_grants = xen_map_cache_init_single(f, opaque,
+XC_PAGE_SHIFT,
+max_mcache_size);
+
 setrlimit(RLIMIT_AS, _as);
 }
 
@@ -169,17 +190,25 @@ static void xen_remap_bucket(MapCache *mc,
  hwaddr size,
  hwaddr address_index,
  bool dummy,
+ bool grant,
+ bool grant_is_write,
+ hwaddr grant_ref,
  ram_addr_t ram_offset)
 {
 uint8_t *vaddr_base;
-xen_pfn_t *pfns;
+uint32_t *refs = NULL;
+xen_pfn_t *pfns = NULL;
 int *err;
 unsigned int i;
 hwaddr nb_pfn = size >> XC_PAGE_SHIFT;
 
 trace_xen_remap_bucket(address_index);
 
-pfns = g_new0(xen_pfn_t, nb_pfn);
+if (grant) {
+refs = g_new0(uint32_t, nb_pfn);
+} else {
+pfns = g_new0(xen_pfn_t, nb_pfn);
+}
 err = g_new0(int, nb_pfn);
 
 if (entry->vaddr_base != NULL) {
@@ -208,21 +237,45 @@ static void xen_remap_bucket(MapCache *mc,
 g_free(entry->valid_mapping);
 entry->valid_mapping = NULL;
 
-for (i = 0; i < nb_pfn; i++) {
-pfns[i] = (address_index << (mc->bucket_shift - XC_PAGE_SHIFT)) + i;
+if (grant) {
+for (i = 0; i < nb_pfn; i++) {
+refs[i] = grant_ref + i;
+}
+} else {
+for (i = 0; i < nb_pfn; i++) {
+pfns[i] = (address_index << (mc->bucket_shift - XC_PAGE_SHIFT)) + 
i;
+}
 }
 
-/*
- * If the caller has requested the mapping at a specific address use
- * MAP_FIXED to make sure it's 

[PATCH v4 14/17] xen: Add xen_mr_is_memory()

2024-04-30 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Add xen_mr_is_memory() to abstract away tests for the
xen_memory MR.

Signed-off-by: Edgar E. Iglesias 
---
 hw/xen/xen-hvm-common.c | 8 +++-
 include/sysemu/xen.h| 8 
 system/physmem.c| 2 +-
 3 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/hw/xen/xen-hvm-common.c b/hw/xen/xen-hvm-common.c
index 1627da7398..0267b88d26 100644
--- a/hw/xen/xen-hvm-common.c
+++ b/hw/xen/xen-hvm-common.c
@@ -12,6 +12,12 @@
 
 MemoryRegion xen_memory;
 
+/* Check for xen memory.  */
+bool xen_mr_is_memory(MemoryRegion *mr)
+{
+return mr == _memory;
+}
+
 void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr,
Error **errp)
 {
@@ -28,7 +34,7 @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, 
MemoryRegion *mr,
 return;
 }
 
-if (mr == _memory) {
+if (xen_mr_is_memory(mr)) {
 return;
 }
 
diff --git a/include/sysemu/xen.h b/include/sysemu/xen.h
index 754ec2e6cb..dc72f83bcb 100644
--- a/include/sysemu/xen.h
+++ b/include/sysemu/xen.h
@@ -34,6 +34,8 @@ void xen_hvm_modified_memory(ram_addr_t start, ram_addr_t 
length);
 void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size,
struct MemoryRegion *mr, Error **errp);
 
+bool xen_mr_is_memory(MemoryRegion *mr);
+
 #else /* !CONFIG_XEN_IS_POSSIBLE */
 
 #define xen_enabled() 0
@@ -47,6 +49,12 @@ static inline void xen_ram_alloc(ram_addr_t ram_addr, 
ram_addr_t size,
 g_assert_not_reached();
 }
 
+static inline bool xen_mr_is_memory(MemoryRegion *mr)
+{
+g_assert_not_reached();
+return false;
+}
+
 #endif /* CONFIG_XEN_IS_POSSIBLE */
 
 #endif
diff --git a/system/physmem.c b/system/physmem.c
index ad7a8c7d95..1a5ffcba2a 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -2227,7 +2227,7 @@ static void *qemu_ram_ptr_length(RAMBlock *block, 
ram_addr_t addr,
  * because we don't want to map the entire memory in QEMU.
  * In that case just map the requested area.
  */
-if (block->offset == 0) {
+if (xen_mr_is_memory(block->mr)) {
 return xen_map_cache(block->mr, addr, len, lock, lock,
  is_write);
 }
-- 
2.40.1




[PATCH v4 12/17] xen: mapcache: Unmap first entries in buckets

2024-04-30 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

When invalidating memory ranges, if we happen to hit the first
entry in a bucket we were never unmapping it. This was harmless
for foreign mappings but now that we're looking to reuse the
mapcache for transient grant mappings, we must unmap entries
when invalidated.

Signed-off-by: Edgar E. Iglesias 
---
 hw/xen/xen-mapcache.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
index 4f98d284dd..0365311788 100644
--- a/hw/xen/xen-mapcache.c
+++ b/hw/xen/xen-mapcache.c
@@ -486,18 +486,22 @@ static void 
xen_invalidate_map_cache_entry_unlocked(MapCache *mc,
 return;
 }
 entry->lock--;
-if (entry->lock > 0 || pentry == NULL) {
+if (entry->lock > 0) {
 return;
 }
 
-pentry->next = entry->next;
 ram_block_notify_remove(entry->vaddr_base, entry->size, entry->size);
 if (munmap(entry->vaddr_base, entry->size) != 0) {
 perror("unmap fails");
 exit(-1);
 }
-g_free(entry->valid_mapping);
-g_free(entry);
+if (pentry) {
+pentry->next = entry->next;
+g_free(entry->valid_mapping);
+g_free(entry);
+} else {
+memset(entry, 0, sizeof *entry);
+}
 }
 
 typedef struct XenMapCacheData {
-- 
2.40.1




[PATCH v4 03/17] xen: mapcache: Refactor lock functions for multi-instance

2024-04-30 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Make the lock functions take MapCache * as argument. This is
in preparation for supporting multiple caches.

No functional changes.

Signed-off-by: Edgar E. Iglesias 
---
 hw/xen/xen-mapcache.c | 34 +-
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
index b7cefb78f7..3f11562075 100644
--- a/hw/xen/xen-mapcache.c
+++ b/hw/xen/xen-mapcache.c
@@ -74,14 +74,14 @@ typedef struct MapCache {
 
 static MapCache *mapcache;
 
-static inline void mapcache_lock(void)
+static inline void mapcache_lock(MapCache *mc)
 {
-qemu_mutex_lock(>lock);
+qemu_mutex_lock(>lock);
 }
 
-static inline void mapcache_unlock(void)
+static inline void mapcache_unlock(MapCache *mc)
 {
-qemu_mutex_unlock(>lock);
+qemu_mutex_unlock(>lock);
 }
 
 static inline int test_bits(int nr, int size, const unsigned long *addr)
@@ -369,9 +369,9 @@ uint8_t *xen_map_cache(hwaddr phys_addr, hwaddr size,
 {
 uint8_t *p;
 
-mapcache_lock();
+mapcache_lock(mapcache);
 p = xen_map_cache_unlocked(phys_addr, size, lock, dma);
-mapcache_unlock();
+mapcache_unlock(mapcache);
 return p;
 }
 
@@ -384,7 +384,7 @@ ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
 ram_addr_t raddr;
 int found = 0;
 
-mapcache_lock();
+mapcache_lock(mapcache);
 QTAILQ_FOREACH(reventry, >locked_entries, next) {
 if (reventry->vaddr_req == ptr) {
 paddr_index = reventry->paddr_index;
@@ -394,7 +394,7 @@ ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
 }
 }
 if (!found) {
-mapcache_unlock();
+mapcache_unlock(mapcache);
 return RAM_ADDR_INVALID;
 }
 
@@ -409,7 +409,7 @@ ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
 raddr = (reventry->paddr_index << MCACHE_BUCKET_SHIFT) +
  ((unsigned long) ptr - (unsigned long) entry->vaddr_base);
 }
-mapcache_unlock();
+mapcache_unlock(mapcache);
 return raddr;
 }
 
@@ -480,9 +480,9 @@ static void xen_invalidate_map_cache_entry_bh(void *opaque)
 {
 XenMapCacheData *data = opaque;
 
-mapcache_lock();
+mapcache_lock(mapcache);
 xen_invalidate_map_cache_entry_unlocked(data->buffer);
-mapcache_unlock();
+mapcache_unlock(mapcache);
 
 aio_co_wake(data->co);
 }
@@ -498,9 +498,9 @@ void coroutine_mixed_fn 
xen_invalidate_map_cache_entry(uint8_t *buffer)
 xen_invalidate_map_cache_entry_bh, );
 qemu_coroutine_yield();
 } else {
-mapcache_lock();
+mapcache_lock(mapcache);
 xen_invalidate_map_cache_entry_unlocked(buffer);
-mapcache_unlock();
+mapcache_unlock(mapcache);
 }
 }
 
@@ -512,7 +512,7 @@ void xen_invalidate_map_cache(void)
 /* Flush pending AIO before destroying the mapcache */
 bdrv_drain_all();
 
-mapcache_lock();
+mapcache_lock(mapcache);
 
 QTAILQ_FOREACH(reventry, >locked_entries, next) {
 if (!reventry->dma) {
@@ -546,7 +546,7 @@ void xen_invalidate_map_cache(void)
 
 mapcache->last_entry = NULL;
 
-mapcache_unlock();
+mapcache_unlock(mapcache);
 }
 
 static uint8_t *xen_replace_cache_entry_unlocked(hwaddr old_phys_addr,
@@ -606,8 +606,8 @@ uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
 {
 uint8_t *p;
 
-mapcache_lock();
+mapcache_lock(mapcache);
 p = xen_replace_cache_entry_unlocked(old_phys_addr, new_phys_addr, size);
-mapcache_unlock();
+mapcache_unlock(mapcache);
 return p;
 }
-- 
2.40.1




[PATCH v4 10/17] xen: mapcache: Break out xen_map_cache_init_single()

2024-04-30 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Break out xen_map_cache_init_single() in preparation for
adding multiple map caches.

Signed-off-by: Edgar E. Iglesias 
---
 hw/xen/xen-mapcache.c | 53 ++-
 1 file changed, 32 insertions(+), 21 deletions(-)

diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
index dd08cd296b..72a7e25e3e 100644
--- a/hw/xen/xen-mapcache.c
+++ b/hw/xen/xen-mapcache.c
@@ -93,23 +93,44 @@ static inline int test_bits(int nr, int size, const 
unsigned long *addr)
 return 0;
 }
 
-void xen_map_cache_init(phys_offset_to_gaddr_t f, void *opaque)
+static MapCache *xen_map_cache_init_single(phys_offset_to_gaddr_t f,
+   void *opaque,
+   unsigned long max_size)
 {
 unsigned long size;
-struct rlimit rlimit_as;
+MapCache *mc;
+
+mc = g_new0(MapCache, 1);
+
+mc->phys_offset_to_gaddr = f;
+mc->opaque = opaque;
+qemu_mutex_init(>lock);
+
+QTAILQ_INIT(>locked_entries);
 
-mapcache = g_new0(MapCache, 1);
+mc->max_mcache_size = max_size;
 
-mapcache->phys_offset_to_gaddr = f;
-mapcache->opaque = opaque;
-qemu_mutex_init(>lock);
+mc->nr_buckets =
+(((mc->max_mcache_size >> XC_PAGE_SHIFT) +
+  (1UL << (MCACHE_BUCKET_SHIFT - XC_PAGE_SHIFT)) - 1) >>
+ (MCACHE_BUCKET_SHIFT - XC_PAGE_SHIFT));
 
-QTAILQ_INIT(>locked_entries);
+size = mc->nr_buckets * sizeof(MapCacheEntry);
+size = (size + XC_PAGE_SIZE - 1) & ~(XC_PAGE_SIZE - 1);
+trace_xen_map_cache_init(mc->nr_buckets, size);
+mc->entry = g_malloc0(size);
+return mc;
+}
+
+void xen_map_cache_init(phys_offset_to_gaddr_t f, void *opaque)
+{
+struct rlimit rlimit_as;
+unsigned long max_mcache_size;
 
 if (geteuid() == 0) {
 rlimit_as.rlim_cur = RLIM_INFINITY;
 rlimit_as.rlim_max = RLIM_INFINITY;
-mapcache->max_mcache_size = MCACHE_MAX_SIZE;
+max_mcache_size = MCACHE_MAX_SIZE;
 } else {
 getrlimit(RLIMIT_AS, _as);
 rlimit_as.rlim_cur = rlimit_as.rlim_max;
@@ -119,24 +140,14 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f, void 
*opaque)
 " memory is not infinity");
 }
 if (rlimit_as.rlim_max < MCACHE_MAX_SIZE + NON_MCACHE_MEMORY_SIZE) {
-mapcache->max_mcache_size = rlimit_as.rlim_max -
-NON_MCACHE_MEMORY_SIZE;
+max_mcache_size = rlimit_as.rlim_max - NON_MCACHE_MEMORY_SIZE;
 } else {
-mapcache->max_mcache_size = MCACHE_MAX_SIZE;
+max_mcache_size = MCACHE_MAX_SIZE;
 }
 }
 
+mapcache = xen_map_cache_init_single(f, opaque, max_mcache_size);
 setrlimit(RLIMIT_AS, _as);
-
-mapcache->nr_buckets =
-(((mapcache->max_mcache_size >> XC_PAGE_SHIFT) +
-  (1UL << (MCACHE_BUCKET_SHIFT - XC_PAGE_SHIFT)) - 1) >>
- (MCACHE_BUCKET_SHIFT - XC_PAGE_SHIFT));
-
-size = mapcache->nr_buckets * sizeof (MapCacheEntry);
-size = (size + XC_PAGE_SIZE - 1) & ~(XC_PAGE_SIZE - 1);
-trace_xen_map_cache_init(mapcache->nr_buckets, size);
-mapcache->entry = g_malloc0(size);
 }
 
 static void xen_remap_bucket(MapCache *mc,
-- 
2.40.1




[PATCH v4 06/17] xen: mapcache: Break out xen_ram_addr_from_mapcache_single

2024-04-30 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Break out xen_ram_addr_from_mapcache_single(), a multi-cache
aware version of xen_ram_addr_from_mapcache.

No functional changes.

Signed-off-by: Edgar E. Iglesias 
---
 hw/xen/xen-mapcache.c | 17 +++--
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
index 326a9b61ca..d2deff70c8 100644
--- a/hw/xen/xen-mapcache.c
+++ b/hw/xen/xen-mapcache.c
@@ -377,7 +377,7 @@ uint8_t *xen_map_cache(hwaddr phys_addr, hwaddr size,
 return p;
 }
 
-ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
+static ram_addr_t xen_ram_addr_from_mapcache_single(MapCache *mc, void *ptr)
 {
 MapCacheEntry *entry = NULL;
 MapCacheRev *reventry;
@@ -386,8 +386,8 @@ ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
 ram_addr_t raddr;
 int found = 0;
 
-mapcache_lock(mapcache);
-QTAILQ_FOREACH(reventry, >locked_entries, next) {
+mapcache_lock(mc);
+QTAILQ_FOREACH(reventry, >locked_entries, next) {
 if (reventry->vaddr_req == ptr) {
 paddr_index = reventry->paddr_index;
 size = reventry->size;
@@ -396,11 +396,11 @@ ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
 }
 }
 if (!found) {
-mapcache_unlock(mapcache);
+mapcache_unlock(mc);
 return RAM_ADDR_INVALID;
 }
 
-entry = >entry[paddr_index % mapcache->nr_buckets];
+entry = >entry[paddr_index % mc->nr_buckets];
 while (entry && (entry->paddr_index != paddr_index || entry->size != 
size)) {
 entry = entry->next;
 }
@@ -411,10 +411,15 @@ ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
 raddr = (reventry->paddr_index << MCACHE_BUCKET_SHIFT) +
  ((unsigned long) ptr - (unsigned long) entry->vaddr_base);
 }
-mapcache_unlock(mapcache);
+mapcache_unlock(mc);
 return raddr;
 }
 
+ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
+{
+return xen_ram_addr_from_mapcache_single(mapcache, ptr);
+}
+
 static void xen_invalidate_map_cache_entry_unlocked(uint8_t *buffer)
 {
 MapCacheEntry *entry = NULL, *pentry = NULL;
-- 
2.40.1




[PATCH v4 08/17] xen: mapcache: Refactor xen_invalidate_map_cache_entry_unlocked

2024-04-30 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Add MapCache argument to xen_invalidate_map_cache_entry_unlocked.
This is in preparation for supporting multiple map caches.

No functional changes.

Signed-off-by: Edgar E. Iglesias 
---
 hw/xen/xen-mapcache.c | 21 +++--
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
index 6e758eff94..34454da2f6 100644
--- a/hw/xen/xen-mapcache.c
+++ b/hw/xen/xen-mapcache.c
@@ -420,7 +420,8 @@ ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
 return xen_ram_addr_from_mapcache_single(mapcache, ptr);
 }
 
-static void xen_invalidate_map_cache_entry_unlocked(uint8_t *buffer)
+static void xen_invalidate_map_cache_entry_unlocked(MapCache *mc,
+uint8_t *buffer)
 {
 MapCacheEntry *entry = NULL, *pentry = NULL;
 MapCacheRev *reventry;
@@ -428,7 +429,7 @@ static void xen_invalidate_map_cache_entry_unlocked(uint8_t 
*buffer)
 hwaddr size;
 int found = 0;
 
-QTAILQ_FOREACH(reventry, >locked_entries, next) {
+QTAILQ_FOREACH(reventry, >locked_entries, next) {
 if (reventry->vaddr_req == buffer) {
 paddr_index = reventry->paddr_index;
 size = reventry->size;
@@ -438,7 +439,7 @@ static void xen_invalidate_map_cache_entry_unlocked(uint8_t 
*buffer)
 }
 if (!found) {
 trace_xen_invalidate_map_cache_entry_unlocked_not_found(buffer);
-QTAILQ_FOREACH(reventry, >locked_entries, next) {
+QTAILQ_FOREACH(reventry, >locked_entries, next) {
 trace_xen_invalidate_map_cache_entry_unlocked_found(
 reventry->paddr_index,
 reventry->vaddr_req
@@ -446,15 +447,15 @@ static void 
xen_invalidate_map_cache_entry_unlocked(uint8_t *buffer)
 }
 return;
 }
-QTAILQ_REMOVE(>locked_entries, reventry, next);
+QTAILQ_REMOVE(>locked_entries, reventry, next);
 g_free(reventry);
 
-if (mapcache->last_entry != NULL &&
-mapcache->last_entry->paddr_index == paddr_index) {
-mapcache->last_entry = NULL;
+if (mc->last_entry != NULL &&
+mc->last_entry->paddr_index == paddr_index) {
+mc->last_entry = NULL;
 }
 
-entry = >entry[paddr_index % mapcache->nr_buckets];
+entry = >entry[paddr_index % mc->nr_buckets];
 while (entry && (entry->paddr_index != paddr_index || entry->size != 
size)) {
 pentry = entry;
 entry = entry->next;
@@ -488,7 +489,7 @@ static void xen_invalidate_map_cache_entry_bh(void *opaque)
 XenMapCacheData *data = opaque;
 
 mapcache_lock(mapcache);
-xen_invalidate_map_cache_entry_unlocked(data->buffer);
+xen_invalidate_map_cache_entry_unlocked(mapcache, data->buffer);
 mapcache_unlock(mapcache);
 
 aio_co_wake(data->co);
@@ -506,7 +507,7 @@ void coroutine_mixed_fn 
xen_invalidate_map_cache_entry(uint8_t *buffer)
 qemu_coroutine_yield();
 } else {
 mapcache_lock(mapcache);
-xen_invalidate_map_cache_entry_unlocked(buffer);
+xen_invalidate_map_cache_entry_unlocked(mapcache, buffer);
 mapcache_unlock(mapcache);
 }
 }
-- 
2.40.1




[PATCH v4 04/17] xen: mapcache: Refactor xen_map_cache for multi-instance

2024-04-30 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Make xen_map_cache take a MapCache as argument. This is in
prepaparation to support multiple map caches.

No functional changes.

Signed-off-by: Edgar E. Iglesias 
---
 hw/xen/xen-mapcache.c | 35 ++-
 1 file changed, 18 insertions(+), 17 deletions(-)

diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
index 3f11562075..896021d86f 100644
--- a/hw/xen/xen-mapcache.c
+++ b/hw/xen/xen-mapcache.c
@@ -240,7 +240,8 @@ static void xen_remap_bucket(MapCacheEntry *entry,
 g_free(err);
 }
 
-static uint8_t *xen_map_cache_unlocked(hwaddr phys_addr, hwaddr size,
+static uint8_t *xen_map_cache_unlocked(MapCache *mc,
+   hwaddr phys_addr, hwaddr size,
uint8_t lock, bool dma)
 {
 MapCacheEntry *entry, *pentry = NULL,
@@ -269,16 +270,16 @@ tryagain:
 test_bit_size = XC_PAGE_SIZE;
 }
 
-if (mapcache->last_entry != NULL &&
-mapcache->last_entry->paddr_index == address_index &&
+if (mc->last_entry != NULL &&
+mc->last_entry->paddr_index == address_index &&
 !lock && !size &&
 test_bits(address_offset >> XC_PAGE_SHIFT,
   test_bit_size >> XC_PAGE_SHIFT,
-  mapcache->last_entry->valid_mapping)) {
+  mc->last_entry->valid_mapping)) {
 trace_xen_map_cache_return(
-mapcache->last_entry->vaddr_base + address_offset
+mc->last_entry->vaddr_base + address_offset
 );
-return mapcache->last_entry->vaddr_base + address_offset;
+return mc->last_entry->vaddr_base + address_offset;
 }
 
 /* size is always a multiple of MCACHE_BUCKET_SIZE */
@@ -291,7 +292,7 @@ tryagain:
 cache_size = MCACHE_BUCKET_SIZE;
 }
 
-entry = >entry[address_index % mapcache->nr_buckets];
+entry = >entry[address_index % mc->nr_buckets];
 
 while (entry && (lock || entry->lock) && entry->vaddr_base &&
 (entry->paddr_index != address_index || entry->size != cache_size 
||
@@ -326,10 +327,10 @@ tryagain:
 if(!test_bits(address_offset >> XC_PAGE_SHIFT,
 test_bit_size >> XC_PAGE_SHIFT,
 entry->valid_mapping)) {
-mapcache->last_entry = NULL;
+mc->last_entry = NULL;
 #ifdef XEN_COMPAT_PHYSMAP
-if (!translated && mapcache->phys_offset_to_gaddr) {
-phys_addr = mapcache->phys_offset_to_gaddr(phys_addr, size);
+if (!translated && mc->phys_offset_to_gaddr) {
+phys_addr = mc->phys_offset_to_gaddr(phys_addr, size);
 translated = true;
 goto tryagain;
 }
@@ -342,7 +343,7 @@ tryagain:
 return NULL;
 }
 
-mapcache->last_entry = entry;
+mc->last_entry = entry;
 if (lock) {
 MapCacheRev *reventry = g_new0(MapCacheRev, 1);
 entry->lock++;
@@ -352,16 +353,16 @@ tryagain:
 abort();
 }
 reventry->dma = dma;
-reventry->vaddr_req = mapcache->last_entry->vaddr_base + 
address_offset;
-reventry->paddr_index = mapcache->last_entry->paddr_index;
+reventry->vaddr_req = mc->last_entry->vaddr_base + address_offset;
+reventry->paddr_index = mc->last_entry->paddr_index;
 reventry->size = entry->size;
-QTAILQ_INSERT_HEAD(>locked_entries, reventry, next);
+QTAILQ_INSERT_HEAD(>locked_entries, reventry, next);
 }
 
 trace_xen_map_cache_return(
-mapcache->last_entry->vaddr_base + address_offset
+mc->last_entry->vaddr_base + address_offset
 );
-return mapcache->last_entry->vaddr_base + address_offset;
+return mc->last_entry->vaddr_base + address_offset;
 }
 
 uint8_t *xen_map_cache(hwaddr phys_addr, hwaddr size,
@@ -370,7 +371,7 @@ uint8_t *xen_map_cache(hwaddr phys_addr, hwaddr size,
 uint8_t *p;
 
 mapcache_lock(mapcache);
-p = xen_map_cache_unlocked(phys_addr, size, lock, dma);
+p = xen_map_cache_unlocked(mapcache, phys_addr, size, lock, dma);
 mapcache_unlock(mapcache);
 return p;
 }
-- 
2.40.1




Re: [RFC PATCH v1 1/2] xen/arm64: entry: Use xen/linkage.h to annotate symbols

2024-04-18 Thread Edgar E. Iglesias
On Thu, Apr 18, 2024 at 8:10 AM Jan Beulich  wrote:
>
> On 10.04.2024 12:24, Edgar E. Iglesias wrote:
> > On Wed, Apr 10, 2024 at 12:21 PM Andrew Cooper 
> > wrote:
> >
> >> On 10/04/2024 10:19 am, Edgar E. Iglesias wrote:
> >>> From: "Edgar E. Iglesias" 
> >>>
> >>> Use the generic xen/linkage.h macros when annotating symbols.
> >>>
> >>> Signed-off-by: Edgar E. Iglesias 
> >>> ---
> >>>  xen/arch/arm/arm64/entry.S | 12 ++--
> >>>  1 file changed, 6 insertions(+), 6 deletions(-)
> >>>
> >>> diff --git a/xen/arch/arm/arm64/entry.S b/xen/arch/arm/arm64/entry.S
> >>> index f963c923bb..6188dd2416 100644
> >>> --- a/xen/arch/arm/arm64/entry.S
> >>> +++ b/xen/arch/arm/arm64/entry.S
> >>> @@ -480,9 +480,9 @@ guest_fiq_invalid_compat:
> >>>  guest_error_compat:
> >>>  guest_vector compat=1, iflags=IFLAGS__AI_, trap=guest_serror
> >>>
> >>> -ENTRY(return_to_new_vcpu32)
> >>> +FUNC(return_to_new_vcpu32)
> >>>  exithyp=0, compat=1
> >>
> >> In the new world, you want an END() too, which sets the size of the symbol.
> >>
> >> A good cross-check of this annotation stuff is:
> >>
> >> readelf -Wa xen-syms | grep return_to_new_vcpu32
> >>
> >> which in this case will tell you that the symbol called
> >> return_to_new_vcpu32 still has a size of 0.
> >
> > Patch 2/2 adds the END, I should probably have squashed them into one...
>
> Only partly afaics: return_to_new_vcpu{32,64} are still left without. And
> yes, preferably the adjustments to the start annotation for a symbol
> would come with an END() addition right away.
>

Thanks Jan,

Yes, in v2 I've squashed the patches into one to avoid confusion:
https://patchew.org/Xen/20240415231541.4140052-1-edgar.igles...@gmail.com/

Here's the hunk in patch 2/2 of the first v1 RFC submission that added
the END's to return_to_new_vcpuXX:
https://lists.xenproject.org/archives/html/xen-devel/2024-04/msg00505.html

FUNC(return_to_new_vcpu32)
 exithyp=0, compat=1
+END(return_to_new_vcpu32)
+
 FUNC(return_to_new_vcpu64)
 exithyp=0, compat=0
+END(return_to_new_vcpu64)

Cheers,
Edgar



[PATCH v2 1/1] xen/arm64: entry: Add missing code symbol annotations

2024-04-16 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Use the generic xen/linkage.h macros when and add missing
code symbol annotations.

Signed-off-by: Edgar E. Iglesias 
---
 xen/arch/arm/arm64/entry.S | 72 +-
 1 file changed, 48 insertions(+), 24 deletions(-)

diff --git a/xen/arch/arm/arm64/entry.S b/xen/arch/arm/arm64/entry.S
index f963c923bb..af9a592cae 100644
--- a/xen/arch/arm/arm64/entry.S
+++ b/xen/arch/arm/arm64/entry.S
@@ -289,21 +289,25 @@
 b   do_bad_mode
 .endm
 
-hyp_sync_invalid:
+FUNC_LOCAL(hyp_sync_invalid)
 entry   hyp=1
 invalid BAD_SYNC
+END(hyp_sync_invalid)
 
-hyp_irq_invalid:
+FUNC_LOCAL(hyp_irq_invalid)
 entry   hyp=1
 invalid BAD_IRQ
+END(hyp_irq_invalid)
 
-hyp_fiq_invalid:
+FUNC_LOCAL(hyp_fiq_invalid)
 entry   hyp=1
 invalid BAD_FIQ
+END(hyp_fiq_invalid)
 
-hyp_error_invalid:
+FUNC_LOCAL(hyp_error_invalid)
 entry   hyp=1
 invalid BAD_ERROR
+END(hyp_error_invalid)
 
 /*
  * SError received while running in the hypervisor mode.
@@ -313,11 +317,12 @@ hyp_error_invalid:
  * simplicity, as SError should be rare and potentially fatal,
  * all interrupts are kept masked.
  */
-hyp_error:
+FUNC_LOCAL(hyp_error)
 entry   hyp=1
 mov x0, sp
 bl  do_trap_hyp_serror
 exithyp=1
+END(hyp_error)
 
 /*
  * Synchronous exception received while running in the hypervisor mode.
@@ -327,7 +332,7 @@ hyp_error:
  * some of them. So we want to inherit the state from the interrupted
  * context.
  */
-hyp_sync:
+FUNC_LOCAL(hyp_sync)
 entry   hyp=1
 
 /* Inherit interrupts */
@@ -338,6 +343,7 @@ hyp_sync:
 mov x0, sp
 bl  do_trap_hyp_sync
 exithyp=1
+END(hyp_sync)
 
 /*
  * IRQ received while running in the hypervisor mode.
@@ -352,7 +358,7 @@ hyp_sync:
  * would require some rework in some paths (e.g. panic, livepatch) to
  * ensure the ordering is enforced everywhere.
  */
-hyp_irq:
+FUNC_LOCAL(hyp_irq)
 entry   hyp=1
 
 /* Inherit D, A, F interrupts and keep I masked */
@@ -365,8 +371,9 @@ hyp_irq:
 mov x0, sp
 bl  do_trap_irq
 exithyp=1
+END(hyp_irq)
 
-guest_sync:
+FUNC_LOCAL(guest_sync)
 /*
  * Save x0, x1 in advance
  */
@@ -413,8 +420,9 @@ fastpath_out_workaround:
 mov x1, xzr
 eret
 sb
+END(guest_sync)
 
-wa2_ssbd:
+FUNC_LOCAL(wa2_ssbd)
 #ifdef CONFIG_ARM_SSBD
 alternative_cb arm_enable_wa2_handling
 b   wa2_end
@@ -450,42 +458,55 @@ wa2_end:
 mov x0, xzr
 eret
 sb
-guest_sync_slowpath:
+END(wa2_ssbd)
+
+FUNC_LOCAL(guest_sync_slowpath)
 /*
  * x0/x1 may have been scratch by the fast path above, so avoid
  * to save them.
  */
 guest_vector compat=0, iflags=IFLAGS__AI_, trap=guest_sync, 
save_x0_x1=0
+END(guest_sync_slowpath)
 
-guest_irq:
+FUNC_LOCAL(guest_irq)
 guest_vector compat=0, iflags=IFLAGS__A__, trap=irq
+END(guest_irq)
 
-guest_fiq_invalid:
+FUNC_LOCAL(guest_fiq_invalid)
 entry   hyp=0, compat=0
 invalid BAD_FIQ
+END(guest_fiq_invalid)
 
-guest_error:
+FUNC_LOCAL(guest_error)
 guest_vector compat=0, iflags=IFLAGS__AI_, trap=guest_serror
+END(guest_error)
 
-guest_sync_compat:
+FUNC_LOCAL(guest_sync_compat)
 guest_vector compat=1, iflags=IFLAGS__AI_, trap=guest_sync
+END(guest_sync_compat)
 
-guest_irq_compat:
+FUNC_LOCAL(guest_irq_compat)
 guest_vector compat=1, iflags=IFLAGS__A__, trap=irq
+END(guest_irq_compat)
 
-guest_fiq_invalid_compat:
+FUNC_LOCAL(guest_fiq_invalid_compat)
 entry   hyp=0, compat=1
 invalid BAD_FIQ
+END(guest_fiq_invalid_compat)
 
-guest_error_compat:
+FUNC_LOCAL(guest_error_compat)
 guest_vector compat=1, iflags=IFLAGS__AI_, trap=guest_serror
+END(guest_error_compat)
 
-ENTRY(return_to_new_vcpu32)
+FUNC(return_to_new_vcpu32)
 exithyp=0, compat=1
-ENTRY(return_to_new_vcpu64)
+END(return_to_new_vcpu32)
+
+FUNC(return_to_new_vcpu64)
 exithyp=0, compat=0
+END(return_to_new_vcpu64)
 
-return_from_trap:
+FUNC_LOCAL(return_from_trap)
 msr daifset, #IFLAGS___I_ /* Mask interrupts */
 
 ldr x21, [sp, #UREGS_PC]/* load ELR */
@@ -524,6 +545,7 @@ return_from_trap:
 
 eret
 sb
+END(return_from_trap)
 
 /*
  * Consume pending SError generated by the guest if any.
@@ -536,7 +558,7 @@ return_from_trap:
  * it. So the function will unmask SError exception for a small window and
  * then mask it again.
  */
-check_pending_guest_serror:
+FUNC_LOCAL(check_pending_guest_serror)
 /*
  * Save elr_el2 to check whether the pending SError exception takes
  * place while we are doing this sync exception.
@@ -586,7 +608,7 @@ abort_guest_exit_end:
 csetx19, ne
 
 ret
-ENDPROC(check_pending_guest_serror)
+END(check_pending_gu

[PATCH v2 0/1] xen/arm: Annotate code symbols

2024-04-16 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

On the way towards Xen safety certification we're evaluating the use
of tools to collect code-coverage/profiling information from execution
traces. Some tools rely on ELF symbols for code being declared with
type FUNC and having a symbol size.

We currently annotate some symbols but not all. Also, there seems to be
different ways to do the annotation so I'm sending out this series to
first figure out how we want to do things before I go ahead and edit
more of the ARM port.

In this first try I've followed the style from commit:
b3a9037550 x86: annotate entry points with type and size
IIUC, prefering to use macros from the generic framework in
xen/linkage.h in favor of ENTRY/ENDPROC.

But perhaps we would like to keep using ENTRY() for entry points
into the hypervisor?
Another way could be to add .type name, %function to the ENTRY macro
and use END from xen/linkage.h.

Or we can keep using ENTRY/GLOBAL/ENDPROC.

Any thoughts or better ideas?

Best regards,
Edgar

ChangeLog:
v1 -> v2:
* Drop RFC.
* Squash into a single patch to avoid confusion.


Edgar E. Iglesias (1):
  xen/arm64: entry: Add missing code symbol annotations

 xen/arch/arm/arm64/entry.S | 72 +-
 1 file changed, 48 insertions(+), 24 deletions(-)

-- 
2.40.1




Re: [VirtIO] Support for various devices in Xen

2024-04-12 Thread Edgar E. Iglesias
On Fri, Apr 12, 2024 at 1:23 AM Stefano Stabellini
 wrote:
>
> -Vikram +Edgar
>
> On Thu, 11 Apr 2024, Andrei Cherechesu wrote:
> > Hi Stefano, Vikram, Viresh,
> >
> > Thank you for your answers and support, and sorry for my late reply.
> >
> >
> > On 12/01/2024 02:56, Vikram Garhwal wrote:
> > > Hi Andrei & Stefano,
> > >
> > > Actually, QEMU patches are already upstreamed for virtio-blk and 
> > > virtio-net
> > > devices available in v8.2.0.
> > > For virtio with grants, the patches are WiP.
> > >
> > > On Xen side, we are yet to upstream xen-tools patches which basically 
> > > generate
> > > the right arguments when invoking QEMU.
> > > Here are down stream patches if you want:
> > > 1. 
> > > https://github.com/Xilinx/xen/commit/be35b46e907c7c78fd23888d837475eb28334638
> > > 2. For Virtio disk backend:
> > > 
> > > https://github.com/Xilinx/xen/commit/947280803294bbb963f428423f679d074c60d632
> > > 3. For Virtio-net:
> > > 
> > > https://github.com/Xilinx/xen/commit/32fcc702718591270e5c8928b7687d853249c882
> > > 4. For changing the machine name to Xenpvh(to align with QEMU changes):
> > > 
> > > https://github.com/Xilinx/xen/commit/5f669949c9ffdb1947cb47038956b5fb8eeb072a
> > >> The libxl changes are lagging behind a bit and you might have to use
> > >> device_model_args to enable virtio backends in QEMU.
> > > But QEMU 8.2.0 can still be used for virtio-net on ARM.
> > >
> > > @Andrei here is an example on how to use virtio-net with QEMU:
> > > -device virtio-net-device,id=nic0,netdev=net0,mac=00:16:3e:4f:43:05 \
> > > -netdev 
> > > type=tap,id=net0,ifname=vif1.0-emu,br=xenbr0,script=no,downscript=no\
> > > -machine xenpvh
> > >
> > > Please make sure to use xenpvh as QEMU machine.
> >
> > I've managed to successfully get a DomU up and running with the rootfs 
> > based on virtio-blk. I'm running QEMU 8.2.1, Xen 4.18 + Vikram's downstream 
> > patches, Linux 6.6.12-rt, built through yocto with some changes to 
> > xen-tools and QEMU recipes.
> >
> > However, when also enabling PV networking through virtio-net, it seems that 
> > DomU cannot successfully boot. The device model args passed by xen-tools 
> > when invoking QEMU look exactly like what Vikram said they should.
> >
> > While executing `xl -v create ..` I can see some error regarding the device 
> > model crashing:
> >
> > libxl: debug: libxl_exec.c:127:libxl_report_child_exitstatus: 
> > domain 1 device model (dying as expected) [300] died due to fatal signal 
> > Killed
> >
> > But the error is not fatal and the DomU spawn goes on, it boots but never 
> > reaches prompt. It seems that kernel crashes silently at some point. 
> > Though, the networking interface is present since udev tries to rename it 
> > right before boot hangs:
> >
> > [4.376715] vif vif-0 enX0: renamed from eth1
> >
> > Why would the QEMU DM process be killed, though? Invalid memory access?
> >
> > Here are the full logs for the "xl create" command [0] and for DomU's dmesg 
> > [1].
> > Any ideas as to why that might happen, some debugging insights, or maybe 
> > some configuration details I could have overlooked?
> >
> > Thank you very much for your help once again.

Hi Andrei,

I'll share some info about my setup:
I'm using:

Xen upstream/master + virtio patches that Vikram shared
Commit 63f66058b5 on this repo/branch:
https://github.com/edgarigl/xen/tree/edgar/virtio-base

QEMU 02e16ab9f4 upstream/master
Linux 09e5c48fea17 upstream/master (from March)
Yocto rootfs.

I had a look at your logs but I can't tell why it's failing on your side.
I've not tried using a virtio-blk as a rootfs on my side, perhaps related.
It would be useful to see a diff of your Xen tree compared to plain
4.18 or whatever base you've got.
You probably don't have
https://github.com/edgarigl/xen/commit/63f66058b508180107963ea37217bc88d813df8f
but if that was the problem, I'd thought virtio wouldn't work at all
with your kernel it could also be related.

My guest config looks like this:
name = "g0"
memory = 1024
vcpus = 1
kernel = "Image"
ramdisk = "core-image-minimal-qemuarm64.rootfs.cpio.gz"
extra = "root=/dev/ram0 console=ttyAMA0"
vif = [ 'model=virtio-net,type=ioemu,bridge=xenbr0' ]
disk = [ '/etc/xen/file.img,,xvda,backendtype=qdisk,specification=virtio' ]

xl launches QEMU with the following args:
/usr/bin/qemu-system-aarch64 -xen-domid 1 -no-shutdown -chardev
socket,id=libxl-cmd,path=/var/run/xen/qmp-libxl-1,server=on,wait=off
-mon chardev=libxl-cmd,mode=control -chardev
socket,id=libxenstat-cmd,path=/var/run/xen/qmp-libxenstat-1,server=on,wait=off
-mon chardev=libxenstat-cmd,mode=control -nodefaults -no-user-config
-xen-attach -name g0 -vnc none -display none -nographic -global
virtio-mmio.force-legacy=false -device
virtio-net-device,id=nic0,netdev=net0,mac=00:16:3e:13:86:9c,iommu_platform=on
-netdev type=tap,id=net0,ifname=vif1.0-emu,br=xenbr0,script=no,downscript=no
-machine xenpvh -m 1024 -device

Re: [QEMU][PATCH v3 4/7] xen: let xen_ram_addr_from_mapcache() return -1 in case of not found entry

2024-04-10 Thread Edgar E. Iglesias
On Fri, Mar 1, 2024 at 6:08 PM Alex Bennée  wrote:

> Vikram Garhwal  writes:
>
> > From: Juergen Gross 
> >
> > Today xen_ram_addr_from_mapcache() will either abort() or return 0 in
> > case it can't find a matching entry for a pointer value. Both cases
> > are bad, so change that to return an invalid address instead.
> >
> > Signed-off-by: Juergen Gross 
> > Reviewed-by: Stefano Stabellini 
> > ---
> >  hw/xen/xen-mapcache.c | 11 +++
> >  1 file changed, 3 insertions(+), 8 deletions(-)
> >
> > diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
> > index dfc412d138..179b7e95b2 100644
> > --- a/hw/xen/xen-mapcache.c
> > +++ b/hw/xen/xen-mapcache.c
> > @@ -396,13 +396,8 @@ ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
> >  }
> >  }
> >  if (!found) {
> > -trace_xen_ram_addr_from_mapcache_not_found(ptr);
> > -QTAILQ_FOREACH(reventry, >locked_entries, next) {
> > -
> trace_xen_ram_addr_from_mapcache_found(reventry->paddr_index,
> > -   reventry->vaddr_req);
> > -}
>
> If these tracepoints aren't useful they need removing from trace-events.
> However I suspect it would be better to keep them in as they are fairly
> cheap.
>
> Otherwise:
>
> Reviewed-by: Alex Bennée 
>
>
Reviewed-by: Edgar E. Iglesias 


Re: [QEMU][PATCH v3 2/7] xen: add pseudo RAM region for grant mappings

2024-04-10 Thread Edgar E. Iglesias
On Fri, Mar 1, 2024 at 3:06 PM Alex Bennée  wrote:

> Vikram Garhwal  writes:
>
> > From: Juergen Gross 
> >
> > Add a memory region which can be used to automatically map granted
> > memory. It is starting at 0x8000ULL in order to be able to
> > distinguish it from normal RAM.
>
> Is the Xen memory map for HVM guests documented anywhere? I couldn't
> find anything googling or on the Xen wiki. I'm guessing this is going to
> be shared across all 64 bit HVM arches in Xen?
>
> Anyway:
>
> Reviewed-by: Alex Bennée 
>
>
Reviewed-by: Edgar E. Iglesias 


Re: [QEMU][PATCH v3 6/7] xen: add map and unmap callbacks for grant region

2024-04-10 Thread Edgar E. Iglesias
On Fri, Mar 1, 2024 at 12:34 AM Stefano Stabellini 
wrote:

> On Tue, 27 Feb 2024, Vikram Garhwal wrote:
> > From: Juergen Gross 
> >
> > Add the callbacks for mapping/unmapping guest memory via grants to the
> > special grant memory region.
> >
> > Signed-off-by: Juergen Gross 
> > Signed-off-by: Vikram Garhwal 
>
> Reviewed-by: Stefano Stabellini 
>
>
Reviewed-by: Edgar E. Iglesias 


Re: [RFC PATCH v1 1/2] xen/arm64: entry: Use xen/linkage.h to annotate symbols

2024-04-10 Thread Edgar E. Iglesias
On Wed, Apr 10, 2024 at 12:21 PM Andrew Cooper 
wrote:

> On 10/04/2024 10:19 am, Edgar E. Iglesias wrote:
> > From: "Edgar E. Iglesias" 
> >
> > Use the generic xen/linkage.h macros when annotating symbols.
> >
> > Signed-off-by: Edgar E. Iglesias 
> > ---
> >  xen/arch/arm/arm64/entry.S | 12 ++--
> >  1 file changed, 6 insertions(+), 6 deletions(-)
> >
> > diff --git a/xen/arch/arm/arm64/entry.S b/xen/arch/arm/arm64/entry.S
> > index f963c923bb..6188dd2416 100644
> > --- a/xen/arch/arm/arm64/entry.S
> > +++ b/xen/arch/arm/arm64/entry.S
> > @@ -480,9 +480,9 @@ guest_fiq_invalid_compat:
> >  guest_error_compat:
> >  guest_vector compat=1, iflags=IFLAGS__AI_, trap=guest_serror
> >
> > -ENTRY(return_to_new_vcpu32)
> > +FUNC(return_to_new_vcpu32)
> >  exithyp=0, compat=1
>
> In the new world, you want an END() too, which sets the size of the symbol.
>
> A good cross-check of this annotation stuff is:
>
> readelf -Wa xen-syms | grep return_to_new_vcpu32
>
> which in this case will tell you that the symbol called
> return_to_new_vcpu32 still has a size of 0.
>

Thanks Andrew,

Patch 2/2 adds the END, I should probably have squashed them into one...

Best regards,
Edgar


[RFC PATCH v1 0/2] xen/arm: Annotate code symbols

2024-04-10 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

On the way towards Xen safety certification we're evaluating the use
of tools to collect code-coverage/profiling information from execution
traces. Some tools rely on ELF symbols for code being declared with
type FUNC and having a symbol size.

We currently annotate some symbols but not all. Also, there seems to be
different ways to do the annotation so I'm sending out this RFC to first
figure out how we want to do things before I go ahead and edit more
of the ARM port.

In this first try I've followed the style from commit:
b3a9037550 x86: annotate entry points with type and size
IIUC, prefering to use macros from the generic framework in
xen/linkage.h in favor of ENTRY/ENDPROC.

But perhaps we would like to keep using ENTRY() for entry points
into the hypervisor?
Another way could be to add .type name, %function to the ENTRY macro
and use END from xen/linkage.h.

Or we can keep using ENTRY/GLOBAL/ENDPROC.

Any thoughts or better ideas?

Best regards,
Edgar

Edgar E. Iglesias (2):
  xen/arm64: entry: Use xen/linkage.h to annotate symbols
  xen/arm64: entry: Add missing code symbol annotations

 xen/arch/arm/arm64/entry.S | 72 +-
 1 file changed, 48 insertions(+), 24 deletions(-)

-- 
2.40.1




[RFC PATCH v1 2/2] xen/arm64: entry: Add missing code symbol annotations

2024-04-10 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Add missing code symbol annotations.

Signed-off-by: Edgar E. Iglesias 
---
 xen/arch/arm/arm64/entry.S | 60 ++
 1 file changed, 42 insertions(+), 18 deletions(-)

diff --git a/xen/arch/arm/arm64/entry.S b/xen/arch/arm/arm64/entry.S
index 6188dd2416..af9a592cae 100644
--- a/xen/arch/arm/arm64/entry.S
+++ b/xen/arch/arm/arm64/entry.S
@@ -289,21 +289,25 @@
 b   do_bad_mode
 .endm
 
-hyp_sync_invalid:
+FUNC_LOCAL(hyp_sync_invalid)
 entry   hyp=1
 invalid BAD_SYNC
+END(hyp_sync_invalid)
 
-hyp_irq_invalid:
+FUNC_LOCAL(hyp_irq_invalid)
 entry   hyp=1
 invalid BAD_IRQ
+END(hyp_irq_invalid)
 
-hyp_fiq_invalid:
+FUNC_LOCAL(hyp_fiq_invalid)
 entry   hyp=1
 invalid BAD_FIQ
+END(hyp_fiq_invalid)
 
-hyp_error_invalid:
+FUNC_LOCAL(hyp_error_invalid)
 entry   hyp=1
 invalid BAD_ERROR
+END(hyp_error_invalid)
 
 /*
  * SError received while running in the hypervisor mode.
@@ -313,11 +317,12 @@ hyp_error_invalid:
  * simplicity, as SError should be rare and potentially fatal,
  * all interrupts are kept masked.
  */
-hyp_error:
+FUNC_LOCAL(hyp_error)
 entry   hyp=1
 mov x0, sp
 bl  do_trap_hyp_serror
 exithyp=1
+END(hyp_error)
 
 /*
  * Synchronous exception received while running in the hypervisor mode.
@@ -327,7 +332,7 @@ hyp_error:
  * some of them. So we want to inherit the state from the interrupted
  * context.
  */
-hyp_sync:
+FUNC_LOCAL(hyp_sync)
 entry   hyp=1
 
 /* Inherit interrupts */
@@ -338,6 +343,7 @@ hyp_sync:
 mov x0, sp
 bl  do_trap_hyp_sync
 exithyp=1
+END(hyp_sync)
 
 /*
  * IRQ received while running in the hypervisor mode.
@@ -352,7 +358,7 @@ hyp_sync:
  * would require some rework in some paths (e.g. panic, livepatch) to
  * ensure the ordering is enforced everywhere.
  */
-hyp_irq:
+FUNC_LOCAL(hyp_irq)
 entry   hyp=1
 
 /* Inherit D, A, F interrupts and keep I masked */
@@ -365,8 +371,9 @@ hyp_irq:
 mov x0, sp
 bl  do_trap_irq
 exithyp=1
+END(hyp_irq)
 
-guest_sync:
+FUNC_LOCAL(guest_sync)
 /*
  * Save x0, x1 in advance
  */
@@ -413,8 +420,9 @@ fastpath_out_workaround:
 mov x1, xzr
 eret
 sb
+END(guest_sync)
 
-wa2_ssbd:
+FUNC_LOCAL(wa2_ssbd)
 #ifdef CONFIG_ARM_SSBD
 alternative_cb arm_enable_wa2_handling
 b   wa2_end
@@ -450,42 +458,55 @@ wa2_end:
 mov x0, xzr
 eret
 sb
-guest_sync_slowpath:
+END(wa2_ssbd)
+
+FUNC_LOCAL(guest_sync_slowpath)
 /*
  * x0/x1 may have been scratch by the fast path above, so avoid
  * to save them.
  */
 guest_vector compat=0, iflags=IFLAGS__AI_, trap=guest_sync, 
save_x0_x1=0
+END(guest_sync_slowpath)
 
-guest_irq:
+FUNC_LOCAL(guest_irq)
 guest_vector compat=0, iflags=IFLAGS__A__, trap=irq
+END(guest_irq)
 
-guest_fiq_invalid:
+FUNC_LOCAL(guest_fiq_invalid)
 entry   hyp=0, compat=0
 invalid BAD_FIQ
+END(guest_fiq_invalid)
 
-guest_error:
+FUNC_LOCAL(guest_error)
 guest_vector compat=0, iflags=IFLAGS__AI_, trap=guest_serror
+END(guest_error)
 
-guest_sync_compat:
+FUNC_LOCAL(guest_sync_compat)
 guest_vector compat=1, iflags=IFLAGS__AI_, trap=guest_sync
+END(guest_sync_compat)
 
-guest_irq_compat:
+FUNC_LOCAL(guest_irq_compat)
 guest_vector compat=1, iflags=IFLAGS__A__, trap=irq
+END(guest_irq_compat)
 
-guest_fiq_invalid_compat:
+FUNC_LOCAL(guest_fiq_invalid_compat)
 entry   hyp=0, compat=1
 invalid BAD_FIQ
+END(guest_fiq_invalid_compat)
 
-guest_error_compat:
+FUNC_LOCAL(guest_error_compat)
 guest_vector compat=1, iflags=IFLAGS__AI_, trap=guest_serror
+END(guest_error_compat)
 
 FUNC(return_to_new_vcpu32)
 exithyp=0, compat=1
+END(return_to_new_vcpu32)
+
 FUNC(return_to_new_vcpu64)
 exithyp=0, compat=0
+END(return_to_new_vcpu64)
 
-return_from_trap:
+FUNC_LOCAL(return_from_trap)
 msr daifset, #IFLAGS___I_ /* Mask interrupts */
 
 ldr x21, [sp, #UREGS_PC]/* load ELR */
@@ -524,6 +545,7 @@ return_from_trap:
 
 eret
 sb
+END(return_from_trap)
 
 /*
  * Consume pending SError generated by the guest if any.
@@ -617,6 +639,7 @@ FUNC(hyp_traps_vector)
 ventry  guest_irq_compat/* IRQ 32-bit EL0/EL1 */
 ventry  guest_fiq_invalid_compat/* FIQ 32-bit EL0/EL1 */
 ventry  guest_error_compat  /* Error 32-bit EL0/EL1 */
+END(hyp_traps_vector)
 
 /*
  * struct vcpu *__context_switch(struct vcpu *prev, struct vcpu *next)
@@ -647,6 +670,7 @@ FUNC(__context_switch)
 ldr lr, [x8]
 mov sp, x9
 ret
+END(__context_switch)
 
 /*
  * Local variables:
-- 
2.40.1




[RFC PATCH v1 1/2] xen/arm64: entry: Use xen/linkage.h to annotate symbols

2024-04-10 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Use the generic xen/linkage.h macros when annotating symbols.

Signed-off-by: Edgar E. Iglesias 
---
 xen/arch/arm/arm64/entry.S | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/xen/arch/arm/arm64/entry.S b/xen/arch/arm/arm64/entry.S
index f963c923bb..6188dd2416 100644
--- a/xen/arch/arm/arm64/entry.S
+++ b/xen/arch/arm/arm64/entry.S
@@ -480,9 +480,9 @@ guest_fiq_invalid_compat:
 guest_error_compat:
 guest_vector compat=1, iflags=IFLAGS__AI_, trap=guest_serror
 
-ENTRY(return_to_new_vcpu32)
+FUNC(return_to_new_vcpu32)
 exithyp=0, compat=1
-ENTRY(return_to_new_vcpu64)
+FUNC(return_to_new_vcpu64)
 exithyp=0, compat=0
 
 return_from_trap:
@@ -536,7 +536,7 @@ return_from_trap:
  * it. So the function will unmask SError exception for a small window and
  * then mask it again.
  */
-check_pending_guest_serror:
+FUNC_LOCAL(check_pending_guest_serror)
 /*
  * Save elr_el2 to check whether the pending SError exception takes
  * place while we are doing this sync exception.
@@ -586,7 +586,7 @@ abort_guest_exit_end:
 csetx19, ne
 
 ret
-ENDPROC(check_pending_guest_serror)
+END(check_pending_guest_serror)
 
 /*
  * Exception vectors.
@@ -597,7 +597,7 @@ ENDPROC(check_pending_guest_serror)
 .endm
 
 .align  11
-ENTRY(hyp_traps_vector)
+FUNC(hyp_traps_vector)
 ventry  hyp_sync_invalid/* Synchronous EL2t */
 ventry  hyp_irq_invalid /* IRQ EL2t */
 ventry  hyp_fiq_invalid /* FIQ EL2t */
@@ -626,7 +626,7 @@ ENTRY(hyp_traps_vector)
  *
  * Returns prev in x0
  */
-ENTRY(__context_switch)
+FUNC(__context_switch)
 add x8, x0, #VCPU_arch_saved_context
 mov x9, sp
 stp x19, x20, [x8], #16 /* store callee-saved registers */
-- 
2.40.1




Re: [PATCH] xen/arm32: SPSR_hyp/SPSR

2021-06-09 Thread Edgar E. Iglesias
On Wed, Jun 09, 2021 at 06:53:02PM +0100, Julien Grall wrote:
> Hi Stefano,
> 
> On 09/06/2021 18:43, Stefano Stabellini wrote:
> > SPSR_hyp is not meant to be accessed from Hyp mode (EL2); accesses
> > trigger UNPREDICTABLE behaviour. Xen should read/write SPSR instead.
> 
> Please provide a reference to the spec. This helps reviewer and/or future
> developper to figure out quickly where this comes from.
> 
> > 
> > This fixes booting Xen/arm32 on QEMU.
> > 
> > Signed-off-by: Stefano Stabellini 
> 
> With the reference added:
> 
> Reviewed-by: Julien Grall 

Reviewed-by: Edgar E. Iglesias 
Tested-by: Edgar E. Iglesias 

Cheers,
Edgar




Re: [Xen-devel] [Qemu-devel] [qemu-s390x] [PATCH v7 33/42] exec: Replace device_endian with MemOp

2019-08-19 Thread Edgar E. Iglesias
On Mon, 19 Aug. 2019, 23:01 Richard Henderson, 
wrote:

> On 8/19/19 11:29 AM, Paolo Bonzini wrote:
> > On 19/08/19 20:28, Paolo Bonzini wrote:
> >> On 16/08/19 12:12, Thomas Huth wrote:
> >>> This patch is *huge*, more than 800kB. It keeps being stuck in the the
> >>> filter of the qemu-s390x list each time you send it. Please:
> >>>
> >>> 1) Try to break it up in more digestible pieces, e.g. change only one
> >>> subsystem at a time (this is also better reviewable by people who are
> >>> interested in one area)
> >>
> >> This is not really possible, since the patch is basically a
> >> search-and-replace.  You could perhaps use some magic
> >> ("DEVICE_MEMOP_ENDIAN" or something like that) to allow a split, but it
> >> would introduce more complication than anything else.
> >
> > I'm stupid, at this point of the series it _would_ be possible to split
> > the patch by subsystem.  Still not sure it would be actually an
> advantage.
>
> It might be easier to review if we split by symbol, one rename per patch
> over
> the entire code base.
>
>
> r~
>

Or if we review your script (I assume this wasn't a manual change). I'm not
sure it's realistic to have review on the entire patch or patches.

Best regards,
Edgar

>
___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

Re: [Xen-devel] [PATCH RFC 03/15] xen/arm: extend device tree based multiboot protocol

2018-07-03 Thread Edgar E. Iglesias
Hi, Sorry for the top post (I'm not managing todo in line reply with my
phone).

Yes, in the long run it there are some benefits if the format could be kept
similar when possible. We could reuse some of the documentation and perhaps
some of the code to parse. Allthough I'm guessing that most of the xl
parsing is not readily reusable from the hypervisor itself.

On the other hand, perhaps the xl format parser is too complex and not
something we would like be reused from within the hypervisor itself?
Considering that one of the use cases for dom0 less is certification.

So an alternative if we don't try to reuse the xl format as much as
possible could be to create a new syntax that is as easy as possible to
parse.

I'm not very convinced on what path is best at the moment.

Regarding strings vs dtb numbers with cells, don't we already have a
generic dtb function that parses numbers and considers the #cells that
could be reused?

Best regards,
Edgar

On Tue, Jul 3, 2018, 06:32 Stefano Stabellini 
wrote:

> On Thu, 14 Jun 2018, Julien Grall wrote:
> > Hi Stefano,
> >
> > On 13/06/18 23:15, Stefano Stabellini wrote:
> > > Extend the existing device tree based multiboot protocol to include
> > > information regarding other domUs to boot.
> > >
> > > Signed-off-by: Stefano Stabellini 
> > > ---
> > >   docs/misc/arm/device-tree/booting.txt | 102
> > > ++
> > >   1 file changed, 102 insertions(+)
> > >
> > > diff --git a/docs/misc/arm/device-tree/booting.txt
> > > b/docs/misc/arm/device-tree/booting.txt
> > > index ce2d0dc..95255e5 100644
> > > --- a/docs/misc/arm/device-tree/booting.txt
> > > +++ b/docs/misc/arm/device-tree/booting.txt
> > > @@ -119,3 +119,105 @@ For those you would hardcode the Xen commandline
> in
> > > the DTB under
> > >   line by writing bootargs (as for native Linux).
> > >   A Xen-aware bootloader would set xen,xen-bootargs for Xen,
> > > xen,dom0-bootargs
> > >   for Dom0 and bootargs for native Linux.
> > > +
> > > +
> > > +Creating DomUs directly from Xen
> > > +
> > > +
> > > +It is possible to have Xen create other domains, in addition to dom0,
> > > +out of the information provided via device tree. A Kernel and initrd
> >
> > NIT: s/Kernel/kernel/
>
> OK
>
>
> > > +(optional) need to be specified for each guest.
> > > +
> > > +For each DomU to be created there needs to be one node under /chosen
> > > +with the following properties:
> >
> > I think it would be better to make this domain agnostic. I.e allow Dom0
> to be
> > created the same way but still supporting the current bindings.
> >
> > We could differentiate Dom0 from the other with a property
> > "xen,initial-domain". Note that I am not asking to add this property in
> this
> > series. This is more a forward looking of the use of this binding.
>
> It sounds like a good idea, I'll add it.
>
>
> > > +
> > > +- compatible
> > > +
> > > +"xen,domU"
> >
> > If we follow my suggestion, this would be renamed "xen,domain".
>
> OK
>
>
> > > +
> > > +- mem (optional)
> >
> > I would prefer the full name "memory".
>
> Yes, especially given that the corresponding xl config file option is
> called "memory".
>
>
> > > +
> > > +A string specifying the amount of RAM to allocate to the guest. If
> > > +not specified it defaults to "64M". The format of the string is
> the
> > > same
> > > +as the one for the mem= parameter in xl config files.
> >
> > I don't much like default values because they are pretty arbitrary. This
> also
> > does not match the default value for Dom0. Why don't you mandate the
> property?
>
> Yes, I can do that.
>
>
> > I would also prefer if the size is specified in the same way number are
> > described in Device-Tree. I.e using cells. You could impose 2 cells for
> the
> > size here.
>
> see below
>
>
> > > +
> > > +- cpus (optional)
> > > +
> > > +A string specifying the number of vcpus to allocate to the guest.
> If
> > > +not specified it defaults to "1".
> >
> > Same remarks as for "mem".
>
> I think it would be nicer if we kept the same format used for xl config
> files for these two options. Especially given that we already have the
> functions in the hypervisor to parse them (Xen knows how to parse
> dom0_max_vcpus and dom0_mem for instance). It is going to be easier to
> use and it doesn't come with a cost for Xen.
>
> Edgar, what do you think?
>
>
> > > +
> > > +- #address-cells and #size-cells
> > > +
> > > +Both #address-cells and #size-cells need to be specified because
> > > +both sub-nodes (described shortly) have reg properties.
> > > +
> > > +Under the "xen,domU" compatible node, one or more sub-nodes are
> present
> > > +for the DomU kernel and ramdisk.
> > > +
> > > +The kernel sub-node has the following properties:
> > > +
> > > +- compatible
> > > +
> > > +"multiboot,domU-kernel"
> >
> > I don't think we need to specify a new compatible here. We could re-use
> > "multiboot,kernel" here because the 

Re: [Xen-devel] [PATCH RFC 00/15] dom0less step1: boot multiple domains from device tree

2018-06-14 Thread Edgar E. Iglesias
On Wed, Jun 13, 2018 at 03:15:09PM -0700, Stefano Stabellini wrote:
> Hi all,
> 
> This is first step toward "dom0less" as discussed in the various
> certifications related threads and discussions.
> 
> The goal of this series is to enable Xen to boot multiple domains in
> parallel, in addition to dom0, out of information found on device tree.
> 
> The device tree based boot protocol is extended to carry information
> about DomUs. Based on that information, Xen creates and starts one or
> more DomUs. DomUs created this way don't have access to xenstore, as
> xenstore is not started yet. This is actually OK, because this is meant
> for mission critical applications that typically only access directly
> assigned devices. They cannot tolerate interference or increased IRQ
> latency due to PV protocols. Device assignment is not actually covered
> by this series, it will be added later.
> 
> DomUs can print to the Xen serial using the CONSOLEIO hypercalls. A
> virtual PL011 is also emulated for them so that they can use their
> regular PL011 driver. This allows unmodified guests to run as Xen on ARM
> guests -- no Xen support needed at all. Console input also comes from
> the Xen serial: the Ctrl-AAA switching mechanism is extended to switch
> among domUs, dom0, and Xen.

Hi Stefano,

I think this looks very promising!

A question, do you have any thoughts on how we in the long run could
try to keep xl configs somewhat on par with the format here?

Or would the device-tree naming of options eventually have to diverge.

Eventually we'll need support for describing arbitrary memory maps and
device passthrough via device-tree for these domUs.

Thanks & Best regards,
Edgar


> 
> Cheers,
> 
> Stefano
> 
> 
> Stefano Stabellini (15):
>   xen: allow console_io hypercalls from DomUs on ARM
>   xen/arm: move a few guest related #defines to public/arch-arm.h
>   xen/arm: extend device tree based multiboot protocol
>   xen/arm: do not pass dt_host to make_memory_node and 
> make_hypervisor_node
>   xen/arm: rename acpi_make_chosen_node to make_chosen_node
>   xen/arm: add BOOTMOD_DOMU_KERNEL/RAMDISK
>   xen/arm: increase MAX_MODULES
>   xen/arm: probe domU kernels and initrds
>   xen/arm: refactor construct_dom0
>   xen/arm: introduce construct_domU
>   xen/arm: generate a simple device tree for domUs
>   xen/arm: generate vpl011 node on device tree for domU
>   xen/arm: Allow vpl011 to be used by DomU
>   xen/arm: call construct_domU from start_xen and start DomU VMs
>   xen: support console_switching between Dom0 and DomUs on ARM
> 
>  docs/misc/arm/device-tree/booting.txt | 102 +++
>  tools/libxl/libxl_arm.c   |  26 --
>  xen/arch/arm/bootfdt.c|   4 +
>  xen/arch/arm/domain_build.c   | 533 
> +++---
>  xen/arch/arm/kernel.c |  54 
>  xen/arch/arm/kernel.h |   2 +
>  xen/arch/arm/setup.c  |  52 +++-
>  xen/arch/arm/vpl011.c |  98 +--
>  xen/common/device_tree.c  |   6 +-
>  xen/drivers/char/console.c|  51 +++-
>  xen/include/asm-arm/setup.h   |  10 +-
>  xen/include/asm-arm/vpl011.h  |   2 +
>  xen/include/asm-x86/setup.h   |   2 +
>  xen/include/public/arch-arm.h |  26 ++
>  xen/include/xen/device_tree.h |   2 +-
>  15 files changed, 789 insertions(+), 181 deletions(-)
> 
> ___
> Xen-devel mailing list
> Xen-devel@lists.xenproject.org
> https://lists.xenproject.org/mailman/listinfo/xen-devel

___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

Re: [Xen-devel] [RFC v2] xen/arm: Suspend to RAM Support in Xen for ARM

2018-03-26 Thread Edgar E. Iglesias
On Mon, Mar 26, 2018 at 09:51:40AM +, Peng Fan wrote:
> Hi Mirela,
> 
> Good to know that you are working suspend/resume support. Currently we are 
> also trying
> to support this on i.MX8, just wonder do you have any open source available to
> support suspend to ram?
> 
> > +
> > +Suspend to RAM (in the following text 'suspend') for ARM in Xen should
> > +be coordinated using ARM PSCI standard [1].
> > +
> > +Ideally, EL1/2 should suspend in the following order:
> > +1) Unprivileged guests (DomUs) suspend
> > +2) Privileged guest (Dom0) suspends
> > +3) Xen suspends
> > +
> > +However, suspending unprivileged guests is not mandatory for suspending
> > +Dom0 and Xen. System suspend initiated by Dom0 (step 2) is considered
> > +to be an ultimate decision to suspend the physical machine. Suspending
> > +of Xen (step 3) is triggered whenever Dom0 completes suspend. Xen
> > +suspend leads to the full suspend of EL2.
> > +
> > +If an unprivileged guest is not suspended at the moment when Dom0
> > +initiates its own suspend, the guest will be paused on Xen's suspend
> > +and unpaused on Xen's resume. That way, a guest which doesn't have
> > +power management support cannot prevent the physical system from
> > +suspending when the decision to suspend is made by privileged software
> > (Dom0).
> > +
> > +Each guest in the system is responsible for suspending the devices it owns.
> > +If a guest does not suspend a device, the device will continue to
> > +operate as it is configured at the moment when the system suspends. If
> > +a device triggers an interrupt while the physical system is suspended, the
> > system will resume.
> > +
> > +It is recommended for an unprivileged guest to participate in power
> > +management in the following scenario:
> > +Assume unprivileged guest owns a device which will trigger interrupt at
> > +some point. This interrupt will wake-up the system. If such a behavior
> > +is not wanted, coordination between Dom0 and the guest is required in
> > +order to inform the guest about the intended physical system suspend.
> > +Then, the guest will have a chance to suspend the device or respond to the
> > request in an abort fashion.
> > +
> > +Since this proposal is focused on implementing PSCI-based suspend
> > +mechanisms in Xen, communication with or among the guests is not covered by
> > this document.
> > +The order of suspending the guests is assumed to be guaranteed by the
> > +software running in EL1.
> > +
> > +This document covers the following:
> > +1) Mechanism for suspending/resuming a guest:
> > +   1.1) Suspend is initiated by the guest
> > +   1.2) Resume is initiated by a device interrupt
> > +2) Mechanism for pausing/unpausing running guests when Dom0 suspends
> 
> Will this take care of passthroughed devices for DomU?

Hi Peng,

The ZynqMP uses the EEMI Firmware interface to do power-management.
https://www.xilinx.com/support/documentation/user_guides/ug1200-eemi-api.pdf

In our case, we've implemented an EEMI mediator in Xen that traps EEMI
requests from domU's and makes sure that the guest owns the device it
is trying to operate on.
https://github.com/Xilinx/xen/blob/xilinx/stable-4.9/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c

So domU will first issue the usual EEMI calls as it would in a non-virtualized
case to suspend all it's devices. Once that has happened, the guest will issue
PSCI calls to suspend the VM. So, Mirela please shim in if I missed something.

The EEMI mediator has been posted to the ML but is currently sitting in our
tree waiting for us to go through the upstreaming effort.

Cheers,
Edgar




> 
> Thanks,
> Peng.
> 
> > +3) Mechanism for suspending/resuming Xen when Dom0 completes suspend
> > +4) Resuming from any state on a wake-up event (device interrupt):
> > +   4.1) Resume DomU on wake-up event when Dom0 is still running
> > +   4.2) Resume DomU on wake-up event when Xen is suspended
> > +   4.3) Resume Dom0 on wake-up event
> > +
> > +Mechanisms enumerated above will allow different kind of policies and
> > +coordination among guests to be implemented in EL1. That is out of the
> > +scope of this document.
> > +
> > +-
> > +Suspending Guests
> > +-
> > +
> > +Suspend procedure for a guest consists of the following:
> > +1) Suspending devices
> > +2) Suspending non-boot CPUs (based on hotplug/PSCI)
> > +3) System suspend, performed by the boot CPU
> > +
> > +Each guest should suspend the devices it owns just like it would when
> > +running without Xen.
> > +
> > +Guests should suspend their non-boot vCPUs using the hotplug mechanism.
> > +Virtual CPUs should be put offline using the already implemented PSCI
> > +vCPU_OFF call (prefix 'v' is added to distinguish PSCI calls made by
> > +guests to Xen, which affect virtual machines; as opposed to PSCI calls
> > +made by Xen to the EL3, which can affect power state of the physical
> > machine).
> > +
> > +After suspending its non-boot vCPUs a guest should finalize 

  1   2   >