Re: [PATCH 1/2] riscv: zicond: make non-experimental

2023-08-24 Thread Vineet Gupta




On 8/10/23 10:14, Alistair Francis wrote:

On Tue, Aug 8, 2023 at 2:18 PM Vineet Gupta  wrote:

zicond is now codegen supported in both llvm and gcc.

This change allows seamless enabling/testing of zicond in downstream
projects. e.g. currently riscv-gnu-toolchain parses elf attributes
to create a cmdline for qemu but fails short of enabling it because of
the "x-" prefix.

Signed-off-by: Vineet Gupta 

Reviewed-by: Alistair Francis 

Alistair


Gentle ping to remind that this lands in some -next tree and not forgotten !

Thx,
-Vineet




---
  target/riscv/cpu.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 6b93b04453c8..022bd9d01223 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1816,6 +1816,7 @@ static Property riscv_cpu_extensions[] = {
  DEFINE_PROP_BOOL("zcf", RISCVCPU, cfg.ext_zcf, false),
  DEFINE_PROP_BOOL("zcmp", RISCVCPU, cfg.ext_zcmp, false),
  DEFINE_PROP_BOOL("zcmt", RISCVCPU, cfg.ext_zcmt, false),
+DEFINE_PROP_BOOL("zicond", RISCVCPU, cfg.ext_zicond, false),

  /* Vendor-specific custom extensions */
  DEFINE_PROP_BOOL("xtheadba", RISCVCPU, cfg.ext_xtheadba, false),
@@ -1832,7 +1833,6 @@ static Property riscv_cpu_extensions[] = {
  DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, 
false),

  /* These are experimental so mark with 'x-' */
-DEFINE_PROP_BOOL("x-zicond", RISCVCPU, cfg.ext_zicond, false),

  /* ePMP 0.9.3 */
  DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
--
2.34.1







Re: [PATCH v2] linux-user: ppoll: eliminate large alloca

2023-08-24 Thread Philippe Mathieu-Daudé

On 24/8/23 19:51, Michael Tokarev wrote:

do_ppoll() in linux-user/syscall.c uses alloca() to
allocate an array of struct pullfds on the stack.
The only upper boundary for number of entries for this
array is so that whole thing fits in INT_MAX. But this
is definitely too much for a stack allocation.  Use
heap allocation instead.

This, together with previous patch for getgroups(),
eliminates all large on-stack allocations from
qemu-user/syscall.c. What's left are actually small
ones.

While at it, also fix missing unlock_user() in two
places, and consolidate target_to_host_timespec*()
calls into time64?_timespec():_timespec64() construct.

Signed-off-by: Michael Tokarev 
---
v1: 
https://patchwork.ozlabs.org/project/qemu-devel/patch/20221216192220.2881898-1-...@msgid.tls.msk.ru/
v2: remove alloca() optimization for smaller number of fds

  linux-user/syscall.c | 45 
  1 file changed, 20 insertions(+), 25 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 9353268cc1..e79594bcd5 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -1487,14 +1487,12 @@ static abi_long do_pselect6(abi_long arg1, abi_long 
arg2, abi_long arg3,
  static abi_long do_ppoll(abi_long arg1, abi_long arg2, abi_long arg3,
   abi_long arg4, abi_long arg5, bool ppoll, bool 
time64)
  {
-struct target_pollfd *target_pfd;
+struct target_pollfd *target_pfd = NULL;
  unsigned int nfds = arg2;
-struct pollfd *pfd;
+struct pollfd *pfd = NULL;
  unsigned int i;
  abi_long ret;
  
-pfd = NULL;

-target_pfd = NULL;
  if (nfds) {
  if (nfds > (INT_MAX / sizeof(struct target_pollfd))) {
  return -TARGET_EINVAL;
@@ -1505,7 +1503,11 @@ static abi_long do_ppoll(abi_long arg1, abi_long arg2, 
abi_long arg3,
  return -TARGET_EFAULT;
  }
  
-pfd = alloca(sizeof(struct pollfd) * nfds);

+pfd = g_try_new(struct pollfd, nfds);
+if (!pfd) {
+ret = -TARGET_ENOMEM;
+goto out;
+}
  for (i = 0; i < nfds; i++) {
  pfd[i].fd = tswap32(target_pfd[i].fd);
  pfd[i].events = tswap16(target_pfd[i].events);
@@ -1516,16 +1518,11 @@ static abi_long do_ppoll(abi_long arg1, abi_long arg2, 
abi_long arg3,
  sigset_t *set = NULL;
  
  if (arg3) {

-if (time64) {
-if (target_to_host_timespec64(timeout_ts, arg3)) {
-unlock_user(target_pfd, arg1, 0);


So this changes unlock(sz=0) ...


-return -TARGET_EFAULT;
-}
-} else {
-if (target_to_host_timespec(timeout_ts, arg3)) {
-unlock_user(target_pfd, arg1, 0);
-return -TARGET_EFAULT;
-}
+if (time64
+? target_to_host_timespec64(timeout_ts, arg3)
+: target_to_host_timespec(timeout_ts, arg3)) {
+ret = -TARGET_EFAULT;
+goto out;


... to unlock(sz=pollfd*nfds). Is that also part of your
"While at it" comment?

Having one patch for each logical change eases review /
cherry-pick / backport.


  }
  } else {
  timeout_ts = NULL;
@@ -1534,8 +1531,7 @@ static abi_long do_ppoll(abi_long arg1, abi_long arg2, 
abi_long arg3,
  if (arg4) {
  ret = process_sigsuspend_mask(, arg4, arg5);
  if (ret != 0) {
-unlock_user(target_pfd, arg1, 0);


(Ditto)


-return ret;
+goto out;
  }
  }
  
@@ -1546,14 +1542,11 @@ static abi_long do_ppoll(abi_long arg1, abi_long arg2, abi_long arg3,

  finish_sigsuspend_mask(ret);
  }
  if (!is_error(ret) && arg3) {
-if (time64) {
-if (host_to_target_timespec64(arg3, timeout_ts)) {
-return -TARGET_EFAULT;
-}
-} else {
-if (host_to_target_timespec(arg3, timeout_ts)) {
-return -TARGET_EFAULT;
-}
+if (time64
+? host_to_target_timespec64(arg3, timeout_ts)
+: host_to_target_timespec(arg3, timeout_ts)) {
+ret = -TARGET_EFAULT;
+goto out;
  }
  }
  } else {
@@ -1576,6 +1569,8 @@ static abi_long do_ppoll(abi_long arg1, abi_long arg2, 
abi_long arg3,
  target_pfd[i].revents = tswap16(pfd[i].revents);
  }
  }
+out:
+g_free(pfd);
  unlock_user(target_pfd, arg1, sizeof(struct target_pollfd) * nfds);
  return ret;
  }





Re: [PATCH] hw/usb/hcd-xhci: Avoid variable-length array in xhci_get_port_bandwidth()

2023-08-24 Thread Philippe Mathieu-Daudé

On 24/8/23 18:48, Peter Maydell wrote:

In xhci_get_port_bandwidth(), we use a variable-length array to
construct the buffer to send back to the guest. Avoid the VLA
by using dma_memory_set() to directly request the memory system
to fill the guest memory with a string of '80's.

The codebase has very few VLAs, and if we can get rid of them all we
can make the compiler error on new additions.  This is a defensive
measure against security bugs where an on-stack dynamic allocation
isn't correctly size-checked (e.g.  CVE-2021-3527).

Signed-off-by: Peter Maydell 
---
Use of dma_memory_set() is a suggestion from RTH from Philippe's
original attempt.  If we ever do anything about the "use real
values" TODO we'll need to do something else (eg heap-allocated
array), but since we haven't done so since the code was written
in 2012 it doesn't seem very likely we'll ever do so.
---
  hw/usb/hcd-xhci.c | 10 --
  1 file changed, 4 insertions(+), 6 deletions(-)


Thanks!

Reviewed-by: Philippe Mathieu-Daudé 



Re: [PATCH v12 0/9] rutabaga_gfx + gfxstream

2023-08-24 Thread Akihiko Odaki

On 2023/08/25 8:40, Gurchetan Singh wrote:

From: Gurchetan Singh 

Prior versions:

Changes since v11:
- Incorporated review feedback

How to build both rutabaga and gfxstream guest/host libs:

https://crosvm.dev/book/appendix/rutabaga_gfx.html

Branch containing this patch series (now on QEMU Gitlab):

https://gitlab.com/gurchetansingh/qemu/-/commits/qemu-gfxstream-v12

Antonio Caggiano (2):
   virtio-gpu: CONTEXT_INIT feature
   virtio-gpu: blob prep

Dr. David Alan Gilbert (1):
   virtio: Add shared memory capability

Gerd Hoffmann (1):
   virtio-gpu: hostmem

Gurchetan Singh (5):
   gfxstream + rutabaga prep: added need defintions, fields, and options
   gfxstream + rutabaga: add initial support for gfxstream
   gfxstream + rutabaga: meson support
   gfxstream + rutabaga: enable rutabaga
   docs/system: add basic virtio-gpu documentation

  docs/system/device-emulation.rst |1 +
  docs/system/devices/virtio-gpu.rst   |  112 +++
  hw/display/meson.build   |   22 +
  hw/display/virtio-gpu-base.c |6 +-
  hw/display/virtio-gpu-pci-rutabaga.c |   47 ++
  hw/display/virtio-gpu-pci.c  |   14 +
  hw/display/virtio-gpu-rutabaga.c | 1119 ++
  hw/display/virtio-gpu.c  |   16 +-
  hw/display/virtio-vga-rutabaga.c |   50 ++
  hw/display/virtio-vga.c  |   33 +-
  hw/virtio/virtio-pci.c   |   18 +
  include/hw/virtio/virtio-gpu-bswap.h |   15 +
  include/hw/virtio/virtio-gpu.h   |   41 +
  include/hw/virtio/virtio-pci.h   |4 +
  meson.build  |7 +
  meson_options.txt|2 +
  scripts/meson-buildoptions.sh|3 +
  softmmu/qdev-monitor.c   |3 +
  softmmu/vl.c |1 +
  19 files changed, 1495 insertions(+), 19 deletions(-)
  create mode 100644 docs/system/devices/virtio-gpu.rst
  create mode 100644 hw/display/virtio-gpu-pci-rutabaga.c
  create mode 100644 hw/display/virtio-gpu-rutabaga.c
  create mode 100644 hw/display/virtio-vga-rutabaga.c



Thanks for keeping working on this. For the entire series:
Reviewed-by: Akihiko Odaki 
Tested-by: Akihiko Odaki 



Re: [PULL 00/12] First batch of s390x patches for QEMU 8.2

2023-08-24 Thread Philippe Mathieu-Daudé

On 24/8/23 18:10, Thomas Huth wrote:

On 24/08/2023 16.51, Stefan Hajnoczi wrote:

On Thu, 24 Aug 2023 at 02:53, Thomas Huth  wrote:


On 23/08/2023 18.34, Stefan Hajnoczi wrote:

On Wed, Aug 23, 2023 at 01:45:32PM +0200, Thomas Huth wrote:
The following changes since commit 
b0dd9a7d6dd15a6898e9c585b521e6bec79b25aa:


    Open 8.2 development tree (2023-08-22 07:14:07 -0700)

are available in the Git repository at:

    https://gitlab.com/thuth/qemu.git tags/pull-request-2023-08-23

for you to fetch changes up to 
6c49f685d30ffe81cfa47da2c258904ad28ac368:


    tests/tcg/s390x: Test VSTRS (2023-08-23 12:07:30 +0200)


Hi Thomas,
Please take a look at the following ubuntu-20.04-s390x-all CI failure:
https://gitlab.com/qemu-project/qemu/-/jobs/4931341536


It says: "TimeoutError: Timeout waiting for job to pause" ... could you
please check the load on that host? ... I think that s390x runner is 
known
for being too slow some times, so I assume that problem should go 
away if

you re-run the job when it is less loaded.


I ran it again and it timed out. I've merged the PR and assume the
test is just flaky.


I think someone needs to look at the runner to see whether there is 
still old stuff taking CPU time or something similar.


Would reporting the runner load on failure help in some way?




Re: [PATCH] tests/qtest/netdev-socket: Avoid variable-length array in inet_get_free_port_multiple()

2023-08-24 Thread Philippe Mathieu-Daudé

On 24/8/23 18:45, Peter Maydell wrote:

We use a variable-length array in inet_get_free_port_multiple().
This is only test code called at the start of a test, so switch to a
heap allocation instead.

The codebase has very few VLAs, and if we can get rid of them all we
can make the compiler error on new additions.  This is a defensive
measure against security bugs where an on-stack dynamic allocation
isn't correctly size-checked (e.g.  CVE-2021-3527).

Signed-off-by: Peter Maydell 
---
  tests/qtest/netdev-socket.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)


Reviewed-by: Philippe Mathieu-Daudé 




[PATCH v2] block/file-posix: fix update_zones_wp() caller

2023-08-24 Thread Sam Li
When the zoned request fail, it needs to update only the wp of
the target zones for not disrupting the in-flight writes on
these other zones. The wp is updated successfully after the
request completes.

Fixed the callers with right offset and nr_zones.

Signed-off-by: Sam Li 
---
 block/file-posix.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/block/file-posix.c b/block/file-posix.c
index b16e9c21a1..55e7f06a2f 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -2522,7 +2522,8 @@ out:
 }
 } else {
 if (type & (QEMU_AIO_WRITE | QEMU_AIO_ZONE_APPEND)) {
-update_zones_wp(bs, s->fd, 0, 1);
+/* write and append write are not allowed to cross zone bounaries 
*/
+update_zones_wp(bs, s->fd, offset, 1);
 }
 }
 
@@ -3472,7 +3473,7 @@ static int coroutine_fn raw_co_zone_mgmt(BlockDriverState 
*bs, BlockZoneOp op,
 len >> BDRV_SECTOR_BITS);
 ret = raw_thread_pool_submit(handle_aiocb_zone_mgmt, );
 if (ret != 0) {
-update_zones_wp(bs, s->fd, offset, i);
+update_zones_wp(bs, s->fd, offset, nrz);
 error_report("ioctl %s failed %d", op_name, ret);
 return ret;
 }
-- 
2.40.1




Re: [PATCH] block/file-posix: fix update_zones_wp() caller

2023-08-24 Thread Sam Li
Damien Le Moal  于2023年8月25日周五 11:32写道:
>
> On 8/25/23 12:05, Sam Li wrote:
> > Damien Le Moal  于2023年8月25日周五 07:49写道:
> >>
> >> On 8/25/23 02:39, Sam Li wrote:
> >>> When the zoned requests that may change wp fail, it needs to
> >>> update only wps of the zones within the range of the requests
> >>> for not disrupting the other in-flight requests. The wp is updated
> >>> successfully after the request completes.
> >>>
> >>> Fixed the callers with right offset and nr_zones.
> >>>
> >>> Signed-off-by: Sam Li 
> >>> ---
> >>>  block/file-posix.c | 5 +++--
> >>>  1 file changed, 3 insertions(+), 2 deletions(-)
> >>>
> >>> diff --git a/block/file-posix.c b/block/file-posix.c
> >>> index b16e9c21a1..22559d6c2d 100644
> >>> --- a/block/file-posix.c
> >>> +++ b/block/file-posix.c
> >>> @@ -2522,7 +2522,8 @@ out:
> >>>  }
> >>>  } else {
> >>>  if (type & (QEMU_AIO_WRITE | QEMU_AIO_ZONE_APPEND)) {
> >>> -update_zones_wp(bs, s->fd, 0, 1);
> >>> +update_zones_wp(bs, s->fd, offset,
> >>> +ROUND_UP(bytes, bs->bl.zone_size));
> >>
> >> Write and zone append operations are not allowed to cross zone boundaries. 
> >> So I
> >> the number of zones should always be 1. The above changes a number of 
> >> zones to a
> >> number of bytes, which seems wrong. The correct fix is I think:
> >>
> >> update_zones_wp(bs, s->fd, offset, 1);
> >>
> >
> > I see. I forgot this constraint.
> >
> >>>  }
> >>>  }
> >>>
> >>> @@ -3472,7 +3473,7 @@ static int coroutine_fn 
> >>> raw_co_zone_mgmt(BlockDriverState *bs, BlockZoneOp op,
> >>>  len >> BDRV_SECTOR_BITS);
> >>>  ret = raw_thread_pool_submit(handle_aiocb_zone_mgmt, );
> >>>  if (ret != 0) {
> >>> -update_zones_wp(bs, s->fd, offset, i);
> >>> +update_zones_wp(bs, s->fd, offset, nrz);
> >>
> >> Same here. Why would you need to update all zones wp ? This will affect 
> >> zones
> >> that do not have a write error and potentially change there correct 
> >> in-memory wp
> >> to a wrong value. I think this also should be:
> >>
> >>update_zones_wp(bs, s->fd, offset, 1);
> >>
> >
> > Is update_zones_wp for cancelling the writes on invalid zones or
> > updating corrupted write pointers caused by caller (write, append or
> > zone_mgmt)?
> >
> > My thought is based on the latter. Zone_mgmt can manage multiple zones
> > with a single request. When the request fails, it's hard to tell which
> > zone is corrupted. The relation between the req (zone_mgmt) and
> > update_zones_wp is: if req succeeds, no updates; if req fails,
> > consider the req never happens and do again.
>
> You should update the wp of the zones that were touched by the operation that
> failed. No other zone should have its wp updated as that could cause 
> corruptions
> of the wp if there are on-going writes on these other zones.
>
> so the call should be "update_zones_wp(bs, s->fd, offset, n);"
>
> with n being the number of zones that the operation targeted.

Yes, so it's nrz in zone_mgmt. Thanks!

>
> >
> > If the former is right, then it assumes only the first zone may
> > contain an error. I am not sure it's right.
> >
> >>>  error_report("ioctl %s failed %d", op_name, ret);
> >>>  return ret;
> >>>  }
> >>
> >> --
> >> Damien Le Moal
> >> Western Digital Research
> >>
>
> --
> Damien Le Moal
> Western Digital Research
>



Re: [PATCH] block/file-posix: fix update_zones_wp() caller

2023-08-24 Thread Damien Le Moal
On 8/25/23 12:05, Sam Li wrote:
> Damien Le Moal  于2023年8月25日周五 07:49写道:
>>
>> On 8/25/23 02:39, Sam Li wrote:
>>> When the zoned requests that may change wp fail, it needs to
>>> update only wps of the zones within the range of the requests
>>> for not disrupting the other in-flight requests. The wp is updated
>>> successfully after the request completes.
>>>
>>> Fixed the callers with right offset and nr_zones.
>>>
>>> Signed-off-by: Sam Li 
>>> ---
>>>  block/file-posix.c | 5 +++--
>>>  1 file changed, 3 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/block/file-posix.c b/block/file-posix.c
>>> index b16e9c21a1..22559d6c2d 100644
>>> --- a/block/file-posix.c
>>> +++ b/block/file-posix.c
>>> @@ -2522,7 +2522,8 @@ out:
>>>  }
>>>  } else {
>>>  if (type & (QEMU_AIO_WRITE | QEMU_AIO_ZONE_APPEND)) {
>>> -update_zones_wp(bs, s->fd, 0, 1);
>>> +update_zones_wp(bs, s->fd, offset,
>>> +ROUND_UP(bytes, bs->bl.zone_size));
>>
>> Write and zone append operations are not allowed to cross zone boundaries. 
>> So I
>> the number of zones should always be 1. The above changes a number of zones 
>> to a
>> number of bytes, which seems wrong. The correct fix is I think:
>>
>> update_zones_wp(bs, s->fd, offset, 1);
>>
> 
> I see. I forgot this constraint.
> 
>>>  }
>>>  }
>>>
>>> @@ -3472,7 +3473,7 @@ static int coroutine_fn 
>>> raw_co_zone_mgmt(BlockDriverState *bs, BlockZoneOp op,
>>>  len >> BDRV_SECTOR_BITS);
>>>  ret = raw_thread_pool_submit(handle_aiocb_zone_mgmt, );
>>>  if (ret != 0) {
>>> -update_zones_wp(bs, s->fd, offset, i);
>>> +update_zones_wp(bs, s->fd, offset, nrz);
>>
>> Same here. Why would you need to update all zones wp ? This will affect zones
>> that do not have a write error and potentially change there correct 
>> in-memory wp
>> to a wrong value. I think this also should be:
>>
>>update_zones_wp(bs, s->fd, offset, 1);
>>
> 
> Is update_zones_wp for cancelling the writes on invalid zones or
> updating corrupted write pointers caused by caller (write, append or
> zone_mgmt)?
> 
> My thought is based on the latter. Zone_mgmt can manage multiple zones
> with a single request. When the request fails, it's hard to tell which
> zone is corrupted. The relation between the req (zone_mgmt) and
> update_zones_wp is: if req succeeds, no updates; if req fails,
> consider the req never happens and do again.

You should update the wp of the zones that were touched by the operation that
failed. No other zone should have its wp updated as that could cause corruptions
of the wp if there are on-going writes on these other zones.

so the call should be "update_zones_wp(bs, s->fd, offset, n);"

with n being the number of zones that the operation targeted.

> 
> If the former is right, then it assumes only the first zone may
> contain an error. I am not sure it's right.
> 
>>>  error_report("ioctl %s failed %d", op_name, ret);
>>>  return ret;
>>>  }
>>
>> --
>> Damien Le Moal
>> Western Digital Research
>>

-- 
Damien Le Moal
Western Digital Research




[PATCH 15/16] tests: bios-tables-test: Add test for smbios type4 thread count2

2023-08-24 Thread Zhao Liu
From: Zhao Liu 

This tests the commit 7298fd7de5551 ("hw/smbios: Fix thread count in
type4").

Add this test to cover 2 cases:
1. Test thread count2 field with multiple sockets and multiple dies to
   confirm this field could correctly calculate threads per sockets.

2. Confirm that field calculation could correctly recognize the
   difference between "-smp maxcpus" and "-smp cpus".

Suggested-by: Igor Mammedov 
Signed-off-by: Zhao Liu 
---
 tests/qtest/bios-tables-test.c | 33 +
 1 file changed, 33 insertions(+)

diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index 26474d376633..1b0c27e95d26 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -96,6 +96,7 @@ typedef struct {
 uint8_t smbios_core_count;
 uint16_t smbios_core_count2;
 uint8_t smbios_thread_count;
+uint16_t smbios_thread_count2;
 uint8_t *required_struct_types;
 int required_struct_types_len;
 int type4_count;
@@ -644,6 +645,7 @@ static void smbios_cpu_test(test_data *data, uint32_t addr,
 uint8_t thread_count, expected_thread_count = data->smbios_thread_count;
 uint16_t speed, expected_speed[2];
 uint16_t core_count2, expected_core_count2 = data->smbios_core_count2;
+uint16_t thread_count2, expected_thread_count2 = 
data->smbios_thread_count2;
 int offset[2];
 int i;
 
@@ -673,6 +675,8 @@ static void smbios_cpu_test(test_data *data, uint32_t addr,
 }
 
 if (ep_type == SMBIOS_ENTRY_POINT_TYPE_64) {
+uint64_t thread_count2_addr;
+
 core_count2 = qtest_readw(data->qts,
   addr + offsetof(struct smbios_type_4, core_count2));
 
@@ -680,6 +684,15 @@ static void smbios_cpu_test(test_data *data, uint32_t addr,
 if (expected_core_count == 0xFF && expected_core_count2) {
 g_assert_cmpuint(core_count2, ==, expected_core_count2);
 }
+
+thread_count2_addr = addr +
+ offsetof(struct smbios_type_4, thread_count2);
+thread_count2 = qtest_readw(data->qts, thread_count2_addr);
+
+/* Thread Count has reached its limit, checking Thread Count 2 */
+if (expected_thread_count == 0xFF && expected_thread_count2) {
+g_assert_cmpuint(thread_count2, ==, expected_thread_count2);
+}
 }
 }
 
@@ -1050,6 +1063,7 @@ static void test_acpi_q35_tcg_thread_count(void)
 .required_struct_types = base_required_struct_types,
 .required_struct_types_len = ARRAY_SIZE(base_required_struct_types),
 .smbios_thread_count = 27,
+.smbios_thread_count2 = 27,
 };
 
 test_acpi_one("-machine smbios-entry-point-type=64 "
@@ -1058,6 +1072,23 @@ static void test_acpi_q35_tcg_thread_count(void)
 free_test_data();
 }
 
+static void test_acpi_q35_tcg_thread_count2(void)
+{
+test_data data = {
+.machine = MACHINE_Q35,
+.variant = ".thread-count2",
+.required_struct_types = base_required_struct_types,
+.required_struct_types_len = ARRAY_SIZE(base_required_struct_types),
+.smbios_thread_count = 0xFF,
+.smbios_thread_count2 = 260,
+};
+
+test_acpi_one("-machine smbios-entry-point-type=64 "
+  "-smp 
cpus=210,maxcpus=520,sockets=2,dies=2,cores=65,threads=2",
+  );
+free_test_data();
+}
+
 static void test_acpi_q35_tcg_bridge(void)
 {
 test_data data = {};
@@ -2216,6 +2247,8 @@ int main(int argc, char *argv[])
test_acpi_q35_tcg_core_count2);
 qtest_add_func("acpi/q35/thread-count",
test_acpi_q35_tcg_thread_count);
+qtest_add_func("acpi/q35/thread-count2",
+   test_acpi_q35_tcg_thread_count2);
 }
 qtest_add_func("acpi/q35/viot", test_acpi_q35_viot);
 #ifdef CONFIG_POSIX
-- 
2.34.1




[PATCH 04/16] tests: bios-tables-test: Add ACPI table binaries for type4 count test

2023-08-24 Thread Zhao Liu
From: Zhao Liu 

Following the guidelines in tests/qtest/bios-tables-test.c, this
is step 5 and 6.

Changes in the tables:
FACP:

+/*
+ * Intel ACPI Component Architecture
+ * AML/ASL+ Disassembler version 20200925 (64-bit version)
+ * Copyright (c) 2000 - 2020 Intel Corporation
+ *
+ * Disassembly of /tmp/aml-W37791, Wed Aug 23 10:36:32 2023
+ *
+ * ACPI Data Table [FACP]
+ *
+ * Format: [HexOffset DecimalOffset ByteLength]  FieldName : FieldValue
+ */
+
+[000h    4]Signature : "FACP"[Fixed ACPI 
Description Table (FADT)]
+[004h 0004   4] Table Length : 00F4
+[008h 0008   1] Revision : 03
+[009h 0009   1] Checksum : B3
+[00Ah 0010   6]   Oem ID : "BOCHS "
+[010h 0016   8] Oem Table ID : "BXPC"
+[018h 0024   4] Oem Revision : 0001
+[01Ch 0028   4]  Asl Compiler ID : "BXPC"
+[020h 0032   4]Asl Compiler Revision : 0001
+
+[024h 0036   4] FACS Address : 
+[028h 0040   4] DSDT Address : 
+[02Ch 0044   1]Model : 01
+[02Dh 0045   1]   PM Profile : 00 [Unspecified]
+[02Eh 0046   2]SCI Interrupt : 0009
+[030h 0048   4] SMI Command Port : 00B2
+[034h 0052   1]ACPI Enable Value : 02
+[035h 0053   1]   ACPI Disable Value : 03
+[036h 0054   1]   S4BIOS Command : 00
+[037h 0055   1]  P-State Control : 00
+[038h 0056   4] PM1A Event Block Address : 0600
+[03Ch 0060   4] PM1B Event Block Address : 
+[040h 0064   4]   PM1A Control Block Address : 0604
+[044h 0068   4]   PM1B Control Block Address : 
+[048h 0072   4]PM2 Control Block Address : 
+[04Ch 0076   4]   PM Timer Block Address : 0608
+[050h 0080   4]   GPE0 Block Address : 0620
+[054h 0084   4]   GPE1 Block Address : 
+[058h 0088   1]   PM1 Event Block Length : 04
+[059h 0089   1] PM1 Control Block Length : 02
+[05Ah 0090   1] PM2 Control Block Length : 00
+[05Bh 0091   1]PM Timer Block Length : 04
+[05Ch 0092   1]GPE0 Block Length : 10
+[05Dh 0093   1]GPE1 Block Length : 00
+[05Eh 0094   1] GPE1 Base Offset : 00
+[05Fh 0095   1] _CST Support : 00
+[060h 0096   2]   C2 Latency : 0FFF
+[062h 0098   2]   C3 Latency : 0FFF
+[064h 0100   2]   CPU Cache Size : 
+[066h 0102   2]   Cache Flush Stride : 
+[068h 0104   1]Duty Cycle Offset : 00
+[069h 0105   1] Duty Cycle Width : 00
+[06Ah 0106   1]  RTC Day Alarm Index : 00
+[06Bh 0107   1]RTC Month Alarm Index : 00
+[06Ch 0108   1]RTC Century Index : 32
+[06Dh 0109   2]   Boot Flags (decoded below) : 0002
+   Legacy Devices Supported (V2) : 0
+8042 Present on ports 60/64 (V2) : 1
+VGA Not Present (V4) : 0
+  MSI Not Supported (V4) : 0
+PCIe ASPM Not Supported (V4) : 0
+   CMOS RTC Not Present (V5) : 0
+[06Fh 0111   1] Reserved : 00
+[070h 0112   4]Flags (decoded below) : 000484A5
+  WBINVD instruction is operational (V1) : 1
+  WBINVD flushes all caches (V1) : 0
+All CPUs support C1 (V1) : 1
+  C2 works on MP system (V1) : 0
+Control Method Power Button (V1) : 0
+Control Method Sleep Button (V1) : 1
+RTC wake not in fixed reg space (V1) : 0
+RTC can wake system from S4 (V1) : 1
+32-bit PM Timer (V1) : 0
+  Docking Supported (V1) : 0
+   Reset Register Supported (V2) : 1
+Sealed Case (V3) : 0
+Headless - No Video (V3) : 0
+Use native instr after SLP_TYPx (V3) : 0
+  PCIEXP_WAK Bits Supported (V4) : 0
+ Use Platform Timer (V4) : 1
+   RTC_STS valid on S4 wake (V4) : 0
+Remote Power-on capable (V4) : 0
+ Use APIC Cluster Model (V4) : 1
+ Use APIC Physical Destination Mode (V4) : 0
+   Hardware Reduced (V5) : 0
+  Low Power S0 Idle (V5) : 0
+
+[074h 0116  12]   Reset Register : [Generic Address Structure]
+[074h 0116   1] Space ID : 01 [SystemIO]
+[075h 0117   1]Bit Width : 08
+[076h 0118   1]   Bit Offset : 00
+[077h 0119   1] Encoded Access Width : 00 [Undefined/Legacy]
+[078h 0120   8]  Address : 0CF9
+
+[080h 0128   1] Value to cause reset : 0F
+[081h 0129   2]ARM Flags (decoded below) : 
+  PSCI Compliant : 0
+   

[PATCH 14/16] tests: bios-tables-test: Prepare the ACPI table change for type4 thread count2 test

2023-08-24 Thread Zhao Liu
From: Zhao Liu 

Following the guidelines in tests/qtest/bios-tables-test.c, this
is step 1 - 3.

List the ACPI tables that will be added to test the thread count2 field
of smbios type4 table.

Signed-off-by: Zhao Liu 
---
 tests/data/acpi/q35/APIC.thread-count2  | 0
 tests/data/acpi/q35/DSDT.thread-count2  | 0
 tests/data/acpi/q35/FACP.thread-count2  | 0
 tests/qtest/bios-tables-test-allowed-diff.h | 3 +++
 4 files changed, 3 insertions(+)
 create mode 100644 tests/data/acpi/q35/APIC.thread-count2
 create mode 100644 tests/data/acpi/q35/DSDT.thread-count2
 create mode 100644 tests/data/acpi/q35/FACP.thread-count2

diff --git a/tests/data/acpi/q35/APIC.thread-count2 
b/tests/data/acpi/q35/APIC.thread-count2
new file mode 100644
index ..e69de29bb2d1
diff --git a/tests/data/acpi/q35/DSDT.thread-count2 
b/tests/data/acpi/q35/DSDT.thread-count2
new file mode 100644
index ..e69de29bb2d1
diff --git a/tests/data/acpi/q35/FACP.thread-count2 
b/tests/data/acpi/q35/FACP.thread-count2
new file mode 100644
index ..e69de29bb2d1
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
b/tests/qtest/bios-tables-test-allowed-diff.h
index dfb8523c8bf4..d17d80e21ab9 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1 +1,4 @@
 /* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/q35/APIC.thread-count2",
+"tests/data/acpi/q35/DSDT.thread-count2",
+"tests/data/acpi/q35/FACP.thread-count2",
-- 
2.34.1




[PATCH 03/16] tests: bios-tables-test: Add test for smbios type4 count

2023-08-24 Thread Zhao Liu
From: Zhao Liu 

This tests the commit d79a284a44bb7 ("hw/smbios: Fix smbios_smp_sockets
calculation").

Test the count of type4 tables for multiple sockets case.

Suggested-by: Igor Mammedov 
Signed-off-by: Zhao Liu 
---
 tests/qtest/bios-tables-test.c | 33 -
 1 file changed, 32 insertions(+), 1 deletion(-)

diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index 47ba20b9579b..8679255449cf 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -97,6 +97,7 @@ typedef struct {
 uint16_t smbios_core_count2;
 uint8_t *required_struct_types;
 int required_struct_types_len;
+int type4_count;
 QTestState *qts;
 } test_data;
 
@@ -673,12 +674,21 @@ static void smbios_cpu_test(test_data *data, uint32_t 
addr,
 }
 }
 
+static void smbios_type4_count_test(test_data *data, int type4_count)
+{
+int expected_type4_count = data->type4_count;
+
+if (expected_type4_count) {
+g_assert_cmpuint(type4_count, ==, expected_type4_count);
+}
+}
+
 static void test_smbios_structs(test_data *data, SmbiosEntryPointType ep_type)
 {
 DECLARE_BITMAP(struct_bitmap, SMBIOS_MAX_TYPE+1) = { 0 };
 
 SmbiosEntryPoint *ep_table = >smbios_ep_table;
-int i = 0, len, max_len = 0;
+int i = 0, len, max_len = 0, type4_count = 0;
 uint8_t type, prv, crt;
 uint64_t addr;
 
@@ -704,6 +714,7 @@ static void test_smbios_structs(test_data *data, 
SmbiosEntryPointType ep_type)
 
 if (type == 4) {
 smbios_cpu_test(data, addr, ep_type);
+type4_count++;
 }
 
 /* seek to end of unformatted string area of this struct ("\0\0") */
@@ -747,6 +758,8 @@ static void test_smbios_structs(test_data *data, 
SmbiosEntryPointType ep_type)
 for (i = 0; i < data->required_struct_types_len; i++) {
 g_assert(test_bit(data->required_struct_types[i], struct_bitmap));
 }
+
+smbios_type4_count_test(data, type4_count);
 }
 
 static void test_acpi_load_tables(test_data *data)
@@ -970,6 +983,22 @@ static void test_acpi_q35_tcg(void)
 free_test_data();
 }
 
+static void test_acpi_q35_tcg_type4_count(void)
+{
+test_data data = {
+.machine = MACHINE_Q35,
+.variant = ".type4-count",
+.required_struct_types = base_required_struct_types,
+.required_struct_types_len = ARRAY_SIZE(base_required_struct_types),
+.type4_count = 5,
+};
+
+test_acpi_one("-machine smbios-entry-point-type=64 "
+  "-smp cpus=100,maxcpus=120,sockets=5,"
+  "dies=2,cores=4,threads=3", );
+free_test_data();
+}
+
 static void test_acpi_q35_tcg_core_count2(void)
 {
 test_data data = {
@@ -2135,6 +2164,8 @@ int main(int argc, char *argv[])
 if (has_kvm) {
 qtest_add_func("acpi/q35/kvm/xapic", test_acpi_q35_kvm_xapic);
 qtest_add_func("acpi/q35/kvm/dmar", test_acpi_q35_kvm_dmar);
+qtest_add_func("acpi/q35/type4-count",
+   test_acpi_q35_tcg_type4_count);
 qtest_add_func("acpi/q35/core-count2",
test_acpi_q35_tcg_core_count2);
 }
-- 
2.34.1




[PATCH 13/16] tests: bios-tables-test: Add ACPI table binaries for type4 thread count test

2023-08-24 Thread Zhao Liu
From: Zhao Liu 

Following the guidelines in tests/qtest/bios-tables-test.c, this
is step 5 and 6.

Changes in the tables:
FACP:

+/*
+ * Intel ACPI Component Architecture
+ * AML/ASL+ Disassembler version 20200925 (64-bit version)
+ * Copyright (c) 2000 - 2020 Intel Corporation
+ *
+ * Disassembly of /tmp/aml-1NP791, Wed Aug 23 21:51:31 2023
+ *
+ * ACPI Data Table [FACP]
+ *
+ * Format: [HexOffset DecimalOffset ByteLength]  FieldName : FieldValue
+ */
+
+[000h    4]Signature : "FACP"[Fixed ACPI 
Description Table (FADT)]
+[004h 0004   4] Table Length : 00F4
+[008h 0008   1] Revision : 03
+[009h 0009   1] Checksum : B3
+[00Ah 0010   6]   Oem ID : "BOCHS "
+[010h 0016   8] Oem Table ID : "BXPC"
+[018h 0024   4] Oem Revision : 0001
+[01Ch 0028   4]  Asl Compiler ID : "BXPC"
+[020h 0032   4]Asl Compiler Revision : 0001
+
+[024h 0036   4] FACS Address : 
+[028h 0040   4] DSDT Address : 
+[02Ch 0044   1]Model : 01
+[02Dh 0045   1]   PM Profile : 00 [Unspecified]
+[02Eh 0046   2]SCI Interrupt : 0009
+[030h 0048   4] SMI Command Port : 00B2
+[034h 0052   1]ACPI Enable Value : 02
+[035h 0053   1]   ACPI Disable Value : 03
+[036h 0054   1]   S4BIOS Command : 00
+[037h 0055   1]  P-State Control : 00
+[038h 0056   4] PM1A Event Block Address : 0600
+[03Ch 0060   4] PM1B Event Block Address : 
+[040h 0064   4]   PM1A Control Block Address : 0604
+[044h 0068   4]   PM1B Control Block Address : 
+[048h 0072   4]PM2 Control Block Address : 
+[04Ch 0076   4]   PM Timer Block Address : 0608
+[050h 0080   4]   GPE0 Block Address : 0620
+[054h 0084   4]   GPE1 Block Address : 
+[058h 0088   1]   PM1 Event Block Length : 04
+[059h 0089   1] PM1 Control Block Length : 02
+[05Ah 0090   1] PM2 Control Block Length : 00
+[05Bh 0091   1]PM Timer Block Length : 04
+[05Ch 0092   1]GPE0 Block Length : 10
+[05Dh 0093   1]GPE1 Block Length : 00
+[05Eh 0094   1] GPE1 Base Offset : 00
+[05Fh 0095   1] _CST Support : 00
+[060h 0096   2]   C2 Latency : 0FFF
+[062h 0098   2]   C3 Latency : 0FFF
+[064h 0100   2]   CPU Cache Size : 
+[066h 0102   2]   Cache Flush Stride : 
+[068h 0104   1]Duty Cycle Offset : 00
+[069h 0105   1] Duty Cycle Width : 00
+[06Ah 0106   1]  RTC Day Alarm Index : 00
+[06Bh 0107   1]RTC Month Alarm Index : 00
+[06Ch 0108   1]RTC Century Index : 32
+[06Dh 0109   2]   Boot Flags (decoded below) : 0002
+   Legacy Devices Supported (V2) : 0
+8042 Present on ports 60/64 (V2) : 1
+VGA Not Present (V4) : 0
+  MSI Not Supported (V4) : 0
+PCIe ASPM Not Supported (V4) : 0
+   CMOS RTC Not Present (V5) : 0
+[06Fh 0111   1] Reserved : 00
+[070h 0112   4]Flags (decoded below) : 000484A5
+  WBINVD instruction is operational (V1) : 1
+  WBINVD flushes all caches (V1) : 0
+All CPUs support C1 (V1) : 1
+  C2 works on MP system (V1) : 0
+Control Method Power Button (V1) : 0
+Control Method Sleep Button (V1) : 1
+RTC wake not in fixed reg space (V1) : 0
+RTC can wake system from S4 (V1) : 1
+32-bit PM Timer (V1) : 0
+  Docking Supported (V1) : 0
+   Reset Register Supported (V2) : 1
+Sealed Case (V3) : 0
+Headless - No Video (V3) : 0
+Use native instr after SLP_TYPx (V3) : 0
+  PCIEXP_WAK Bits Supported (V4) : 0
+ Use Platform Timer (V4) : 1
+   RTC_STS valid on S4 wake (V4) : 0
+Remote Power-on capable (V4) : 0
+ Use APIC Cluster Model (V4) : 1
+ Use APIC Physical Destination Mode (V4) : 0
+   Hardware Reduced (V5) : 0
+  Low Power S0 Idle (V5) : 0
+
+[074h 0116  12]   Reset Register : [Generic Address Structure]
+[074h 0116   1] Space ID : 01 [SystemIO]
+[075h 0117   1]Bit Width : 08
+[076h 0118   1]   Bit Offset : 00
+[077h 0119   1] Encoded Access Width : 00 [Undefined/Legacy]
+[078h 0120   8]  Address : 0CF9
+
+[080h 0128   1] Value to cause reset : 0F
+[081h 0129   2]ARM Flags (decoded below) : 
+  PSCI Compliant : 0
+   

[PATCH 07/16] tests: bios-tables-test: Add ACPI table binaries for type4 core count test

2023-08-24 Thread Zhao Liu
From: Zhao Liu 

Following the guidelines in tests/qtest/bios-tables-test.c, this
is step 5 and 6.

Changes in the tables:
FACP:

+/*
+ * Intel ACPI Component Architecture
+ * AML/ASL+ Disassembler version 20200925 (64-bit version)
+ * Copyright (c) 2000 - 2020 Intel Corporation
+ *
+ * Disassembly of /tmp/aml-Y6WW91, Wed Aug 23 15:43:43 2023
+ *
+ * ACPI Data Table [FACP]
+ *
+ * Format: [HexOffset DecimalOffset ByteLength]  FieldName : FieldValue
+ */
+
+[000h    4]Signature : "FACP"[Fixed ACPI 
Description Table (FADT)]
+[004h 0004   4] Table Length : 00F4
+[008h 0008   1] Revision : 03
+[009h 0009   1] Checksum : B3
+[00Ah 0010   6]   Oem ID : "BOCHS "
+[010h 0016   8] Oem Table ID : "BXPC"
+[018h 0024   4] Oem Revision : 0001
+[01Ch 0028   4]  Asl Compiler ID : "BXPC"
+[020h 0032   4]Asl Compiler Revision : 0001
+
+[024h 0036   4] FACS Address : 
+[028h 0040   4] DSDT Address : 
+[02Ch 0044   1]Model : 01
+[02Dh 0045   1]   PM Profile : 00 [Unspecified]
+[02Eh 0046   2]SCI Interrupt : 0009
+[030h 0048   4] SMI Command Port : 00B2
+[034h 0052   1]ACPI Enable Value : 02
+[035h 0053   1]   ACPI Disable Value : 03
+[036h 0054   1]   S4BIOS Command : 00
+[037h 0055   1]  P-State Control : 00
+[038h 0056   4] PM1A Event Block Address : 0600
+[03Ch 0060   4] PM1B Event Block Address : 
+[040h 0064   4]   PM1A Control Block Address : 0604
+[044h 0068   4]   PM1B Control Block Address : 
+[048h 0072   4]PM2 Control Block Address : 
+[04Ch 0076   4]   PM Timer Block Address : 0608
+[050h 0080   4]   GPE0 Block Address : 0620
+[054h 0084   4]   GPE1 Block Address : 
+[058h 0088   1]   PM1 Event Block Length : 04
+[059h 0089   1] PM1 Control Block Length : 02
+[05Ah 0090   1] PM2 Control Block Length : 00
+[05Bh 0091   1]PM Timer Block Length : 04
+[05Ch 0092   1]GPE0 Block Length : 10
+[05Dh 0093   1]GPE1 Block Length : 00
+[05Eh 0094   1] GPE1 Base Offset : 00
+[05Fh 0095   1] _CST Support : 00
+[060h 0096   2]   C2 Latency : 0FFF
+[062h 0098   2]   C3 Latency : 0FFF
+[064h 0100   2]   CPU Cache Size : 
+[066h 0102   2]   Cache Flush Stride : 
+[068h 0104   1]Duty Cycle Offset : 00
+[069h 0105   1] Duty Cycle Width : 00
+[06Ah 0106   1]  RTC Day Alarm Index : 00
+[06Bh 0107   1]RTC Month Alarm Index : 00
+[06Ch 0108   1]RTC Century Index : 32
+[06Dh 0109   2]   Boot Flags (decoded below) : 0002
+   Legacy Devices Supported (V2) : 0
+8042 Present on ports 60/64 (V2) : 1
+VGA Not Present (V4) : 0
+  MSI Not Supported (V4) : 0
+PCIe ASPM Not Supported (V4) : 0
+   CMOS RTC Not Present (V5) : 0
+[06Fh 0111   1] Reserved : 00
+[070h 0112   4]Flags (decoded below) : 000484A5
+  WBINVD instruction is operational (V1) : 1
+  WBINVD flushes all caches (V1) : 0
+All CPUs support C1 (V1) : 1
+  C2 works on MP system (V1) : 0
+Control Method Power Button (V1) : 0
+Control Method Sleep Button (V1) : 1
+RTC wake not in fixed reg space (V1) : 0
+RTC can wake system from S4 (V1) : 1
+32-bit PM Timer (V1) : 0
+  Docking Supported (V1) : 0
+   Reset Register Supported (V2) : 1
+Sealed Case (V3) : 0
+Headless - No Video (V3) : 0
+Use native instr after SLP_TYPx (V3) : 0
+  PCIEXP_WAK Bits Supported (V4) : 0
+ Use Platform Timer (V4) : 1
+   RTC_STS valid on S4 wake (V4) : 0
+Remote Power-on capable (V4) : 0
+ Use APIC Cluster Model (V4) : 1
+ Use APIC Physical Destination Mode (V4) : 0
+   Hardware Reduced (V5) : 0
+  Low Power S0 Idle (V5) : 0
+
+[074h 0116  12]   Reset Register : [Generic Address Structure]
+[074h 0116   1] Space ID : 01 [SystemIO]
+[075h 0117   1]Bit Width : 08
+[076h 0118   1]   Bit Offset : 00
+[077h 0119   1] Encoded Access Width : 00 [Undefined/Legacy]
+[078h 0120   8]  Address : 0CF9
+
+[080h 0128   1] Value to cause reset : 0F
+[081h 0129   2]ARM Flags (decoded below) : 
+  PSCI Compliant : 0
+   

[PATCH 10/16] tests: bios-tables-test: Update ACPI table binaries for core count2 test

2023-08-24 Thread Zhao Liu
From: Zhao Liu 

Change the core count2 from 275 to 260.

Following the guidelines in tests/qtest/bios-tables-test.c, this
is step 5 and 6.

Changes in the tables:
APIC:

 /*
  * Intel ACPI Component Architecture
  * AML/ASL+ Disassembler version 20200925 (64-bit version)
  * Copyright (c) 2000 - 2020 Intel Corporation
  *
- * Disassembly of tests/data/acpi/q35/APIC.core-count2, Wed Aug 23 16:29:51 
2023
+ * Disassembly of /tmp/aml-KQDX91, Wed Aug 23 16:29:51 2023
  *
  * ACPI Data Table [APIC]
  *
  * Format: [HexOffset DecimalOffset ByteLength]  FieldName : FieldValue
  */

 [000h    4]Signature : "APIC"[Multiple APIC 
Description Table (MADT)]
-[004h 0004   4] Table Length : 09AE
+[004h 0004   4] Table Length : 0CA6
 [008h 0008   1] Revision : 03
-[009h 0009   1] Checksum : CE
+[009h 0009   1] Checksum : FA
 [00Ah 0010   6]   Oem ID : "BOCHS "
 [010h 0016   8] Oem Table ID : "BXPC"
 [018h 0024   4] Oem Revision : 0001
 [01Ch 0028   4]  Asl Compiler ID : "BXPC"
 [020h 0032   4]Asl Compiler Revision : 0001

 [024h 0036   4]   Local Apic Address : FEE0
 [028h 0040   4]Flags (decoded below) : 0001
  PC-AT Compatibility : 1

 [02Ch 0044   1]Subtable Type : 00 [Processor Local APIC]
 [02Dh 0045   1]   Length : 08
 [02Eh 0046   1] Processor ID : 00
 [02Fh 0047   1]Local Apic ID : 00
 [030h 0048   4]Flags (decoded below) : 0001
Processor Enabled : 1
@@ -1051,1256 +1051,1136 @@
 [42Ch 1068   1]Subtable Type : 00 [Processor Local APIC]
 [42Dh 1069   1]   Length : 08
 [42Eh 1070   1] Processor ID : 80
 [42Fh 1071   1]Local Apic ID : 80
 [430h 1072   4]Flags (decoded below) : 0001
Processor Enabled : 1
   Runtime Online Capable : 0

 [434h 1076   1]Subtable Type : 00 [Processor Local APIC]
 [435h 1077   1]   Length : 08
 [436h 1078   1] Processor ID : 81
 [437h 1079   1]Local Apic ID : 81
 [438h 1080   4]Flags (decoded below) : 0001
Processor Enabled : 1
   Runtime Online Capable : 0

-[43Ch 1084   1]Subtable Type : 00 [Processor Local APIC]
-[43Dh 1085   1]   Length : 08
-[43Eh 1086   1] Processor ID : 82
-[43Fh 1087   1]Local Apic ID : 82
-[440h 1088   4]Flags (decoded below) : 0001
-   Processor Enabled : 1
-  Runtime Online Capable : 0
-
-[444h 1092   1]Subtable Type : 00 [Processor Local APIC]
-[445h 1093   1]   Length : 08
-[446h 1094   1] Processor ID : 83
-[447h 1095   1]Local Apic ID : 83
-[448h 1096   4]Flags (decoded below) : 0001
-   Processor Enabled : 1
-  Runtime Online Capable : 0

[snip]

-
-[964h 2404   1]Subtable Type : 01 [I/O APIC]
-[965h 2405   1]   Length : 0C
-[966h 2406   1]  I/O Apic ID : 00
-[967h 2407   1] Reserved : 00
-[968h 2408   4]  Address : FEC0
-[96Ch 2412   4]Interrupt : 
-
-[970h 2416   1]Subtable Type : 02 [Interrupt Source Override]
-[971h 2417   1]   Length : 0A
-[972h 2418   1]  Bus : 00
-[973h 2419   1]   Source : 00
-[974h 2420   4]Interrupt : 0002
-[978h 2424   2]Flags (decoded below) : 
+[43Ch 1084   1]Subtable Type : 09 [Processor Local x2APIC]
+[43Dh 1085   1]   Length : 10
+[43Eh 1086   2] Reserved : 
+[440h 1088   4]  Processor x2Apic ID : 0100
+[444h 1092   4]Flags (decoded below) : 0001
+   Processor Enabled : 1
+[448h 1096   4]Processor UID : 0082
+
+[44Ch 1100   1]Subtable Type : 09 [Processor Local x2APIC]
+[44Dh 1101   1]   Length : 10
+[44Eh 1102   2] Reserved : 
+[450h 1104   4]  Processor x2Apic ID : 0101
+[454h 1108   4]Flags (decoded below) : 0001
+   Processor Enabled : 1
+[458h 1112   4]Processor UID : 0083
+

[snip]

+
+[C68h 3176   1]Subtable Type : 02 [Interrupt Source Override]
+[C69h 3177   1]   Length : 0A
+[C6Ah 3178   1]  Bus : 00
+[C6Bh 3179   

[PATCH 11/16] tests: bios-tables-test: Prepare the ACPI table change for type4 thread count test

2023-08-24 Thread Zhao Liu
From: Zhao Liu 

Following the guidelines in tests/qtest/bios-tables-test.c, this
is step 1 - 3.

List the ACPI tables that will be added to test the thread count field
of smbios type4 table.

Signed-off-by: Zhao Liu 
---
 tests/data/acpi/q35/APIC.thread-count   | 0
 tests/data/acpi/q35/DSDT.thread-count   | 0
 tests/data/acpi/q35/FACP.thread-count   | 0
 tests/qtest/bios-tables-test-allowed-diff.h | 3 +++
 4 files changed, 3 insertions(+)
 create mode 100644 tests/data/acpi/q35/APIC.thread-count
 create mode 100644 tests/data/acpi/q35/DSDT.thread-count
 create mode 100644 tests/data/acpi/q35/FACP.thread-count

diff --git a/tests/data/acpi/q35/APIC.thread-count 
b/tests/data/acpi/q35/APIC.thread-count
new file mode 100644
index ..e69de29bb2d1
diff --git a/tests/data/acpi/q35/DSDT.thread-count 
b/tests/data/acpi/q35/DSDT.thread-count
new file mode 100644
index ..e69de29bb2d1
diff --git a/tests/data/acpi/q35/FACP.thread-count 
b/tests/data/acpi/q35/FACP.thread-count
new file mode 100644
index ..e69de29bb2d1
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
b/tests/qtest/bios-tables-test-allowed-diff.h
index dfb8523c8bf4..4d139d7f6b7e 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1 +1,4 @@
 /* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/q35/APIC.thread-count",
+"tests/data/acpi/q35/DSDT.thread-count",
+"tests/data/acpi/q35/FACP.thread-count",
-- 
2.34.1




[PATCH 05/16] tests: bios-tables-test: Prepare the ACPI table change for type4 core count test

2023-08-24 Thread Zhao Liu
From: Zhao Liu 

Following the guidelines in tests/qtest/bios-tables-test.c, this
is step 1 - 3.

List the ACPI tables that will be added to test the type 4 core count
field.

Signed-off-by: Zhao Liu 
---
 tests/data/acpi/q35/APIC.core-count | 0
 tests/data/acpi/q35/DSDT.core-count | 0
 tests/data/acpi/q35/FACP.core-count | 0
 tests/qtest/bios-tables-test-allowed-diff.h | 3 +++
 4 files changed, 3 insertions(+)
 create mode 100644 tests/data/acpi/q35/APIC.core-count
 create mode 100644 tests/data/acpi/q35/DSDT.core-count
 create mode 100644 tests/data/acpi/q35/FACP.core-count

diff --git a/tests/data/acpi/q35/APIC.core-count 
b/tests/data/acpi/q35/APIC.core-count
new file mode 100644
index ..e69de29bb2d1
diff --git a/tests/data/acpi/q35/DSDT.core-count 
b/tests/data/acpi/q35/DSDT.core-count
new file mode 100644
index ..e69de29bb2d1
diff --git a/tests/data/acpi/q35/FACP.core-count 
b/tests/data/acpi/q35/FACP.core-count
new file mode 100644
index ..e69de29bb2d1
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
b/tests/qtest/bios-tables-test-allowed-diff.h
index dfb8523c8bf4..b9bc1961309a 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1 +1,4 @@
 /* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/q35/APIC.core-count",
+"tests/data/acpi/q35/DSDT.core-count",
+"tests/data/acpi/q35/FACP.core-count",
-- 
2.34.1




[PATCH 16/16] tests: bios-tables-test: Add ACPI table binaries for type4 thread count2 test

2023-08-24 Thread Zhao Liu
From: Zhao Liu 

Following the guidelines in tests/qtest/bios-tables-test.c, this
is step 5 and 6.

Changes in the tables:
FACP:

+/*
+ * Intel ACPI Component Architecture
+ * AML/ASL+ Disassembler version 20200925 (64-bit version)
+ * Copyright (c) 2000 - 2020 Intel Corporation
+ *
+ * Disassembly of /tmp/aml-WOA191, Wed Aug 23 22:29:53 2023
+ *
+ * ACPI Data Table [FACP]
+ *
+ * Format: [HexOffset DecimalOffset ByteLength]  FieldName : FieldValue
+ */
+
+[000h    4]Signature : "FACP"[Fixed ACPI 
Description Table (FADT)]
+[004h 0004   4] Table Length : 00F4
+[008h 0008   1] Revision : 03
+[009h 0009   1] Checksum : B3
+[00Ah 0010   6]   Oem ID : "BOCHS "
+[010h 0016   8] Oem Table ID : "BXPC"
+[018h 0024   4] Oem Revision : 0001
+[01Ch 0028   4]  Asl Compiler ID : "BXPC"
+[020h 0032   4]Asl Compiler Revision : 0001
+
+[024h 0036   4] FACS Address : 
+[028h 0040   4] DSDT Address : 
+[02Ch 0044   1]Model : 01
+[02Dh 0045   1]   PM Profile : 00 [Unspecified]
+[02Eh 0046   2]SCI Interrupt : 0009
+[030h 0048   4] SMI Command Port : 00B2
+[034h 0052   1]ACPI Enable Value : 02
+[035h 0053   1]   ACPI Disable Value : 03
+[036h 0054   1]   S4BIOS Command : 00
+[037h 0055   1]  P-State Control : 00
+[038h 0056   4] PM1A Event Block Address : 0600
+[03Ch 0060   4] PM1B Event Block Address : 
+[040h 0064   4]   PM1A Control Block Address : 0604
+[044h 0068   4]   PM1B Control Block Address : 
+[048h 0072   4]PM2 Control Block Address : 
+[04Ch 0076   4]   PM Timer Block Address : 0608
+[050h 0080   4]   GPE0 Block Address : 0620
+[054h 0084   4]   GPE1 Block Address : 
+[058h 0088   1]   PM1 Event Block Length : 04
+[059h 0089   1] PM1 Control Block Length : 02
+[05Ah 0090   1] PM2 Control Block Length : 00
+[05Bh 0091   1]PM Timer Block Length : 04
+[05Ch 0092   1]GPE0 Block Length : 10
+[05Dh 0093   1]GPE1 Block Length : 00
+[05Eh 0094   1] GPE1 Base Offset : 00
+[05Fh 0095   1] _CST Support : 00
+[060h 0096   2]   C2 Latency : 0FFF
+[062h 0098   2]   C3 Latency : 0FFF
+[064h 0100   2]   CPU Cache Size : 
+[066h 0102   2]   Cache Flush Stride : 
+[068h 0104   1]Duty Cycle Offset : 00
+[069h 0105   1] Duty Cycle Width : 00
+[06Ah 0106   1]  RTC Day Alarm Index : 00
+[06Bh 0107   1]RTC Month Alarm Index : 00
+[06Ch 0108   1]RTC Century Index : 32
+[06Dh 0109   2]   Boot Flags (decoded below) : 0002
+   Legacy Devices Supported (V2) : 0
+8042 Present on ports 60/64 (V2) : 1
+VGA Not Present (V4) : 0
+  MSI Not Supported (V4) : 0
+PCIe ASPM Not Supported (V4) : 0
+   CMOS RTC Not Present (V5) : 0
+[06Fh 0111   1] Reserved : 00
+[070h 0112   4]Flags (decoded below) : 000484A5
+  WBINVD instruction is operational (V1) : 1
+  WBINVD flushes all caches (V1) : 0
+All CPUs support C1 (V1) : 1
+  C2 works on MP system (V1) : 0
+Control Method Power Button (V1) : 0
+Control Method Sleep Button (V1) : 1
+RTC wake not in fixed reg space (V1) : 0
+RTC can wake system from S4 (V1) : 1
+32-bit PM Timer (V1) : 0
+  Docking Supported (V1) : 0
+   Reset Register Supported (V2) : 1
+Sealed Case (V3) : 0
+Headless - No Video (V3) : 0
+Use native instr after SLP_TYPx (V3) : 0
+  PCIEXP_WAK Bits Supported (V4) : 0
+ Use Platform Timer (V4) : 1
+   RTC_STS valid on S4 wake (V4) : 0
+Remote Power-on capable (V4) : 0
+ Use APIC Cluster Model (V4) : 1
+ Use APIC Physical Destination Mode (V4) : 0
+   Hardware Reduced (V5) : 0
+  Low Power S0 Idle (V5) : 0
+
+[074h 0116  12]   Reset Register : [Generic Address Structure]
+[074h 0116   1] Space ID : 01 [SystemIO]
+[075h 0117   1]Bit Width : 08
+[076h 0118   1]   Bit Offset : 00
+[077h 0119   1] Encoded Access Width : 00 [Undefined/Legacy]
+[078h 0120   8]  Address : 0CF9
+
+[080h 0128   1] Value to cause reset : 0F
+[081h 0129   2]ARM Flags (decoded below) : 
+  PSCI Compliant : 0
+   

[PATCH 06/16] tests: bios-tables-test: Add test for smbios type4 core count

2023-08-24 Thread Zhao Liu
From: Zhao Liu 

This tests the commit 196ea60a734c3 ("hw/smbios: Fix core count in
type4").

Test the core count field of type4 table for multiple sockets/dies case.

Suggested-by: Igor Mammedov 
Signed-off-by: Zhao Liu 
---
 tests/qtest/bios-tables-test.c | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index 8679255449cf..a35c753a3a00 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -999,6 +999,23 @@ static void test_acpi_q35_tcg_type4_count(void)
 free_test_data();
 }
 
+static void test_acpi_q35_tcg_core_count(void)
+{
+test_data data = {
+.machine = MACHINE_Q35,
+.variant = ".core-count",
+.required_struct_types = base_required_struct_types,
+.required_struct_types_len = ARRAY_SIZE(base_required_struct_types),
+.smbios_core_count = 9,
+.smbios_core_count2 = 9,
+};
+
+test_acpi_one("-machine smbios-entry-point-type=64 "
+  "-smp 54,sockets=2,dies=3,cores=3,threads=3",
+  );
+free_test_data();
+}
+
 static void test_acpi_q35_tcg_core_count2(void)
 {
 test_data data = {
@@ -2166,6 +2183,8 @@ int main(int argc, char *argv[])
 qtest_add_func("acpi/q35/kvm/dmar", test_acpi_q35_kvm_dmar);
 qtest_add_func("acpi/q35/type4-count",
test_acpi_q35_tcg_type4_count);
+qtest_add_func("acpi/q35/core-count",
+   test_acpi_q35_tcg_core_count);
 qtest_add_func("acpi/q35/core-count2",
test_acpi_q35_tcg_core_count2);
 }
-- 
2.34.1




[PATCH 09/16] tests: bios-tables-test: Extend core count2 test to cover general topology

2023-08-24 Thread Zhao Liu
From: Zhao Liu 

Currently, this case just covers the topology with only core and smt
levels, and doesn't consider more topology layers between socket and
core.

To cover the fixed case in the commit 196ea60a734c3 ("hw/smbios: Fix
core count in type4"), add the "die" level in "-smp" as the more
general topology case.

Suggested-by: Igor Mammedov 
Signed-off-by: Zhao Liu 
---
 tests/qtest/bios-tables-test.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index a35c753a3a00..8cba1d8126f2 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -1024,10 +1024,12 @@ static void test_acpi_q35_tcg_core_count2(void)
 .required_struct_types = base_required_struct_types,
 .required_struct_types_len = ARRAY_SIZE(base_required_struct_types),
 .smbios_core_count = 0xFF,
-.smbios_core_count2 = 275,
+.smbios_core_count2 = 260,
 };
 
-test_acpi_one("-machine smbios-entry-point-type=64 -smp 275", );
+test_acpi_one("-machine smbios-entry-point-type=64 "
+  "-smp 260,dies=2,cores=130,threads=1",
+  );
 free_test_data();
 }
 
-- 
2.34.1




[PATCH 00/16] tests: Add CPU topology related smbios test cases

2023-08-24 Thread Zhao Liu
From: Zhao Liu 

Hi all,

This patchset is the follow up tests of previous topology fixes in
smbios [1].

In this patchset, add these test cases:

1. Add the case to test 2 newly added topology helpers (patch 1):
   * machine_topo_get_cores_per_socket()
   * machine_topo_get_threads_per_socket()

2. Add the cases in bios-tables-test.c to:
   * test smbios type4 table count (patch 2-4).
   * test smbios type4 core count field (patch 5-7).
   * update the test of smbios type4 core count2 field (patch 8-10).
   * test smbios type4 thread count (patch 11-13).
   * test smbios type4 thread count2 (patch 14-16).

With the above new cases, cover all commits of [1] in test.

[1]: https://lists.gnu.org/archive/html/qemu-devel/2023-06/msg06225.html

Regards,
Zhao
---
Zhao Liu (16):
  tests: test-smp-parse: Add the test for cores/threads per socket
helpers
  tests: bios-tables-test: Prepare the ACPI table change for type4 count
test
  tests: bios-tables-test: Add test for smbios type4 count
  tests: bios-tables-test: Add ACPI table binaries for type4 count test
  tests: bios-tables-test: Prepare the ACPI table change for type4 core
count test
  tests: bios-tables-test: Add test for smbios type4 core count
  tests: bios-tables-test: Add ACPI table binaries for type4 core count
test
  tests: bios-tables-test: Prepare the ACPI table change for type4 core
count2 test
  tests: bios-tables-test: Extend core count2 test to cover general
topology
  tests: bios-tables-test: Update ACPI table binaries for core count2
test
  tests: bios-tables-test: Prepare the ACPI table change for type4
thread count test
  tests: bios-tables-test: Add test for smbios type4 thread count
  tests: bios-tables-test: Add ACPI table binaries for type4 thread
count test
  tests: bios-tables-test: Prepare the ACPI table change for type4
thread count2 test
  tests: bios-tables-test: Add test for smbios type4 thread count2
  tests: bios-tables-test: Add ACPI table binaries for type4 thread
count2 test

 tests/data/acpi/q35/APIC.core-count| Bin 0 -> 544 bytes
 tests/data/acpi/q35/APIC.core-count2   | Bin 2478 -> 3238 bytes
 tests/data/acpi/q35/APIC.thread-count  | Bin 0 -> 544 bytes
 tests/data/acpi/q35/APIC.thread-count2 | Bin 0 -> 7398 bytes
 tests/data/acpi/q35/APIC.type4-count   | Bin 0 -> 1072 bytes
 tests/data/acpi/q35/DSDT.core-count| Bin 0 -> 12913 bytes
 tests/data/acpi/q35/DSDT.core-count2   | Bin 32495 -> 33770 bytes
 tests/data/acpi/q35/DSDT.thread-count  | Bin 0 -> 12913 bytes
 tests/data/acpi/q35/DSDT.thread-count2 | Bin 0 -> 63671 bytes
 tests/data/acpi/q35/DSDT.type4-count   | Bin 0 -> 18589 bytes
 tests/data/acpi/q35/FACP.core-count| Bin 0 -> 244 bytes
 tests/data/acpi/q35/FACP.thread-count  | Bin 0 -> 244 bytes
 tests/data/acpi/q35/FACP.thread-count2 | Bin 0 -> 244 bytes
 tests/data/acpi/q35/FACP.type4-count   | Bin 0 -> 244 bytes
 tests/qtest/bios-tables-test.c | 118 -
 tests/unit/test-smp-parse.c|  67 +++---
 16 files changed, 169 insertions(+), 16 deletions(-)
 create mode 100644 tests/data/acpi/q35/APIC.core-count
 create mode 100644 tests/data/acpi/q35/APIC.thread-count
 create mode 100644 tests/data/acpi/q35/APIC.thread-count2
 create mode 100644 tests/data/acpi/q35/APIC.type4-count
 create mode 100644 tests/data/acpi/q35/DSDT.core-count
 create mode 100644 tests/data/acpi/q35/DSDT.thread-count
 create mode 100644 tests/data/acpi/q35/DSDT.thread-count2
 create mode 100644 tests/data/acpi/q35/DSDT.type4-count
 create mode 100644 tests/data/acpi/q35/FACP.core-count
 create mode 100644 tests/data/acpi/q35/FACP.thread-count
 create mode 100644 tests/data/acpi/q35/FACP.thread-count2
 create mode 100644 tests/data/acpi/q35/FACP.type4-count

-- 
2.34.1




[PATCH 01/16] tests: test-smp-parse: Add the test for cores/threads per socket helpers

2023-08-24 Thread Zhao Liu
From: Zhao Liu 

Use the different ways to calculate cores/threads per socket, so that
the new CPU topology levels won't be missed in these 2 helpes:

* machine_topo_get_cores_per_socket()
* machine_topo_get_threads_per_socket()

Test the commit a1d027be95bc3 ("machine: Add helpers to get cores/
threads per socket").

Suggested-by: Igor Mammedov 
Signed-off-by: Zhao Liu 
---
 tests/unit/test-smp-parse.c | 67 ++---
 1 file changed, 54 insertions(+), 13 deletions(-)

diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c
index fdc39a846ca6..24972666a74d 100644
--- a/tests/unit/test-smp-parse.c
+++ b/tests/unit/test-smp-parse.c
@@ -394,20 +394,47 @@ static char *smp_config_to_string(const SMPConfiguration 
*config)
 config->has_maxcpus ? "true" : "false", config->maxcpus);
 }
 
-static char *cpu_topology_to_string(const CpuTopology *topo)
+/* Use the different calculation than machine_topo_get_threads_per_socket(). */
+static unsigned int cpu_topology_get_threads_per_socket(const CpuTopology 
*topo)
+{
+/* Check the divisor to avoid invalid topology examples causing SIGFPE. */
+if (!topo->sockets) {
+return 0;
+} else {
+return topo->max_cpus / topo->sockets;
+}
+}
+
+/* Use the different calculation than machine_topo_get_cores_per_socket(). */
+static unsigned int cpu_topology_get_cores_per_socket(const CpuTopology *topo)
+{
+/* Check the divisor to avoid invalid topology examples causing SIGFPE. */
+if (!topo->threads) {
+return 0;
+} else {
+return cpu_topology_get_threads_per_socket(topo) / topo->threads;
+}
+}
+
+static char *cpu_topology_to_string(const CpuTopology *topo,
+unsigned int threads_per_socket,
+unsigned int cores_per_socket)
 {
 return g_strdup_printf(
 "(CpuTopology) {\n"
-".cpus = %u,\n"
-".sockets  = %u,\n"
-".dies = %u,\n"
-".clusters = %u,\n"
-".cores= %u,\n"
-".threads  = %u,\n"
-".max_cpus = %u,\n"
+".cpus   = %u,\n"
+".sockets= %u,\n"
+".dies   = %u,\n"
+".clusters   = %u,\n"
+".cores  = %u,\n"
+".threads= %u,\n"
+".max_cpus   = %u,\n"
+".threads_per_socket = %u,\n"
+".cores_per_socket   = %u,\n"
 "}",
 topo->cpus, topo->sockets, topo->dies, topo->clusters,
-topo->cores, topo->threads, topo->max_cpus);
+topo->cores, topo->threads, topo->max_cpus,
+threads_per_socket, cores_per_socket);
 }
 
 static void check_parse(MachineState *ms, const SMPConfiguration *config,
@@ -415,14 +442,26 @@ static void check_parse(MachineState *ms, const 
SMPConfiguration *config,
 bool is_valid)
 {
 g_autofree char *config_str = smp_config_to_string(config);
-g_autofree char *expect_topo_str = cpu_topology_to_string(expect_topo);
-g_autofree char *output_topo_str = NULL;
+g_autofree char *expect_topo_str = NULL, *output_topo_str = NULL;
+unsigned int expect_threads_per_socket, expect_cores_per_socket;
+unsigned int ms_threads_per_socket, ms_cores_per_socket;
 Error *err = NULL;
 
+expect_threads_per_socket =
+cpu_topology_get_threads_per_socket(expect_topo);
+expect_cores_per_socket =
+cpu_topology_get_cores_per_socket(expect_topo);
+expect_topo_str = cpu_topology_to_string(expect_topo,
+ expect_threads_per_socket,
+ expect_cores_per_socket);
+
 /* call the generic parser */
 machine_parse_smp_config(ms, config, );
 
-output_topo_str = cpu_topology_to_string(>smp);
+ms_threads_per_socket = machine_topo_get_threads_per_socket(ms);
+ms_cores_per_socket = machine_topo_get_cores_per_socket(ms);
+output_topo_str = cpu_topology_to_string(>smp, ms_threads_per_socket,
+ ms_cores_per_socket);
 
 /* when the configuration is supposed to be valid */
 if (is_valid) {
@@ -433,7 +472,9 @@ static void check_parse(MachineState *ms, const 
SMPConfiguration *config,
 (ms->smp.clusters == expect_topo->clusters) &&
 (ms->smp.cores == expect_topo->cores) &&
 (ms->smp.threads == expect_topo->threads) &&
-(ms->smp.max_cpus == expect_topo->max_cpus)) {
+(ms->smp.max_cpus == expect_topo->max_cpus) &&
+(ms_threads_per_socket == expect_threads_per_socket) &&
+(ms_cores_per_socket == expect_cores_per_socket)) {
 return;
 }
 
-- 
2.34.1




[PATCH 12/16] tests: bios-tables-test: Add test for smbios type4 thread count

2023-08-24 Thread Zhao Liu
From: Zhao Liu 

This tests the commit 7298fd7de5551 ("hw/smbios: Fix thread count in
type4").

Add this test to cover 2 cases:
1. Test thread count field with multiple sockets and multiple dies to
   confirm this field could correctly calculate threads per sockets.

2. Confirm that field calculation could correctly recognize the
   difference between "-smp maxcpus" and "-smp cpus".

Suggested-by: Igor Mammedov 
Signed-off-by: Zhao Liu 
---
 tests/qtest/bios-tables-test.c | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index 8cba1d8126f2..26474d376633 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -95,6 +95,7 @@ typedef struct {
 uint16_t smbios_cpu_curr_speed;
 uint8_t smbios_core_count;
 uint16_t smbios_core_count2;
+uint8_t smbios_thread_count;
 uint8_t *required_struct_types;
 int required_struct_types_len;
 int type4_count;
@@ -640,6 +641,7 @@ static void smbios_cpu_test(test_data *data, uint32_t addr,
 SmbiosEntryPointType ep_type)
 {
 uint8_t core_count, expected_core_count = data->smbios_core_count;
+uint8_t thread_count, expected_thread_count = data->smbios_thread_count;
 uint16_t speed, expected_speed[2];
 uint16_t core_count2, expected_core_count2 = data->smbios_core_count2;
 int offset[2];
@@ -663,6 +665,13 @@ static void smbios_cpu_test(test_data *data, uint32_t addr,
 g_assert_cmpuint(core_count, ==, expected_core_count);
 }
 
+thread_count = qtest_readb(data->qts,
+   addr + offsetof(struct smbios_type_4, thread_count));
+
+if (expected_thread_count) {
+g_assert_cmpuint(thread_count, ==, expected_thread_count);
+}
+
 if (ep_type == SMBIOS_ENTRY_POINT_TYPE_64) {
 core_count2 = qtest_readw(data->qts,
   addr + offsetof(struct smbios_type_4, core_count2));
@@ -1033,6 +1042,22 @@ static void test_acpi_q35_tcg_core_count2(void)
 free_test_data();
 }
 
+static void test_acpi_q35_tcg_thread_count(void)
+{
+test_data data = {
+.machine = MACHINE_Q35,
+.variant = ".thread-count",
+.required_struct_types = base_required_struct_types,
+.required_struct_types_len = ARRAY_SIZE(base_required_struct_types),
+.smbios_thread_count = 27,
+};
+
+test_acpi_one("-machine smbios-entry-point-type=64 "
+  "-smp cpus=15,maxcpus=54,sockets=2,dies=3,cores=3,threads=3",
+  );
+free_test_data();
+}
+
 static void test_acpi_q35_tcg_bridge(void)
 {
 test_data data = {};
@@ -2189,6 +2214,8 @@ int main(int argc, char *argv[])
test_acpi_q35_tcg_core_count);
 qtest_add_func("acpi/q35/core-count2",
test_acpi_q35_tcg_core_count2);
+qtest_add_func("acpi/q35/thread-count",
+   test_acpi_q35_tcg_thread_count);
 }
 qtest_add_func("acpi/q35/viot", test_acpi_q35_viot);
 #ifdef CONFIG_POSIX
-- 
2.34.1




[PATCH 08/16] tests: bios-tables-test: Prepare the ACPI table change for type4 core count2 test

2023-08-24 Thread Zhao Liu
From: Zhao Liu 

Following the guidelines in tests/qtest/bios-tables-test.c, this
is step 1 - 3.

List the ACPI tables that will be changed about the type 4 core count2
test case.

Signed-off-by: Zhao Liu 
---
 tests/qtest/bios-tables-test-allowed-diff.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
b/tests/qtest/bios-tables-test-allowed-diff.h
index dfb8523c8bf4..0f95d1344b2c 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1 +1,3 @@
 /* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/q35/APIC.core-count2",
+"tests/data/acpi/q35/DSDT.core-count2",
-- 
2.34.1




[PATCH 02/16] tests: bios-tables-test: Prepare the ACPI table change for type4 count test

2023-08-24 Thread Zhao Liu
From: Zhao Liu 

Following the guidelines in tests/qtest/bios-tables-test.c, this
is step 1 - 3.

List the ACPI tables that will be added to test the type 4 count.

Signed-off-by: Zhao Liu 
---
 tests/data/acpi/q35/APIC.type4-count| 0
 tests/data/acpi/q35/DSDT.type4-count| 0
 tests/data/acpi/q35/FACP.type4-count| 0
 tests/qtest/bios-tables-test-allowed-diff.h | 3 +++
 4 files changed, 3 insertions(+)
 create mode 100644 tests/data/acpi/q35/APIC.type4-count
 create mode 100644 tests/data/acpi/q35/DSDT.type4-count
 create mode 100644 tests/data/acpi/q35/FACP.type4-count

diff --git a/tests/data/acpi/q35/APIC.type4-count 
b/tests/data/acpi/q35/APIC.type4-count
new file mode 100644
index ..e69de29bb2d1
diff --git a/tests/data/acpi/q35/DSDT.type4-count 
b/tests/data/acpi/q35/DSDT.type4-count
new file mode 100644
index ..e69de29bb2d1
diff --git a/tests/data/acpi/q35/FACP.type4-count 
b/tests/data/acpi/q35/FACP.type4-count
new file mode 100644
index ..e69de29bb2d1
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
b/tests/qtest/bios-tables-test-allowed-diff.h
index dfb8523c8bf4..0ce6f8fc72ee 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1 +1,4 @@
 /* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/q35/APIC.type4-count",
+"tests/data/acpi/q35/DSDT.type4-count",
+"tests/data/acpi/q35/FACP.type4-count",
-- 
2.34.1




Re: [PATCH] block/file-posix: fix update_zones_wp() caller

2023-08-24 Thread Sam Li
Damien Le Moal  于2023年8月25日周五 07:49写道:
>
> On 8/25/23 02:39, Sam Li wrote:
> > When the zoned requests that may change wp fail, it needs to
> > update only wps of the zones within the range of the requests
> > for not disrupting the other in-flight requests. The wp is updated
> > successfully after the request completes.
> >
> > Fixed the callers with right offset and nr_zones.
> >
> > Signed-off-by: Sam Li 
> > ---
> >  block/file-posix.c | 5 +++--
> >  1 file changed, 3 insertions(+), 2 deletions(-)
> >
> > diff --git a/block/file-posix.c b/block/file-posix.c
> > index b16e9c21a1..22559d6c2d 100644
> > --- a/block/file-posix.c
> > +++ b/block/file-posix.c
> > @@ -2522,7 +2522,8 @@ out:
> >  }
> >  } else {
> >  if (type & (QEMU_AIO_WRITE | QEMU_AIO_ZONE_APPEND)) {
> > -update_zones_wp(bs, s->fd, 0, 1);
> > +update_zones_wp(bs, s->fd, offset,
> > +ROUND_UP(bytes, bs->bl.zone_size));
>
> Write and zone append operations are not allowed to cross zone boundaries. So 
> I
> the number of zones should always be 1. The above changes a number of zones 
> to a
> number of bytes, which seems wrong. The correct fix is I think:
>
> update_zones_wp(bs, s->fd, offset, 1);
>

I see. I forgot this constraint.

> >  }
> >  }
> >
> > @@ -3472,7 +3473,7 @@ static int coroutine_fn 
> > raw_co_zone_mgmt(BlockDriverState *bs, BlockZoneOp op,
> >  len >> BDRV_SECTOR_BITS);
> >  ret = raw_thread_pool_submit(handle_aiocb_zone_mgmt, );
> >  if (ret != 0) {
> > -update_zones_wp(bs, s->fd, offset, i);
> > +update_zones_wp(bs, s->fd, offset, nrz);
>
> Same here. Why would you need to update all zones wp ? This will affect zones
> that do not have a write error and potentially change there correct in-memory 
> wp
> to a wrong value. I think this also should be:
>
>update_zones_wp(bs, s->fd, offset, 1);
>

Is update_zones_wp for cancelling the writes on invalid zones or
updating corrupted write pointers caused by caller (write, append or
zone_mgmt)?

My thought is based on the latter. Zone_mgmt can manage multiple zones
with a single request. When the request fails, it's hard to tell which
zone is corrupted. The relation between the req (zone_mgmt) and
update_zones_wp is: if req succeeds, no updates; if req fails,
consider the req never happens and do again.

If the former is right, then it assumes only the first zone may
contain an error. I am not sure it's right.

> >  error_report("ioctl %s failed %d", op_name, ret);
> >  return ret;
> >  }
>
> --
> Damien Le Moal
> Western Digital Research
>



Re: [PATCH v2 2/2] softmmu/dirtylimit: Convert free to g_free

2023-08-24 Thread Yong Huang
On Fri, Aug 25, 2023 at 10:33 AM  wrote:

> From: alloc 
>
> Convert free to g_free to match g_new and g_malloc functions.
>
> Signed-off-by: alloc 
> ---
>  softmmu/dirtylimit.c | 10 +-
>  1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/softmmu/dirtylimit.c b/softmmu/dirtylimit.c
> index e3ff53b8fc..fa959d7743 100644
> --- a/softmmu/dirtylimit.c
> +++ b/softmmu/dirtylimit.c
> @@ -100,7 +100,7 @@ static void vcpu_dirty_rate_stat_collect(void)
>  stat.rates[i].dirty_rate;
>  }
>
> -free(stat.rates);
> +g_free(stat.rates);
>  }
>
>  static void *vcpu_dirty_rate_stat_thread(void *opaque)
> @@ -171,10 +171,10 @@ void vcpu_dirty_rate_stat_initialize(void)
>
>  void vcpu_dirty_rate_stat_finalize(void)
>  {
> -free(vcpu_dirty_rate_stat->stat.rates);
> +g_free(vcpu_dirty_rate_stat->stat.rates);
>  vcpu_dirty_rate_stat->stat.rates = NULL;
>
> -free(vcpu_dirty_rate_stat);
> +g_free(vcpu_dirty_rate_stat);
>  vcpu_dirty_rate_stat = NULL;
>  }
>
> @@ -220,10 +220,10 @@ void dirtylimit_state_initialize(void)
>
>  void dirtylimit_state_finalize(void)
>  {
> -free(dirtylimit_state->states);
> +g_free(dirtylimit_state->states);
>  dirtylimit_state->states = NULL;
>
> -free(dirtylimit_state);
> +g_free(dirtylimit_state);
>  dirtylimit_state = NULL;
>
>  trace_dirtylimit_state_finalize();
> --
> 2.39.3
>
>
Reviewed-by: Hyman Huang 

-- 
Best regards


[PATCH v2 0/2] softmmu/dirtylimit: Fix memory leak issue

2023-08-24 Thread alloc . young
From: alloc 

Changes in v2:
- Split into two patches, one fixing memory leak issue and another
  converting free to g_free.
- Fix typos

alloc (1):
  softmmu/dirtylimit: Convert free to g_free

alloc.young (1):
  softmmu: Fix dirtylimit memory leak

 softmmu/dirtylimit.c | 26 --
 1 file changed, 12 insertions(+), 14 deletions(-)

-- 
2.39.3




[PATCH v2 2/2] softmmu/dirtylimit: Convert free to g_free

2023-08-24 Thread alloc . young
From: alloc 

Convert free to g_free to match g_new and g_malloc functions.

Signed-off-by: alloc 
---
 softmmu/dirtylimit.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/softmmu/dirtylimit.c b/softmmu/dirtylimit.c
index e3ff53b8fc..fa959d7743 100644
--- a/softmmu/dirtylimit.c
+++ b/softmmu/dirtylimit.c
@@ -100,7 +100,7 @@ static void vcpu_dirty_rate_stat_collect(void)
 stat.rates[i].dirty_rate;
 }
 
-free(stat.rates);
+g_free(stat.rates);
 }
 
 static void *vcpu_dirty_rate_stat_thread(void *opaque)
@@ -171,10 +171,10 @@ void vcpu_dirty_rate_stat_initialize(void)
 
 void vcpu_dirty_rate_stat_finalize(void)
 {
-free(vcpu_dirty_rate_stat->stat.rates);
+g_free(vcpu_dirty_rate_stat->stat.rates);
 vcpu_dirty_rate_stat->stat.rates = NULL;
 
-free(vcpu_dirty_rate_stat);
+g_free(vcpu_dirty_rate_stat);
 vcpu_dirty_rate_stat = NULL;
 }
 
@@ -220,10 +220,10 @@ void dirtylimit_state_initialize(void)
 
 void dirtylimit_state_finalize(void)
 {
-free(dirtylimit_state->states);
+g_free(dirtylimit_state->states);
 dirtylimit_state->states = NULL;
 
-free(dirtylimit_state);
+g_free(dirtylimit_state);
 dirtylimit_state = NULL;
 
 trace_dirtylimit_state_finalize();
-- 
2.39.3




[PATCH v2 1/2] softmmu: Fix dirtylimit memory leak

2023-08-24 Thread alloc . young
From: "alloc.young" 

Fix memory leak in hmp_info_vcpu_dirty_limit,use g_autoptr
to handle memory deallocation.

Signed-off-by: alloc.young 
---
 softmmu/dirtylimit.c | 16 +++-
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/softmmu/dirtylimit.c b/softmmu/dirtylimit.c
index 3c275ee55b..e3ff53b8fc 100644
--- a/softmmu/dirtylimit.c
+++ b/softmmu/dirtylimit.c
@@ -653,7 +653,8 @@ struct DirtyLimitInfoList *qmp_query_vcpu_dirty_limit(Error 
**errp)
 
 void hmp_info_vcpu_dirty_limit(Monitor *mon, const QDict *qdict)
 {
-DirtyLimitInfoList *limit, *head, *info = NULL;
+DirtyLimitInfoList *info;
+g_autoptr(DirtyLimitInfoList) head = NULL;
 Error *err = NULL;
 
 if (!dirtylimit_in_service()) {
@@ -661,20 +662,17 @@ void hmp_info_vcpu_dirty_limit(Monitor *mon, const QDict 
*qdict)
 return;
 }
 
-info = qmp_query_vcpu_dirty_limit();
+head = qmp_query_vcpu_dirty_limit();
 if (err) {
 hmp_handle_error(mon, err);
 return;
 }
 
-head = info;
-for (limit = head; limit != NULL; limit = limit->next) {
+for (info = head; info != NULL; info = info->next) {
 monitor_printf(mon, "vcpu[%"PRIi64"], limit rate %"PRIi64 " (MB/s),"
 " current rate %"PRIi64 " (MB/s)\n",
-limit->value->cpu_index,
-limit->value->limit_rate,
-limit->value->current_rate);
+info->value->cpu_index,
+info->value->limit_rate,
+info->value->current_rate);
 }
-
-g_free(info);
 }
-- 
2.39.3




Re: constructor vs. __constructor__

2023-08-24 Thread Liu Jaloo
Thanks for your reply.

On Thu, Aug 24, 2023 at 5:33 PM Peter Maydell 
wrote:

> On Thu, 24 Aug 2023 at 06:55, Markus Armbruster  wrote:
> >
> > Liu Jaloo  writes:
> >
> > > What's the difference between  "__attribute__((constructor))" and
> > > "__attribute__((__constructor__))" in qemu source?
> >
> > Reading the fine manual helps:
> >
> > You may optionally specify attribute names with ‘__’ preceding and
> > following the name.  This allows you to use them in header files
> > without being concerned about a possible macro of the same name. For
> > example, you may use the attribute name __noreturn__ instead of
> > noreturn.
>
> As usual in the QEMU sources, we are not particularly consistent
> about using one version compared to the other. However we
> mostly use the "__attribute__((foo))" form rather than
> "__attribute__((__foo__))" so if you're writing new code then
> prefer the former.
>
> We also have a handful of uses of "__attribute((foo))" and
> "__attribute((__foo__))". Definitely don't add more of those :-)
>
> thanks
> -- PMM
>


[PATCH 3/5] target/hppa: Do not use hardcoded value for tlb_flush_*()

2023-08-24 Thread deller
From: Helge Deller 

Avoid using hardcoded values when calling the tlb_flush*() functions.
Instead define the correct mask (HPPA_MMU_FLUSH_MASK) and use it.
Skip flushing the MMU for physical addresses.

Signed-off-by: Helge Deller 
---
 target/hppa/cpu.h| 5 +
 target/hppa/helper.c | 2 +-
 target/hppa/mem_helper.c | 7 +++
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index 50b513f0ea..6623712644 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -41,6 +41,11 @@
 
 #define TARGET_INSN_START_EXTRA_WORDS 1
 
+/* No need to flush MMU_PHYS_IDX  */
+#define HPPA_MMU_FLUSH_MASK \
+(1 << MMU_KERNEL_IDX | 1 << MMU_PL1_IDX |   \
+ 1 << MMU_PL2_IDX| 1 << MMU_USER_IDX)
+
 /* Hardware exceptions, interrupts, faults, and traps.  */
 #define EXCP_HPMC1  /* high priority machine check */
 #define EXCP_POWER_FAIL  2
diff --git a/target/hppa/helper.c b/target/hppa/helper.c
index 74b8747083..a8d3f456ee 100644
--- a/target/hppa/helper.c
+++ b/target/hppa/helper.c
@@ -71,7 +71,7 @@ void cpu_hppa_put_psw(CPUHPPAState *env, target_ureg psw)
 /* If PSW_P changes, it affects how we translate addresses.  */
 if ((psw ^ old_psw) & PSW_P) {
 #ifndef CONFIG_USER_ONLY
-tlb_flush_by_mmuidx(env_cpu(env), 0xf);
+tlb_flush_by_mmuidx(env_cpu(env), HPPA_MMU_FLUSH_MASK);
 #endif
 }
 }
diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c
index 5046cc8f9d..6f04c101dd 100644
--- a/target/hppa/mem_helper.c
+++ b/target/hppa/mem_helper.c
@@ -50,8 +50,7 @@ static void hppa_flush_tlb_ent(CPUHPPAState *env, 
hppa_tlb_entry *ent)
 trace_hppa_tlb_flush_ent(env, ent, ent->va_b, ent->va_e, ent->pa);
 
 for (i = 0; i < n; ++i, addr += TARGET_PAGE_SIZE) {
-/* Do not flush MMU_PHYS_IDX.  */
-tlb_flush_page_by_mmuidx(cs, addr, 0xf);
+tlb_flush_page_by_mmuidx(cs, addr, HPPA_MMU_FLUSH_MASK);
 }
 
 memset(ent, 0, sizeof(*ent));
@@ -335,13 +334,13 @@ void HELPER(ptlbe)(CPUHPPAState *env)
 {
 trace_hppa_tlb_ptlbe(env);
 memset(env->tlb, 0, sizeof(env->tlb));
-tlb_flush_by_mmuidx(env_cpu(env), 0xf);
+tlb_flush_by_mmuidx(env_cpu(env), HPPA_MMU_FLUSH_MASK);
 }
 
 void cpu_hppa_change_prot_id(CPUHPPAState *env)
 {
 if (env->psw & PSW_P) {
-tlb_flush_by_mmuidx(env_cpu(env), 0xf);
+tlb_flush_by_mmuidx(env_cpu(env), HPPA_MMU_FLUSH_MASK);
 }
 }
 
-- 
2.41.0




[PATCH 0/5] target/hppa: Clean up conversion from/to MMU index and priviledge level

2023-08-24 Thread deller
From: Helge Deller 

Make the conversion between priviledge level and QEMU MMU index
consitent, and afterwards switch to MMU indices 11-15.

Signed-off-by: Helge Deller 

Helge Deller (5):
  target/hppa: Add missing PL1 and PL2 priviledge levels
  target/hppa: Add priviledge to MMU index conversion helpers
  target/hppa: Do not use hardcoded value for tlb_flush_*()
  target/hppa: Use privilege helper in hppa_get_physical_address()
  target/hppa: Switch to use MMU indices 11-15

 target/hppa/cpu.h| 19 +++
 target/hppa/helper.c |  2 +-
 target/hppa/mem_helper.c | 16 
 target/hppa/translate.c  |  9 +
 4 files changed, 29 insertions(+), 17 deletions(-)

-- 
2.41.0




[PATCH 5/5] target/hppa: Switch to use MMU indices 11-15

2023-08-24 Thread deller
From: Helge Deller 

The MMU indices 9-15 will use shorter assembler instructions
when run on a x86-64 host. So, switch over to those to get
smaller code and maybe minimally faster emulation.

Signed-off-by: Helge Deller 
---
 target/hppa/cpu.h | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index 6623712644..fa13694dab 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -30,14 +30,14 @@
basis.  It's probably easier to fall back to a strong memory model.  */
 #define TCG_GUEST_DEFAULT_MOTCG_MO_ALL
 
-#define MMU_KERNEL_IDX   0
-#define MMU_PL1_IDX  1
-#define MMU_PL2_IDX  2
-#define MMU_USER_IDX 3
-#define MMU_PHYS_IDX 4
-
-#define PRIV_TO_MMU_IDX(priv)(priv)
-#define MMU_IDX_TO_PRIV(mmu_idx) (mmu_idx)
+#define MMU_KERNEL_IDX   11
+#define MMU_PL1_IDX  12
+#define MMU_PL2_IDX  13
+#define MMU_USER_IDX 14
+#define MMU_PHYS_IDX 15
+
+#define PRIV_TO_MMU_IDX(priv)(MMU_KERNEL_IDX + (priv))
+#define MMU_IDX_TO_PRIV(mmu_idx) ((mmu_idx) - MMU_KERNEL_IDX)
 
 #define TARGET_INSN_START_EXTRA_WORDS 1
 
-- 
2.41.0




[PATCH 1/5] target/hppa: Add missing PL1 and PL2 priviledge levels

2023-08-24 Thread deller
From: Helge Deller 

The hppa CPU has 4 priviledge levels (0-3).
Mention the missing PL1 and PL2 levels, although the Linux kernel
uses only 0 (KERNEL) and 3 (USER). Not sure about HP-UX.

Signed-off-by: Helge Deller 
---
 target/hppa/cpu.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index 75c5c0ccf7..6c5b0e67c8 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -31,8 +31,11 @@
 #define TCG_GUEST_DEFAULT_MOTCG_MO_ALL
 
 #define MMU_KERNEL_IDX   0
+#define MMU_PL1_IDX  1
+#define MMU_PL2_IDX  2
 #define MMU_USER_IDX 3
 #define MMU_PHYS_IDX 4
+
 #define TARGET_INSN_START_EXTRA_WORDS 1
 
 /* Hardware exceptions, interrupts, faults, and traps.  */
-- 
2.41.0




[PATCH 4/5] target/hppa: Use privilege helper in hppa_get_physical_address()

2023-08-24 Thread deller
From: Helge Deller 

Convert hppa_get_physical_address() to use the privilege helper macro.

Signed-off-by: Helge Deller 
---
 target/hppa/mem_helper.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c
index 6f04c101dd..66cf84a0d9 100644
--- a/target/hppa/mem_helper.c
+++ b/target/hppa/mem_helper.c
@@ -73,7 +73,7 @@ int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, 
int mmu_idx,
   int type, hwaddr *pphys, int *pprot)
 {
 hwaddr phys;
-int prot, r_prot, w_prot, x_prot;
+int prot, r_prot, w_prot, x_prot, mmu_priv;
 hppa_tlb_entry *ent;
 int ret = -1;
 
@@ -97,9 +97,10 @@ int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, 
int mmu_idx,
 phys = ent->pa + (addr & ~TARGET_PAGE_MASK);
 
 /* Map TLB access_rights field to QEMU protection.  */
-r_prot = (mmu_idx <= ent->ar_pl1) * PAGE_READ;
-w_prot = (mmu_idx <= ent->ar_pl2) * PAGE_WRITE;
-x_prot = (ent->ar_pl2 <= mmu_idx && mmu_idx <= ent->ar_pl1) * PAGE_EXEC;
+mmu_priv = MMU_IDX_TO_PRIV(mmu_idx);
+r_prot = (mmu_priv <= ent->ar_pl1) * PAGE_READ;
+w_prot = (mmu_priv <= ent->ar_pl2) * PAGE_WRITE;
+x_prot = (ent->ar_pl2 <= mmu_priv && mmu_priv <= ent->ar_pl1) * PAGE_EXEC;
 switch (ent->ar_type) {
 case 0: /* read-only: data page */
 prot = r_prot;
-- 
2.41.0




[PATCH 2/5] target/hppa: Add priviledge to MMU index conversion helpers

2023-08-24 Thread deller
From: Helge Deller 

Add two macros which convert priviledge level to/from MMU index:

- PRIV_TO_MMU_IDX(priv)
returns the MMU index for the given priviledge level

- MMU_IDX_TO_PRIV(mmu_idx)
returns the corresponding priviledge level for this MMU index

The introduction of those macros make the code easier to read and
will help to improve performance in follow-up patch.

Signed-off-by: Helge Deller 
---
 target/hppa/cpu.h   | 5 -
 target/hppa/translate.c | 9 +
 2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index 6c5b0e67c8..50b513f0ea 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -36,6 +36,9 @@
 #define MMU_USER_IDX 3
 #define MMU_PHYS_IDX 4
 
+#define PRIV_TO_MMU_IDX(priv)(priv)
+#define MMU_IDX_TO_PRIV(mmu_idx) (mmu_idx)
+
 #define TARGET_INSN_START_EXTRA_WORDS 1
 
 /* Hardware exceptions, interrupts, faults, and traps.  */
@@ -236,7 +239,7 @@ static inline int cpu_mmu_index(CPUHPPAState *env, bool 
ifetch)
 return MMU_USER_IDX;
 #else
 if (env->psw & (ifetch ? PSW_C : PSW_D)) {
-return env->iaoq_f & 3;
+return PRIV_TO_MMU_IDX(env->iaoq_f & 3);
 }
 return MMU_PHYS_IDX;  /* mmu disabled */
 #endif
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index d66fcb3e6a..e3af668252 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -4057,14 +4057,15 @@ static void hppa_tr_init_disas_context(DisasContextBase 
*dcbase, CPUState *cs)
 ctx->tb_flags = ctx->base.tb->flags;
 
 #ifdef CONFIG_USER_ONLY
-ctx->privilege = MMU_USER_IDX;
+ctx->privilege = MMU_IDX_TO_PRIV(MMU_USER_IDX);
 ctx->mmu_idx = MMU_USER_IDX;
-ctx->iaoq_f = ctx->base.pc_first | MMU_USER_IDX;
-ctx->iaoq_b = ctx->base.tb->cs_base | MMU_USER_IDX;
+ctx->iaoq_f = ctx->base.pc_first | ctx->privilege;
+ctx->iaoq_b = ctx->base.tb->cs_base | ctx->privilege;
 ctx->unalign = (ctx->tb_flags & TB_FLAG_UNALIGN ? MO_UNALN : MO_ALIGN);
 #else
 ctx->privilege = (ctx->tb_flags >> TB_FLAG_PRIV_SHIFT) & 3;
-ctx->mmu_idx = (ctx->tb_flags & PSW_D ? ctx->privilege : MMU_PHYS_IDX);
+ctx->mmu_idx = (ctx->tb_flags & PSW_D ?
+PRIV_TO_MMU_IDX(ctx->privilege) : MMU_PHYS_IDX);
 
 /* Recover the IAOQ values from the GVA + PRIV.  */
 uint64_t cs_base = ctx->base.tb->cs_base;
-- 
2.41.0




Re: [PATCH v11 0/9] rutabaga_gfx + gfxstream

2023-08-24 Thread Gurchetan Singh
On Wed, Aug 23, 2023 at 4:07 AM Alyssa Ross  wrote:

> Gurchetan Singh  writes:
>
> > - Official "release commits" issued for rutabaga_gfx_ffi,
> >   gfxstream, aemu-base.  For example, see crrev.com/c/4778941
> >
> > - The release commits can make packaging easier, though once
> >   again all known users will likely just build from sources
> >   anyways
>
> It's a small thing, but could there be actual tags, rather than just
> blessed commits?  It'd just make them easier to find, and save a bit of
> time in review for packages.
>

I added:

https://crosvm.dev/book/appendix/rutabaga_gfx.html#latest-releases-for-potential-packaging

Tags are possible, but I want to clarify the use case before packaging.
Where are you thinking of packaging it for (Debian??)? Are you mostly
interested in Wayland passthrough (my guess) or gfxstream too?  Depending
your use case, we may be able to minimize the work involved.


Re: [PATCH v7 6/9] gfxstream + rutabaga: add initial support for gfxstream

2023-08-24 Thread Gurchetan Singh
On Wed, Aug 23, 2023 at 8:03 AM Mark Cave-Ayland <
mark.cave-ayl...@ilande.co.uk> wrote:

> On 17/08/2023 03:23, Gurchetan Singh wrote:
>
> > From: Gurchetan Singh 
> >
> > This adds initial support for gfxstream and cross-domain.  Both
> > features rely on virtio-gpu blob resources and context types, which
> > are also implemented in this patch.
> >
> > gfxstream has a long and illustrious history in Android graphics
> > paravirtualization.  It has been powering graphics in the Android
> > Studio Emulator for more than a decade, which is the main developer
> > platform.
> >
> > Originally conceived by Jesse Hall, it was first known as "EmuGL" [a].
> > The key design characteristic was a 1:1 threading model and
> > auto-generation, which fit nicely with the OpenGLES spec.  It also
> > allowed easy layering with ANGLE on the host, which provides the GLES
> > implementations on Windows or MacOS enviroments.
> >
> > gfxstream has traditionally been maintained by a single engineer, and
> > between 2015 to 2021, the goldfish throne passed to Frank Yang.
> > Historians often remark this glorious reign ("pax gfxstreama" is the
> > academic term) was comparable to that of Augustus and both Queen
> > Elizabeths.  Just to name a few accomplishments in a resplendent
> > panoply: higher versions of GLES, address space graphics, snapshot
> > support and CTS compliant Vulkan [b].
> >
> > One major drawback was the use of out-of-tree goldfish drivers.
> > Android engineers didn't know much about DRM/KMS and especially TTM so
> > a simple guest to host pipe was conceived.
> >
> > Luckily, virtio-gpu 3D started to emerge in 2016 due to the work of
> > the Mesa/virglrenderer communities.  In 2018, the initial virtio-gpu
> > port of gfxstream was done by Cuttlefish enthusiast Alistair Delva.
> > It was a symbol compatible replacement of virglrenderer [c] and named
> > "AVDVirglrenderer".  This implementation forms the basis of the
> > current gfxstream host implementation still in use today.
> >
> > cross-domain support follows a similar arc.  Originally conceived by
> > Wayland aficionado David Reveman and crosvm enjoyer Zach Reizner in
> > 2018, it initially relied on the downstream "virtio-wl" device.
> >
> > In 2020 and 2021, virtio-gpu was extended to include blob resources
> > and multiple timelines by yours truly, features gfxstream/cross-domain
> > both require to function correctly.
> >
> > Right now, we stand at the precipice of a truly fantastic possibility:
> > the Android Emulator powered by upstream QEMU and upstream Linux
> > kernel.  gfxstream will then be packaged properfully, and app
> > developers can even fix gfxstream bugs on their own if they encounter
> > them.
> >
> > It's been quite the ride, my friends.  Where will gfxstream head next,
> > nobody really knows.  I wouldn't be surprised if it's around for
> > another decade, maintained by a new generation of Android graphics
> > enthusiasts.
> >
> > Technical details:
> >- Very simple initial display integration: just used Pixman
> >- Largely, 1:1 mapping of virtio-gpu hypercalls to rutabaga function
> >  calls
> >
> > Next steps for Android VMs:
> >- The next step would be improving display integration and UI
> interfaces
> >  with the goal of the QEMU upstream graphics being in an emulator
> >  release [d].
> >
> > Next steps for Linux VMs for display virtualization:
> >- For widespread distribution, someone needs to package Sommelier or
> the
> >  wayland-proxy-virtwl [e] ideally into Debian main. In addition,
> newer
> >  versions of the Linux kernel come with DRM_VIRTIO_GPU_KMS option,
> >  which allows disabling KMS hypercalls.  If anyone cares enough,
> it'll
> >  probably be possible to build a custom VM variant that uses this
> display
> >  virtualization strategy.
> >
> > [a]
> https://android-review.googlesource.com/c/platform/development/+/34470
> > [b]
> https://android-review.googlesource.com/q/topic:%22vulkan-hostconnection-start%22
> > [c]
> https://android-review.googlesource.com/c/device/generic/goldfish-opengl/+/761927
> > [d] https://developer.android.com/studio/releases/emulator
> > [e] https://github.com/talex5/wayland-proxy-virtwl
> >
> > Signed-off-by: Gurchetan Singh 
> > Tested-by: Alyssa Ross 
> > Tested-by: Emmanouil Pitsidianakis 
> > Reviewed-by: Emmanouil Pitsidianakis 
> > ---
> > v1: Incorported various suggestions by Akihiko Odaki and Bernard Berschow
> >  - Removed GET_VIRTIO_GPU_GL / GET_RUTABAGA macros
> >  - Used error_report(..)
> >  - Used g_autofree to fix leaks on error paths
> >  - Removed unnecessary casts
> >  - added virtio-gpu-pci-rutabaga.c + virtio-vga-rutabaga.c files
> >
> > v2: Incorported various suggestions by Akihiko Odaki, Marc-André Lureau
> and
> >  Bernard Berschow:
> >  - Parenthesis in CHECK macro
> >  - CHECK_RESULT(result, ..) --> CHECK(!result, ..)
> >  - delay until g->parent_obj.enable = 1
> >  - 

Re: [PATCH] block/file-posix: fix update_zones_wp() caller

2023-08-24 Thread Damien Le Moal
On 8/25/23 02:39, Sam Li wrote:
> When the zoned requests that may change wp fail, it needs to
> update only wps of the zones within the range of the requests
> for not disrupting the other in-flight requests. The wp is updated
> successfully after the request completes.
> 
> Fixed the callers with right offset and nr_zones.
> 
> Signed-off-by: Sam Li 
> ---
>  block/file-posix.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/block/file-posix.c b/block/file-posix.c
> index b16e9c21a1..22559d6c2d 100644
> --- a/block/file-posix.c
> +++ b/block/file-posix.c
> @@ -2522,7 +2522,8 @@ out:
>  }
>  } else {
>  if (type & (QEMU_AIO_WRITE | QEMU_AIO_ZONE_APPEND)) {
> -update_zones_wp(bs, s->fd, 0, 1);
> +update_zones_wp(bs, s->fd, offset,
> +ROUND_UP(bytes, bs->bl.zone_size));

Write and zone append operations are not allowed to cross zone boundaries. So I
the number of zones should always be 1. The above changes a number of zones to a
number of bytes, which seems wrong. The correct fix is I think:

update_zones_wp(bs, s->fd, offset, 1);

>  }
>  }
>  
> @@ -3472,7 +3473,7 @@ static int coroutine_fn 
> raw_co_zone_mgmt(BlockDriverState *bs, BlockZoneOp op,
>  len >> BDRV_SECTOR_BITS);
>  ret = raw_thread_pool_submit(handle_aiocb_zone_mgmt, );
>  if (ret != 0) {
> -update_zones_wp(bs, s->fd, offset, i);
> +update_zones_wp(bs, s->fd, offset, nrz);

Same here. Why would you need to update all zones wp ? This will affect zones
that do not have a write error and potentially change there correct in-memory wp
to a wrong value. I think this also should be:

   update_zones_wp(bs, s->fd, offset, 1);

>  error_report("ioctl %s failed %d", op_name, ret);
>  return ret;
>  }

-- 
Damien Le Moal
Western Digital Research




Re: [PATCH v7 5/9] gfxstream + rutabaga prep: added need defintions, fields, and options

2023-08-24 Thread Gurchetan Singh
On Wed, Aug 23, 2023 at 7:32 AM Mark Cave-Ayland <
mark.cave-ayl...@ilande.co.uk> wrote:

> On 17/08/2023 03:23, Gurchetan Singh wrote:
>
> > From: Gurchetan Singh 
> >
> > This modifies the common virtio-gpu.h file have the fields and
> > defintions needed by gfxstream/rutabaga, by VirtioGpuRutabaga.
> >
> > Signed-off-by: Gurchetan Singh 
> > Tested-by: Alyssa Ross 
> > Tested-by: Emmanouil Pitsidianakis 
> > Reviewed-by: Emmanouil Pitsidianakis 
> > ---
> > v1: void *rutabaga --> struct rutabaga *rutabaga (Akihiko)
> >  have a separate rutabaga device instead of using GL device (Bernard)
> >
> > v2: VirtioGpuRutabaga --> VirtIOGPURutabaga (Akihiko)
> >  move MemoryRegionInfo into VirtIOGPURutabaga (Akihiko)
> >  remove 'ctx' field (Akihiko)
> >  remove 'rutabaga_active'
> >
> > v6: remove command from commit message, refer to docs instead (Manos)
> >
> >   include/hw/virtio/virtio-gpu.h | 28 
> >   1 file changed, 28 insertions(+)
> >
> > diff --git a/include/hw/virtio/virtio-gpu.h
> b/include/hw/virtio/virtio-gpu.h
> > index 55973e112f..e2a07e68d9 100644
> > --- a/include/hw/virtio/virtio-gpu.h
> > +++ b/include/hw/virtio/virtio-gpu.h
> > @@ -38,6 +38,9 @@ OBJECT_DECLARE_SIMPLE_TYPE(VirtIOGPUGL, VIRTIO_GPU_GL)
> >   #define TYPE_VHOST_USER_GPU "vhost-user-gpu"
> >   OBJECT_DECLARE_SIMPLE_TYPE(VhostUserGPU, VHOST_USER_GPU)
> >
> > +#define TYPE_VIRTIO_GPU_RUTABAGA "virtio-gpu-rutabaga-device"
> > +OBJECT_DECLARE_SIMPLE_TYPE(VirtIOGPURutabaga, VIRTIO_GPU_RUTABAGA)
> > +
> >   struct virtio_gpu_simple_resource {
> >   uint32_t resource_id;
> >   uint32_t width;
> > @@ -94,6 +97,7 @@ enum virtio_gpu_base_conf_flags {
> >   VIRTIO_GPU_FLAG_DMABUF_ENABLED,
> >   VIRTIO_GPU_FLAG_BLOB_ENABLED,
> >   VIRTIO_GPU_FLAG_CONTEXT_INIT_ENABLED,
> > +VIRTIO_GPU_FLAG_RUTABAGA_ENABLED,
> >   };
> >
> >   #define virtio_gpu_virgl_enabled(_cfg) \
> > @@ -108,6 +112,8 @@ enum virtio_gpu_base_conf_flags {
> >   (_cfg.flags & (1 << VIRTIO_GPU_FLAG_BLOB_ENABLED))
> >   #define virtio_gpu_context_init_enabled(_cfg) \
> >   (_cfg.flags & (1 << VIRTIO_GPU_FLAG_CONTEXT_INIT_ENABLED))
> > +#define virtio_gpu_rutabaga_enabled(_cfg) \
> > +(_cfg.flags & (1 << VIRTIO_GPU_FLAG_RUTABAGA_ENABLED))
> >   #define virtio_gpu_hostmem_enabled(_cfg) \
> >   (_cfg.hostmem > 0)
> >
> > @@ -232,6 +238,28 @@ struct VhostUserGPU {
> >   bool backend_blocked;
> >   };
> >
> > +#define MAX_SLOTS 4096
> > +
> > +struct MemoryRegionInfo {
> > +int used;
> > +MemoryRegion mr;
> > +uint32_t resource_id;
> > +};
> > +
> > +struct rutabaga;
> > +
> > +struct VirtIOGPURutabaga {
> > +struct VirtIOGPU parent_obj;
>
> The QOM macro should define a typedef for you, so you can drop the
> "struct" here.
>
> > +
> > +struct MemoryRegionInfo memory_regions[MAX_SLOTS];
> > +char *capset_names;
> > +char *wayland_socket_path;
> > +char *wsi;
> > +bool headless;
> > +uint32_t num_capsets;
> > +struct rutabaga *rutabaga;
> > +};
> > +
>
> Shouldn't the VIRTIO_GPU_RUTABAGA QOM declaration and this structure be in
> a separate
> virtio-gpu-rutabaga header file which also includes the header defining
> struct
> rutabaga? The fact that you're having to pre-declare struct rutabaga in
> this header
> when rutabaga support is an optional dependency doesn't seem right.
>

It is the prevailing style of the virtio-gpu code.  For example, we do have
"virtio_gpu_virgl_*" functions, vhost-user, and udmabuf stubs in the same
file.  So for now, I didn't add an extra header file in v12.  In the
future, separating out optional dependencies into constituent header files
could be future refactoring/cleanup.


>
> >   #define VIRTIO_GPU_FILL_CMD(out) do {
>  \
> >   size_t s;
>  \
> >   s = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num, 0,
>   \
>
>
> ATB,
>
> Mark.
>
>


[PATCH v12 6/9] gfxstream + rutabaga: add initial support for gfxstream

2023-08-24 Thread Gurchetan Singh
This adds initial support for gfxstream and cross-domain.  Both
features rely on virtio-gpu blob resources and context types, which
are also implemented in this patch.

gfxstream has a long and illustrious history in Android graphics
paravirtualization.  It has been powering graphics in the Android
Studio Emulator for more than a decade, which is the main developer
platform.

Originally conceived by Jesse Hall, it was first known as "EmuGL" [a].
The key design characteristic was a 1:1 threading model and
auto-generation, which fit nicely with the OpenGLES spec.  It also
allowed easy layering with ANGLE on the host, which provides the GLES
implementations on Windows or MacOS enviroments.

gfxstream has traditionally been maintained by a single engineer, and
between 2015 to 2021, the goldfish throne passed to Frank Yang.
Historians often remark this glorious reign ("pax gfxstreama" is the
academic term) was comparable to that of Augustus and both Queen
Elizabeths.  Just to name a few accomplishments in a resplendent
panoply: higher versions of GLES, address space graphics, snapshot
support and CTS compliant Vulkan [b].

One major drawback was the use of out-of-tree goldfish drivers.
Android engineers didn't know much about DRM/KMS and especially TTM so
a simple guest to host pipe was conceived.

Luckily, virtio-gpu 3D started to emerge in 2016 due to the work of
the Mesa/virglrenderer communities.  In 2018, the initial virtio-gpu
port of gfxstream was done by Cuttlefish enthusiast Alistair Delva.
It was a symbol compatible replacement of virglrenderer [c] and named
"AVDVirglrenderer".  This implementation forms the basis of the
current gfxstream host implementation still in use today.

cross-domain support follows a similar arc.  Originally conceived by
Wayland aficionado David Reveman and crosvm enjoyer Zach Reizner in
2018, it initially relied on the downstream "virtio-wl" device.

In 2020 and 2021, virtio-gpu was extended to include blob resources
and multiple timelines by yours truly, features gfxstream/cross-domain
both require to function correctly.

Right now, we stand at the precipice of a truly fantastic possibility:
the Android Emulator powered by upstream QEMU and upstream Linux
kernel.  gfxstream will then be packaged properfully, and app
developers can even fix gfxstream bugs on their own if they encounter
them.

It's been quite the ride, my friends.  Where will gfxstream head next,
nobody really knows.  I wouldn't be surprised if it's around for
another decade, maintained by a new generation of Android graphics
enthusiasts.

Technical details:
  - Very simple initial display integration: just used Pixman
  - Largely, 1:1 mapping of virtio-gpu hypercalls to rutabaga function
calls

Next steps for Android VMs:
  - The next step would be improving display integration and UI interfaces
with the goal of the QEMU upstream graphics being in an emulator
release [d].

Next steps for Linux VMs for display virtualization:
  - For widespread distribution, someone needs to package Sommelier or the
wayland-proxy-virtwl [e] ideally into Debian main. In addition, newer
versions of the Linux kernel come with DRM_VIRTIO_GPU_KMS option,
which allows disabling KMS hypercalls.  If anyone cares enough, it'll
probably be possible to build a custom VM variant that uses this display
virtualization strategy.

[a] https://android-review.googlesource.com/c/platform/development/+/34470
[b] 
https://android-review.googlesource.com/q/topic:%22vulkan-hostconnection-start%22
[c] 
https://android-review.googlesource.com/c/device/generic/goldfish-opengl/+/761927
[d] https://developer.android.com/studio/releases/emulator
[e] https://github.com/talex5/wayland-proxy-virtwl

Signed-off-by: Gurchetan Singh 
Tested-by: Alyssa Ross 
Tested-by: Emmanouil Pitsidianakis 
Reviewed-by: Emmanouil Pitsidianakis 
---
v1: Incorported various suggestions by Akihiko Odaki and Bernard Berschow
- Removed GET_VIRTIO_GPU_GL / GET_RUTABAGA macros
- Used error_report(..)
- Used g_autofree to fix leaks on error paths
- Removed unnecessary casts
- added virtio-gpu-pci-rutabaga.c + virtio-vga-rutabaga.c files

v2: Incorported various suggestions by Akihiko Odaki, Marc-André Lureau and
Bernard Berschow:
- Parenthesis in CHECK macro
- CHECK_RESULT(result, ..) --> CHECK(!result, ..)
- delay until g->parent_obj.enable = 1
- Additional cast fixes
- initialize directly in virtio_gpu_rutabaga_realize(..)
- add debug callback to hook into QEMU error's APIs

v3: Incorporated feedback from Akihiko Odaki and Alyssa Ross:
- Autodetect Wayland socket when not explicitly specified
- Fix map_blob error paths
- Add comment why we need both `res` and `resource` in create blob
- Cast and whitespace fixes
- Big endian check comes before virtio_gpu_rutabaga_init().
- VirtIOVGARUTABAGA --> VirtIOVGARutabaga

v4: Incorporated feedback from Akihiko Odaki and Alyssa Ross:

[PATCH v12 5/9] gfxstream + rutabaga prep: added need defintions, fields, and options

2023-08-24 Thread Gurchetan Singh
This modifies the common virtio-gpu.h file have the fields and
defintions needed by gfxstream/rutabaga, by VirtioGpuRutabaga.

Signed-off-by: Gurchetan Singh 
Tested-by: Alyssa Ross 
Tested-by: Emmanouil Pitsidianakis 
Reviewed-by: Emmanouil Pitsidianakis 
---
v1: void *rutabaga --> struct rutabaga *rutabaga (Akihiko)
have a separate rutabaga device instead of using GL device (Bernard)

v2: VirtioGpuRutabaga --> VirtIOGPURutabaga (Akihiko)
move MemoryRegionInfo into VirtIOGPURutabaga (Akihiko)
remove 'ctx' field (Akihiko)
remove 'rutabaga_active'

v6: remove command from commit message, refer to docs instead (Manos)

v12: Drop unnecessary "struct" (Mark)

 include/hw/virtio/virtio-gpu.h | 28 
 1 file changed, 28 insertions(+)

diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index 55973e112f..de06bcdba4 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -38,6 +38,9 @@ OBJECT_DECLARE_SIMPLE_TYPE(VirtIOGPUGL, VIRTIO_GPU_GL)
 #define TYPE_VHOST_USER_GPU "vhost-user-gpu"
 OBJECT_DECLARE_SIMPLE_TYPE(VhostUserGPU, VHOST_USER_GPU)
 
+#define TYPE_VIRTIO_GPU_RUTABAGA "virtio-gpu-rutabaga-device"
+OBJECT_DECLARE_SIMPLE_TYPE(VirtIOGPURutabaga, VIRTIO_GPU_RUTABAGA)
+
 struct virtio_gpu_simple_resource {
 uint32_t resource_id;
 uint32_t width;
@@ -94,6 +97,7 @@ enum virtio_gpu_base_conf_flags {
 VIRTIO_GPU_FLAG_DMABUF_ENABLED,
 VIRTIO_GPU_FLAG_BLOB_ENABLED,
 VIRTIO_GPU_FLAG_CONTEXT_INIT_ENABLED,
+VIRTIO_GPU_FLAG_RUTABAGA_ENABLED,
 };
 
 #define virtio_gpu_virgl_enabled(_cfg) \
@@ -108,6 +112,8 @@ enum virtio_gpu_base_conf_flags {
 (_cfg.flags & (1 << VIRTIO_GPU_FLAG_BLOB_ENABLED))
 #define virtio_gpu_context_init_enabled(_cfg) \
 (_cfg.flags & (1 << VIRTIO_GPU_FLAG_CONTEXT_INIT_ENABLED))
+#define virtio_gpu_rutabaga_enabled(_cfg) \
+(_cfg.flags & (1 << VIRTIO_GPU_FLAG_RUTABAGA_ENABLED))
 #define virtio_gpu_hostmem_enabled(_cfg) \
 (_cfg.hostmem > 0)
 
@@ -232,6 +238,28 @@ struct VhostUserGPU {
 bool backend_blocked;
 };
 
+#define MAX_SLOTS 4096
+
+struct MemoryRegionInfo {
+int used;
+MemoryRegion mr;
+uint32_t resource_id;
+};
+
+struct rutabaga;
+
+struct VirtIOGPURutabaga {
+VirtIOGPU parent_obj;
+
+struct MemoryRegionInfo memory_regions[MAX_SLOTS];
+char *capset_names;
+char *wayland_socket_path;
+char *wsi;
+bool headless;
+uint32_t num_capsets;
+struct rutabaga *rutabaga;
+};
+
 #define VIRTIO_GPU_FILL_CMD(out) do {   \
 size_t s;   \
 s = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num, 0,  \
-- 
2.42.0.rc2.253.gd59a3bf2b4-goog




[PATCH v12 2/9] virtio-gpu: CONTEXT_INIT feature

2023-08-24 Thread Gurchetan Singh
From: Antonio Caggiano 

The feature can be enabled when a backend wants it.

Signed-off-by: Antonio Caggiano 
Reviewed-by: Marc-André Lureau 
Signed-off-by: Gurchetan Singh 
Tested-by: Alyssa Ross 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Akihiko Odaki 
---
 hw/display/virtio-gpu-base.c   | 3 +++
 include/hw/virtio/virtio-gpu.h | 3 +++
 2 files changed, 6 insertions(+)

diff --git a/hw/display/virtio-gpu-base.c b/hw/display/virtio-gpu-base.c
index ca1fb7b16f..4f2b0ba1f3 100644
--- a/hw/display/virtio-gpu-base.c
+++ b/hw/display/virtio-gpu-base.c
@@ -232,6 +232,9 @@ virtio_gpu_base_get_features(VirtIODevice *vdev, uint64_t 
features,
 if (virtio_gpu_blob_enabled(g->conf)) {
 features |= (1 << VIRTIO_GPU_F_RESOURCE_BLOB);
 }
+if (virtio_gpu_context_init_enabled(g->conf)) {
+features |= (1 << VIRTIO_GPU_F_CONTEXT_INIT);
+}
 
 return features;
 }
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index 390c4642b8..8377c365ef 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -93,6 +93,7 @@ enum virtio_gpu_base_conf_flags {
 VIRTIO_GPU_FLAG_EDID_ENABLED,
 VIRTIO_GPU_FLAG_DMABUF_ENABLED,
 VIRTIO_GPU_FLAG_BLOB_ENABLED,
+VIRTIO_GPU_FLAG_CONTEXT_INIT_ENABLED,
 };
 
 #define virtio_gpu_virgl_enabled(_cfg) \
@@ -105,6 +106,8 @@ enum virtio_gpu_base_conf_flags {
 (_cfg.flags & (1 << VIRTIO_GPU_FLAG_DMABUF_ENABLED))
 #define virtio_gpu_blob_enabled(_cfg) \
 (_cfg.flags & (1 << VIRTIO_GPU_FLAG_BLOB_ENABLED))
+#define virtio_gpu_context_init_enabled(_cfg) \
+(_cfg.flags & (1 << VIRTIO_GPU_FLAG_CONTEXT_INIT_ENABLED))
 
 struct virtio_gpu_base_conf {
 uint32_t max_outputs;
-- 
2.42.0.rc2.253.gd59a3bf2b4-goog




[PATCH v12 8/9] gfxstream + rutabaga: enable rutabaga

2023-08-24 Thread Gurchetan Singh
This change enables rutabaga to receive virtio-gpu-3d hypercalls
when it is active.

Signed-off-by: Gurchetan Singh 
Tested-by: Alyssa Ross 
Tested-by: Emmanouil Pitsidianakis 
Reviewed-by: Emmanouil Pitsidianakis 
---
v3: Whitespace fix (Akihiko)
v9: reorder virtio_gpu_have_udmabuf() after checking if rutabaga
is enabled to avoid spurious warnings (Akihiko)

 hw/display/virtio-gpu-base.c | 3 ++-
 hw/display/virtio-gpu.c  | 5 +++--
 softmmu/qdev-monitor.c   | 3 +++
 softmmu/vl.c | 1 +
 4 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/hw/display/virtio-gpu-base.c b/hw/display/virtio-gpu-base.c
index 4f2b0ba1f3..50c5373b65 100644
--- a/hw/display/virtio-gpu-base.c
+++ b/hw/display/virtio-gpu-base.c
@@ -223,7 +223,8 @@ virtio_gpu_base_get_features(VirtIODevice *vdev, uint64_t 
features,
 {
 VirtIOGPUBase *g = VIRTIO_GPU_BASE(vdev);
 
-if (virtio_gpu_virgl_enabled(g->conf)) {
+if (virtio_gpu_virgl_enabled(g->conf) ||
+virtio_gpu_rutabaga_enabled(g->conf)) {
 features |= (1 << VIRTIO_GPU_F_VIRGL);
 }
 if (virtio_gpu_edid_enabled(g->conf)) {
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 3e658f1fef..fe094addef 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -1361,8 +1361,9 @@ void virtio_gpu_device_realize(DeviceState *qdev, Error 
**errp)
 VirtIOGPU *g = VIRTIO_GPU(qdev);
 
 if (virtio_gpu_blob_enabled(g->parent_obj.conf)) {
-if (!virtio_gpu_have_udmabuf()) {
-error_setg(errp, "cannot enable blob resources without udmabuf");
+if (!virtio_gpu_rutabaga_enabled(g->parent_obj.conf) &&
+!virtio_gpu_have_udmabuf()) {
+error_setg(errp, "need rutabaga or udmabuf for blob resources");
 return;
 }
 
diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c
index 74f4e41338..1b8005ae55 100644
--- a/softmmu/qdev-monitor.c
+++ b/softmmu/qdev-monitor.c
@@ -86,6 +86,9 @@ static const QDevAlias qdev_alias_table[] = {
 { "virtio-gpu-pci", "virtio-gpu", QEMU_ARCH_VIRTIO_PCI },
 { "virtio-gpu-gl-device", "virtio-gpu-gl", QEMU_ARCH_VIRTIO_MMIO },
 { "virtio-gpu-gl-pci", "virtio-gpu-gl", QEMU_ARCH_VIRTIO_PCI },
+{ "virtio-gpu-rutabaga-device", "virtio-gpu-rutabaga",
+  QEMU_ARCH_VIRTIO_MMIO },
+{ "virtio-gpu-rutabaga-pci", "virtio-gpu-rutabaga", QEMU_ARCH_VIRTIO_PCI },
 { "virtio-input-host-device", "virtio-input-host", QEMU_ARCH_VIRTIO_MMIO },
 { "virtio-input-host-ccw", "virtio-input-host", QEMU_ARCH_VIRTIO_CCW },
 { "virtio-input-host-pci", "virtio-input-host", QEMU_ARCH_VIRTIO_PCI },
diff --git a/softmmu/vl.c b/softmmu/vl.c
index b0b96f67fa..2f98eefdf3 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -216,6 +216,7 @@ static struct {
 { .driver = "ati-vga",  .flag = _vga   },
 { .driver = "vhost-user-vga",   .flag = _vga   },
 { .driver = "virtio-vga-gl",.flag = _vga   },
+{ .driver = "virtio-vga-rutabaga",  .flag = _vga   },
 };
 
 static QemuOptsList qemu_rtc_opts = {
-- 
2.42.0.rc2.253.gd59a3bf2b4-goog




[PATCH v12 7/9] gfxstream + rutabaga: meson support

2023-08-24 Thread Gurchetan Singh
- Add meson detection of rutabaga_gfx
- Build virtio-gpu-rutabaga.c + associated vga/pci files when
  present

Signed-off-by: Gurchetan Singh 
Tested-by: Alyssa Ross 
Tested-by: Emmanouil Pitsidianakis 
Reviewed-by: Emmanouil Pitsidianakis 
---
v3: Fix alignment issues (Akihiko)

 hw/display/meson.build| 22 ++
 meson.build   |  7 +++
 meson_options.txt |  2 ++
 scripts/meson-buildoptions.sh |  3 +++
 4 files changed, 34 insertions(+)

diff --git a/hw/display/meson.build b/hw/display/meson.build
index 413ba4ab24..e362d625dd 100644
--- a/hw/display/meson.build
+++ b/hw/display/meson.build
@@ -79,6 +79,13 @@ if config_all_devices.has_key('CONFIG_VIRTIO_GPU')
  if_true: [files('virtio-gpu-gl.c', 
'virtio-gpu-virgl.c'), pixman, virgl])
 hw_display_modules += {'virtio-gpu-gl': virtio_gpu_gl_ss}
   endif
+
+  if rutabaga.found()
+virtio_gpu_rutabaga_ss = ss.source_set()
+virtio_gpu_rutabaga_ss.add(when: ['CONFIG_VIRTIO_GPU', rutabaga],
+   if_true: [files('virtio-gpu-rutabaga.c'), 
pixman])
+hw_display_modules += {'virtio-gpu-rutabaga': virtio_gpu_rutabaga_ss}
+  endif
 endif
 
 if config_all_devices.has_key('CONFIG_VIRTIO_PCI')
@@ -95,6 +102,12 @@ if config_all_devices.has_key('CONFIG_VIRTIO_PCI')
  if_true: [files('virtio-gpu-pci-gl.c'), pixman])
 hw_display_modules += {'virtio-gpu-pci-gl': virtio_gpu_pci_gl_ss}
   endif
+  if rutabaga.found()
+virtio_gpu_pci_rutabaga_ss = ss.source_set()
+virtio_gpu_pci_rutabaga_ss.add(when: ['CONFIG_VIRTIO_GPU', 
'CONFIG_VIRTIO_PCI', rutabaga],
+   if_true: 
[files('virtio-gpu-pci-rutabaga.c'), pixman])
+hw_display_modules += {'virtio-gpu-pci-rutabaga': 
virtio_gpu_pci_rutabaga_ss}
+  endif
 endif
 
 if config_all_devices.has_key('CONFIG_VIRTIO_VGA')
@@ -113,6 +126,15 @@ if config_all_devices.has_key('CONFIG_VIRTIO_VGA')
   virtio_vga_gl_ss.add(when: 'CONFIG_ACPI', if_true: files('acpi-vga.c'),
 if_false: files('acpi-vga-stub.c'))
   hw_display_modules += {'virtio-vga-gl': virtio_vga_gl_ss}
+
+  if rutabaga.found()
+virtio_vga_rutabaga_ss = ss.source_set()
+virtio_vga_rutabaga_ss.add(when: ['CONFIG_VIRTIO_VGA', rutabaga],
+   if_true: [files('virtio-vga-rutabaga.c'), 
pixman])
+virtio_vga_rutabaga_ss.add(when: 'CONFIG_ACPI', if_true: 
files('acpi-vga.c'),
+if_false: 
files('acpi-vga-stub.c'))
+hw_display_modules += {'virtio-vga-rutabaga': virtio_vga_rutabaga_ss}
+  endif
 endif
 
 system_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_lcdc.c'))
diff --git a/meson.build b/meson.build
index 98e68ef0b1..293f388e53 100644
--- a/meson.build
+++ b/meson.build
@@ -1069,6 +1069,12 @@ if not get_option('virglrenderer').auto() or have_system 
or have_vhost_user_gpu
dependencies: virgl))
   endif
 endif
+rutabaga = not_found
+if not get_option('rutabaga_gfx').auto() or have_system or have_vhost_user_gpu
+  rutabaga = dependency('rutabaga_gfx_ffi',
+ method: 'pkg-config',
+ required: get_option('rutabaga_gfx'))
+endif
 blkio = not_found
 if not get_option('blkio').auto() or have_block
   blkio = dependency('blkio',
@@ -4272,6 +4278,7 @@ summary_info += {'libtasn1':  tasn1}
 summary_info += {'PAM':   pam}
 summary_info += {'iconv support': iconv}
 summary_info += {'virgl support': virgl}
+summary_info += {'rutabaga support':  rutabaga}
 summary_info += {'blkio support': blkio}
 summary_info += {'curl support':  curl}
 summary_info += {'Multipath support': mpathpersist}
diff --git a/meson_options.txt b/meson_options.txt
index aaea5ddd77..dea3bf7d9c 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -224,6 +224,8 @@ option('vmnet', type : 'feature', value : 'auto',
description: 'vmnet.framework network backend support')
 option('virglrenderer', type : 'feature', value : 'auto',
description: 'virgl rendering support')
+option('rutabaga_gfx', type : 'feature', value : 'auto',
+   description: 'rutabaga_gfx support')
 option('png', type : 'feature', value : 'auto',
description: 'PNG support with libpng')
 option('vnc', type : 'feature', value : 'auto',
diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
index 9da3fe299b..9a95b4f782 100644
--- a/scripts/meson-buildoptions.sh
+++ b/scripts/meson-buildoptions.sh
@@ -154,6 +154,7 @@ meson_options_help() {
   printf "%s\n" '  rbd Ceph block device driver'
   printf "%s\n" '  rdmaEnable RDMA-based migration'
   printf "%s\n" '  replication replication support'
+  printf "%s\n" '  rutabaga-gfxrutabaga_gfx support'
   printf "%s\n" '  sdl SDL user interface'
   printf "%s\n" '  sdl-image

[PATCH v12 1/9] virtio: Add shared memory capability

2023-08-24 Thread Gurchetan Singh
From: "Dr. David Alan Gilbert" 

Define a new capability type 'VIRTIO_PCI_CAP_SHARED_MEMORY_CFG' to allow
defining shared memory regions with sizes and offsets of 2^32 and more.
Multiple instances of the capability are allowed and distinguished
by a device-specific 'id'.

Signed-off-by: Dr. David Alan Gilbert 
Signed-off-by: Antonio Caggiano 
Reviewed-by: Gurchetan Singh 
Signed-off-by: Gurchetan Singh 
Tested-by: Alyssa Ross 
Acked-by: Huang Rui 
Tested-by: Huang Rui 
Reviewed-by: Akihiko Odaki 
---
 hw/virtio/virtio-pci.c | 18 ++
 include/hw/virtio/virtio-pci.h |  4 
 2 files changed, 22 insertions(+)

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index edbc0daa18..da8c9ea12d 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1435,6 +1435,24 @@ static int virtio_pci_add_mem_cap(VirtIOPCIProxy *proxy,
 return offset;
 }
 
+int virtio_pci_add_shm_cap(VirtIOPCIProxy *proxy,
+   uint8_t bar, uint64_t offset, uint64_t length,
+   uint8_t id)
+{
+struct virtio_pci_cap64 cap = {
+.cap.cap_len = sizeof cap,
+.cap.cfg_type = VIRTIO_PCI_CAP_SHARED_MEMORY_CFG,
+};
+
+cap.cap.bar = bar;
+cap.cap.length = cpu_to_le32(length);
+cap.length_hi = cpu_to_le32(length >> 32);
+cap.cap.offset = cpu_to_le32(offset);
+cap.offset_hi = cpu_to_le32(offset >> 32);
+cap.cap.id = id;
+return virtio_pci_add_mem_cap(proxy, );
+}
+
 static uint64_t virtio_pci_common_read(void *opaque, hwaddr addr,
unsigned size)
 {
diff --git a/include/hw/virtio/virtio-pci.h b/include/hw/virtio/virtio-pci.h
index ab2051b64b..5a3f182f99 100644
--- a/include/hw/virtio/virtio-pci.h
+++ b/include/hw/virtio/virtio-pci.h
@@ -264,4 +264,8 @@ unsigned virtio_pci_optimal_num_queues(unsigned 
fixed_queues);
 void virtio_pci_set_guest_notifier_fd_handler(VirtIODevice *vdev, VirtQueue 
*vq,
   int n, bool assign,
   bool with_irqfd);
+
+int virtio_pci_add_shm_cap(VirtIOPCIProxy *proxy, uint8_t bar, uint64_t offset,
+   uint64_t length, uint8_t id);
+
 #endif
-- 
2.42.0.rc2.253.gd59a3bf2b4-goog




[PATCH v12 0/9] rutabaga_gfx + gfxstream

2023-08-24 Thread Gurchetan Singh
From: Gurchetan Singh 

Prior versions:

Changes since v11:
- Incorporated review feedback

How to build both rutabaga and gfxstream guest/host libs:

https://crosvm.dev/book/appendix/rutabaga_gfx.html

Branch containing this patch series (now on QEMU Gitlab):

https://gitlab.com/gurchetansingh/qemu/-/commits/qemu-gfxstream-v12

Antonio Caggiano (2):
  virtio-gpu: CONTEXT_INIT feature
  virtio-gpu: blob prep

Dr. David Alan Gilbert (1):
  virtio: Add shared memory capability

Gerd Hoffmann (1):
  virtio-gpu: hostmem

Gurchetan Singh (5):
  gfxstream + rutabaga prep: added need defintions, fields, and options
  gfxstream + rutabaga: add initial support for gfxstream
  gfxstream + rutabaga: meson support
  gfxstream + rutabaga: enable rutabaga
  docs/system: add basic virtio-gpu documentation

 docs/system/device-emulation.rst |1 +
 docs/system/devices/virtio-gpu.rst   |  112 +++
 hw/display/meson.build   |   22 +
 hw/display/virtio-gpu-base.c |6 +-
 hw/display/virtio-gpu-pci-rutabaga.c |   47 ++
 hw/display/virtio-gpu-pci.c  |   14 +
 hw/display/virtio-gpu-rutabaga.c | 1119 ++
 hw/display/virtio-gpu.c  |   16 +-
 hw/display/virtio-vga-rutabaga.c |   50 ++
 hw/display/virtio-vga.c  |   33 +-
 hw/virtio/virtio-pci.c   |   18 +
 include/hw/virtio/virtio-gpu-bswap.h |   15 +
 include/hw/virtio/virtio-gpu.h   |   41 +
 include/hw/virtio/virtio-pci.h   |4 +
 meson.build  |7 +
 meson_options.txt|2 +
 scripts/meson-buildoptions.sh|3 +
 softmmu/qdev-monitor.c   |3 +
 softmmu/vl.c |1 +
 19 files changed, 1495 insertions(+), 19 deletions(-)
 create mode 100644 docs/system/devices/virtio-gpu.rst
 create mode 100644 hw/display/virtio-gpu-pci-rutabaga.c
 create mode 100644 hw/display/virtio-gpu-rutabaga.c
 create mode 100644 hw/display/virtio-vga-rutabaga.c

-- 
2.42.0.rc2.253.gd59a3bf2b4-goog




[PATCH v12 9/9] docs/system: add basic virtio-gpu documentation

2023-08-24 Thread Gurchetan Singh
This adds basic documentation for virtio-gpu.

Suggested-by: Akihiko Odaki 
Signed-off-by: Gurchetan Singh 
Tested-by: Alyssa Ross 
Tested-by: Emmanouil Pitsidianakis 
Reviewed-by: Emmanouil Pitsidianakis 

---
v2: - Incorporated suggestions by Akihiko Odaki
- Listed the currently supported capset_names (Bernard)

v3: - Incorporated suggestions by Akihiko Odaki and Alyssa Ross

v4: - Incorporated suggestions by Akihiko Odaki

v5: - Removed pci suffix from examples
- Verified that -device virtio-gpu-rutabaga works.  Strangely
  enough, I don't remember changing anything, and I remember
  it not working.  I did rebase to top of tree though.
- Fixed meson examples in crosvm docs

v8: - Remove different links for "rutabaga_gfx" and
  "gfxstream-enabled rutabaga" (Akihiko)

v11: - Use GPL-2.0-or-later license (Phillippe)

 docs/system/device-emulation.rst   |   1 +
 docs/system/devices/virtio-gpu.rst | 112 +
 2 files changed, 113 insertions(+)
 create mode 100644 docs/system/devices/virtio-gpu.rst

diff --git a/docs/system/device-emulation.rst b/docs/system/device-emulation.rst
index 4491c4cbf7..1167f3a9f2 100644
--- a/docs/system/device-emulation.rst
+++ b/docs/system/device-emulation.rst
@@ -91,6 +91,7 @@ Emulated Devices
devices/nvme.rst
devices/usb.rst
devices/vhost-user.rst
+   devices/virtio-gpu.rst
devices/virtio-pmem.rst
devices/vhost-user-rng.rst
devices/canokey.rst
diff --git a/docs/system/devices/virtio-gpu.rst 
b/docs/system/devices/virtio-gpu.rst
new file mode 100644
index 00..21465e4ce2
--- /dev/null
+++ b/docs/system/devices/virtio-gpu.rst
@@ -0,0 +1,112 @@
+..
+   SPDX-License-Identifier: GPL-2.0-or-later
+
+virtio-gpu
+==
+
+This document explains the setup and usage of the virtio-gpu device.
+The virtio-gpu device paravirtualizes the GPU and display controller.
+
+Linux kernel support
+
+
+virtio-gpu requires a guest Linux kernel built with the
+``CONFIG_DRM_VIRTIO_GPU`` option.
+
+QEMU virtio-gpu variants
+
+
+QEMU virtio-gpu device variants come in the following form:
+
+ * ``virtio-vga[-BACKEND]``
+ * ``virtio-gpu[-BACKEND][-INTERFACE]``
+ * ``vhost-user-vga``
+ * ``vhost-user-pci``
+
+**Backends:** QEMU provides a 2D virtio-gpu backend, and two accelerated
+backends: virglrenderer ('gl' device label) and rutabaga_gfx ('rutabaga'
+device label).  There is a vhost-user backend that runs the graphics stack
+in a separate process for improved isolation.
+
+**Interfaces:** QEMU further categorizes virtio-gpu device variants based
+on the interface exposed to the guest. The interfaces can be classified
+into VGA and non-VGA variants. The VGA ones are prefixed with virtio-vga
+or vhost-user-vga while the non-VGA ones are prefixed with virtio-gpu or
+vhost-user-gpu.
+
+The VGA ones always use the PCI interface, but for the non-VGA ones, the
+user can further pick between MMIO or PCI. For MMIO, the user can suffix
+the device name with -device, though vhost-user-gpu does not support MMIO.
+For PCI, the user can suffix it with -pci. Without these suffixes, the
+platform default will be chosen.
+
+virtio-gpu 2d
+-
+
+The default 2D backend only performs 2D operations. The guest needs to
+employ a software renderer for 3D graphics.
+
+Typically, the software renderer is provided by `Mesa`_ or `SwiftShader`_.
+Mesa's implementations (LLVMpipe, Lavapipe and virgl below) work out of box
+on typical modern Linux distributions.
+
+.. parsed-literal::
+-device virtio-gpu
+
+.. _Mesa: https://www.mesa3d.org/
+.. _SwiftShader: https://github.com/google/swiftshader
+
+virtio-gpu virglrenderer
+
+
+When using virgl accelerated graphics mode in the guest, OpenGL API calls
+are translated into an intermediate representation (see `Gallium3D`_). The
+intermediate representation is communicated to the host and the
+`virglrenderer`_ library on the host translates the intermediate
+representation back to OpenGL API calls.
+
+.. parsed-literal::
+-device virtio-gpu-gl
+
+.. _Gallium3D: https://www.freedesktop.org/wiki/Software/gallium/
+.. _virglrenderer: https://gitlab.freedesktop.org/virgl/virglrenderer/
+
+virtio-gpu rutabaga
+---
+
+virtio-gpu can also leverage rutabaga_gfx to provide `gfxstream`_
+rendering and `Wayland display passthrough`_.  With the gfxstream rendering
+mode, GLES and Vulkan calls are forwarded to the host with minimal
+modification.
+
+The crosvm book provides directions on how to build a `gfxstream-enabled
+rutabaga`_ and launch a `guest Wayland proxy`_.
+
+This device does require host blob support (``hostmem`` field below). The
+``hostmem`` field specifies the size of virtio-gpu host memory window.
+This is typically between 256M and 8G.
+
+At least one capset (see colon separated ``capset_names`` below) must be
+specified when starting the device.  The currently supported
+``capset_names`` are 

[PATCH v12 4/9] virtio-gpu: blob prep

2023-08-24 Thread Gurchetan Singh
From: Antonio Caggiano 

This adds preparatory functions needed to:

 - decode blob cmds
 - tracking iovecs

Signed-off-by: Antonio Caggiano 
Signed-off-by: Dmitry Osipenko 
Signed-off-by: Gurchetan Singh 
Tested-by: Alyssa Ross 
Tested-by: Emmanouil Pitsidianakis 
Reviewed-by: Emmanouil Pitsidianakis 
---
 hw/display/virtio-gpu.c  | 10 +++---
 include/hw/virtio/virtio-gpu-bswap.h | 15 +++
 include/hw/virtio/virtio-gpu.h   |  5 +
 3 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 48ef0d9fad..3e658f1fef 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -33,15 +33,11 @@
 
 #define VIRTIO_GPU_VM_VERSION 1
 
-static struct virtio_gpu_simple_resource*
-virtio_gpu_find_resource(VirtIOGPU *g, uint32_t resource_id);
 static struct virtio_gpu_simple_resource *
 virtio_gpu_find_check_resource(VirtIOGPU *g, uint32_t resource_id,
bool require_backing,
const char *caller, uint32_t *error);
 
-static void virtio_gpu_cleanup_mapping(VirtIOGPU *g,
-   struct virtio_gpu_simple_resource *res);
 static void virtio_gpu_reset_bh(void *opaque);
 
 void virtio_gpu_update_cursor_data(VirtIOGPU *g,
@@ -116,7 +112,7 @@ static void update_cursor(VirtIOGPU *g, struct 
virtio_gpu_update_cursor *cursor)
   cursor->resource_id ? 1 : 0);
 }
 
-static struct virtio_gpu_simple_resource *
+struct virtio_gpu_simple_resource *
 virtio_gpu_find_resource(VirtIOGPU *g, uint32_t resource_id)
 {
 struct virtio_gpu_simple_resource *res;
@@ -904,8 +900,8 @@ void virtio_gpu_cleanup_mapping_iov(VirtIOGPU *g,
 g_free(iov);
 }
 
-static void virtio_gpu_cleanup_mapping(VirtIOGPU *g,
-   struct virtio_gpu_simple_resource *res)
+void virtio_gpu_cleanup_mapping(VirtIOGPU *g,
+struct virtio_gpu_simple_resource *res)
 {
 virtio_gpu_cleanup_mapping_iov(g, res->iov, res->iov_cnt);
 res->iov = NULL;
diff --git a/include/hw/virtio/virtio-gpu-bswap.h 
b/include/hw/virtio/virtio-gpu-bswap.h
index 637a0585d0..dd1975e2d4 100644
--- a/include/hw/virtio/virtio-gpu-bswap.h
+++ b/include/hw/virtio/virtio-gpu-bswap.h
@@ -70,6 +70,21 @@ virtio_gpu_create_blob_bswap(struct 
virtio_gpu_resource_create_blob *cblob)
 le64_to_cpus(>size);
 }
 
+static inline void
+virtio_gpu_map_blob_bswap(struct virtio_gpu_resource_map_blob *mblob)
+{
+virtio_gpu_ctrl_hdr_bswap(>hdr);
+le32_to_cpus(>resource_id);
+le64_to_cpus(>offset);
+}
+
+static inline void
+virtio_gpu_unmap_blob_bswap(struct virtio_gpu_resource_unmap_blob *ublob)
+{
+virtio_gpu_ctrl_hdr_bswap(>hdr);
+le32_to_cpus(>resource_id);
+}
+
 static inline void
 virtio_gpu_scanout_blob_bswap(struct virtio_gpu_set_scanout_blob *ssb)
 {
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index de4f624e94..55973e112f 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -257,6 +257,9 @@ void virtio_gpu_base_fill_display_info(VirtIOGPUBase *g,
 void virtio_gpu_base_generate_edid(VirtIOGPUBase *g, int scanout,
struct virtio_gpu_resp_edid *edid);
 /* virtio-gpu.c */
+struct virtio_gpu_simple_resource *
+virtio_gpu_find_resource(VirtIOGPU *g, uint32_t resource_id);
+
 void virtio_gpu_ctrl_response(VirtIOGPU *g,
   struct virtio_gpu_ctrl_command *cmd,
   struct virtio_gpu_ctrl_hdr *resp,
@@ -275,6 +278,8 @@ int virtio_gpu_create_mapping_iov(VirtIOGPU *g,
   uint32_t *niov);
 void virtio_gpu_cleanup_mapping_iov(VirtIOGPU *g,
 struct iovec *iov, uint32_t count);
+void virtio_gpu_cleanup_mapping(VirtIOGPU *g,
+struct virtio_gpu_simple_resource *res);
 void virtio_gpu_process_cmdq(VirtIOGPU *g);
 void virtio_gpu_device_realize(DeviceState *qdev, Error **errp);
 void virtio_gpu_reset(VirtIODevice *vdev);
-- 
2.42.0.rc2.253.gd59a3bf2b4-goog




[PATCH v12 3/9] virtio-gpu: hostmem

2023-08-24 Thread Gurchetan Singh
From: Gerd Hoffmann 

Use VIRTIO_GPU_SHM_ID_HOST_VISIBLE as id for virtio-gpu.

Signed-off-by: Antonio Caggiano 
Tested-by: Alyssa Ross 
Acked-by: Michael S. Tsirkin 
---
 hw/display/virtio-gpu-pci.c| 14 ++
 hw/display/virtio-gpu.c|  1 +
 hw/display/virtio-vga.c| 33 -
 include/hw/virtio/virtio-gpu.h |  5 +
 4 files changed, 44 insertions(+), 9 deletions(-)

diff --git a/hw/display/virtio-gpu-pci.c b/hw/display/virtio-gpu-pci.c
index 93f214ff58..da6a99f038 100644
--- a/hw/display/virtio-gpu-pci.c
+++ b/hw/display/virtio-gpu-pci.c
@@ -33,6 +33,20 @@ static void virtio_gpu_pci_base_realize(VirtIOPCIProxy 
*vpci_dev, Error **errp)
 DeviceState *vdev = DEVICE(g);
 int i;
 
+if (virtio_gpu_hostmem_enabled(g->conf)) {
+vpci_dev->msix_bar_idx = 1;
+vpci_dev->modern_mem_bar_idx = 2;
+memory_region_init(>hostmem, OBJECT(g), "virtio-gpu-hostmem",
+   g->conf.hostmem);
+pci_register_bar(_dev->pci_dev, 4,
+ PCI_BASE_ADDRESS_SPACE_MEMORY |
+ PCI_BASE_ADDRESS_MEM_PREFETCH |
+ PCI_BASE_ADDRESS_MEM_TYPE_64,
+ >hostmem);
+virtio_pci_add_shm_cap(vpci_dev, 4, 0, g->conf.hostmem,
+   VIRTIO_GPU_SHM_ID_HOST_VISIBLE);
+}
+
 virtio_pci_force_virtio_1(vpci_dev);
 if (!qdev_realize(vdev, BUS(_dev->bus), errp)) {
 return;
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index bbd5c6561a..48ef0d9fad 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -1509,6 +1509,7 @@ static Property virtio_gpu_properties[] = {
  256 * MiB),
 DEFINE_PROP_BIT("blob", VirtIOGPU, parent_obj.conf.flags,
 VIRTIO_GPU_FLAG_BLOB_ENABLED, false),
+DEFINE_PROP_SIZE("hostmem", VirtIOGPU, parent_obj.conf.hostmem, 0),
 DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/display/virtio-vga.c b/hw/display/virtio-vga.c
index e6fb0aa876..c8552ff760 100644
--- a/hw/display/virtio-vga.c
+++ b/hw/display/virtio-vga.c
@@ -115,17 +115,32 @@ static void virtio_vga_base_realize(VirtIOPCIProxy 
*vpci_dev, Error **errp)
 pci_register_bar(_dev->pci_dev, 0,
  PCI_BASE_ADDRESS_MEM_PREFETCH, >vram);
 
-/*
- * Configure virtio bar and regions
- *
- * We use bar #2 for the mmio regions, to be compatible with stdvga.
- * virtio regions are moved to the end of bar #2, to make room for
- * the stdvga mmio registers at the start of bar #2.
- */
-vpci_dev->modern_mem_bar_idx = 2;
-vpci_dev->msix_bar_idx = 4;
 vpci_dev->modern_io_bar_idx = 5;
 
+if (!virtio_gpu_hostmem_enabled(g->conf)) {
+/*
+ * Configure virtio bar and regions
+ *
+ * We use bar #2 for the mmio regions, to be compatible with stdvga.
+ * virtio regions are moved to the end of bar #2, to make room for
+ * the stdvga mmio registers at the start of bar #2.
+ */
+vpci_dev->modern_mem_bar_idx = 2;
+vpci_dev->msix_bar_idx = 4;
+} else {
+vpci_dev->msix_bar_idx = 1;
+vpci_dev->modern_mem_bar_idx = 2;
+memory_region_init(>hostmem, OBJECT(g), "virtio-gpu-hostmem",
+   g->conf.hostmem);
+pci_register_bar(_dev->pci_dev, 4,
+ PCI_BASE_ADDRESS_SPACE_MEMORY |
+ PCI_BASE_ADDRESS_MEM_PREFETCH |
+ PCI_BASE_ADDRESS_MEM_TYPE_64,
+ >hostmem);
+virtio_pci_add_shm_cap(vpci_dev, 4, 0, g->conf.hostmem,
+   VIRTIO_GPU_SHM_ID_HOST_VISIBLE);
+}
+
 if (!(vpci_dev->flags & VIRTIO_PCI_FLAG_PAGE_PER_VQ)) {
 /*
  * with page-per-vq=off there is no padding space we can use
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index 8377c365ef..de4f624e94 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -108,12 +108,15 @@ enum virtio_gpu_base_conf_flags {
 (_cfg.flags & (1 << VIRTIO_GPU_FLAG_BLOB_ENABLED))
 #define virtio_gpu_context_init_enabled(_cfg) \
 (_cfg.flags & (1 << VIRTIO_GPU_FLAG_CONTEXT_INIT_ENABLED))
+#define virtio_gpu_hostmem_enabled(_cfg) \
+(_cfg.hostmem > 0)
 
 struct virtio_gpu_base_conf {
 uint32_t max_outputs;
 uint32_t flags;
 uint32_t xres;
 uint32_t yres;
+uint64_t hostmem;
 };
 
 struct virtio_gpu_ctrl_command {
@@ -137,6 +140,8 @@ struct VirtIOGPUBase {
 int renderer_blocked;
 int enable;
 
+MemoryRegion hostmem;
+
 struct virtio_gpu_scanout scanout[VIRTIO_GPU_MAX_SCANOUTS];
 
 int enabled_output_bitmask;
-- 
2.42.0.rc2.253.gd59a3bf2b4-goog




[PATCH RESEND v8 13/20] target/riscv/cpu.c: use offset in isa_ext_is_enabled/update_enabled

2023-08-24 Thread Daniel Henrique Barboza
We'll have future usage for a function where, given an offset of the
struct RISCVCPUConfig, the flag is updated to a certain val.

Change all existing callers to use edata->ext_enable_offset instead of
'edata'.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 913b64264f..cbf8ceec54 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -162,18 +162,17 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(xventanacondops, PRIV_VERSION_1_12_0, 
ext_XVentanaCondOps),
 };
 
-static bool isa_ext_is_enabled(RISCVCPU *cpu,
-   const struct isa_ext_data *edata)
+static bool isa_ext_is_enabled(RISCVCPU *cpu, uint32_t ext_offset)
 {
-bool *ext_enabled = (void *)>cfg + edata->ext_enable_offset;
+bool *ext_enabled = (void *)>cfg + ext_offset;
 
 return *ext_enabled;
 }
 
-static void isa_ext_update_enabled(RISCVCPU *cpu,
-   const struct isa_ext_data *edata, bool en)
+static void isa_ext_update_enabled(RISCVCPU *cpu, uint32_t ext_offset,
+   bool en)
 {
-bool *ext_enabled = (void *)>cfg + edata->ext_enable_offset;
+bool *ext_enabled = (void *)>cfg + ext_offset;
 
 *ext_enabled = en;
 }
@@ -1045,9 +1044,10 @@ static void 
riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu)
 
 /* Force disable extensions if priv spec version does not match */
 for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
-if (isa_ext_is_enabled(cpu, _edata_arr[i]) &&
+if (isa_ext_is_enabled(cpu, isa_edata_arr[i].ext_enable_offset) &&
 (env->priv_ver < isa_edata_arr[i].min_version)) {
-isa_ext_update_enabled(cpu, _edata_arr[i], false);
+isa_ext_update_enabled(cpu, isa_edata_arr[i].ext_enable_offset,
+   false);
 #ifndef CONFIG_USER_ONLY
 warn_report("disabling %s extension for hart 0x" TARGET_FMT_lx
 " because privilege spec version does not match",
@@ -2337,7 +2337,7 @@ static void riscv_isa_string_ext(RISCVCPU *cpu, char 
**isa_str,
 int i;
 
 for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
-if (isa_ext_is_enabled(cpu, _edata_arr[i])) {
+if (isa_ext_is_enabled(cpu, isa_edata_arr[i].ext_enable_offset)) {
 new = g_strconcat(old, "_", isa_edata_arr[i].name, NULL);
 g_free(old);
 old = new;
-- 
2.41.0




[PATCH RESEND v8 12/20] target/riscv: deprecate the 'any' CPU type

2023-08-24 Thread Daniel Henrique Barboza
The 'any' CPU type was introduced in commit dc5bd18fa5725 ("RISC-V CPU
Core Definition"), being around since the beginning. It's not an easy
CPU to use: it's undocumented and its name doesn't tell users much about
what the CPU is supposed to bring. 'git log' doesn't help us either in
knowing what was the original design of this CPU type.

The closest we have is a comment from Alistair [1] where he recalls from
memory that the 'any' CPU is supposed to behave like the newly added
'max' CPU. He also suggested that the 'any' CPU should be removed.

The default CPUs are rv32 and rv64, so removing the 'any' CPU will have
impact only on users that might have a script that uses '-cpu any'.
And those users are better off using the default CPUs or the new 'max'
CPU.

We would love to just remove the code and be done with it, but one does
not simply remove a feature in QEMU. We'll put the CPU in quarantine
first, letting users know that we have the intent of removing it in the
future.

[1] https://lists.gnu.org/archive/html/qemu-devel/2023-07/msg02891.html

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
---
 docs/about/deprecated.rst | 12 
 target/riscv/cpu.c|  5 +
 2 files changed, 17 insertions(+)

diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
index 92a2bafd2b..4ced7427ac 100644
--- a/docs/about/deprecated.rst
+++ b/docs/about/deprecated.rst
@@ -371,6 +371,18 @@ QEMU's ``vhost`` feature, which would eliminate the high 
latency costs under
 which the 9p ``proxy`` backend currently suffers. However as of to date nobody
 has indicated plans for such kind of reimplementation unfortunately.
 
+RISC-V 'any' CPU type ``-cpu any`` (since 8.2)
+^^
+
+The 'any' CPU type was introduced back in 2018 and has been around since the
+initial RISC-V QEMU port. Its usage has always been unclear: users don't know
+what to expect from a CPU called 'any', and in fact the CPU does not do 
anything
+special that aren't already done by the default CPUs rv32/rv64.
+
+After the introduction of the 'max' CPU type RISC-V now has a good coverage
+of generic CPUs: rv32 and rv64 as default CPUs and 'max' as a feature complete
+CPU for both 32 and 64 bit builds. Users are then discouraged to use the 'any'
+CPU type starting in 8.2.
 
 Block device options
 
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 8dc85f75bb..913b64264f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1522,6 +1522,11 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
 Error *local_err = NULL;
 
+if (object_dynamic_cast(OBJECT(dev), TYPE_RISCV_CPU_ANY) != NULL) {
+warn_report("The 'any' CPU is deprecated and will be "
+"removed in the future.");
+}
+
 cpu_exec_realizefn(cs, _err);
 if (local_err != NULL) {
 error_propagate(errp, local_err);
-- 
2.41.0




[PATCH RESEND v8 14/20] target/riscv: make CPUCFG() macro public

2023-08-24 Thread Daniel Henrique Barboza
The RISC-V KVM driver uses a CPUCFG() macro that calculates the offset
of a certain field in the struct RISCVCPUConfig. We're going to use this
macro in target/riscv/cpu.c as well in the next patches. Make it public.

Rename it to CPU_CFG_OFFSET() for more clarity while we're at it.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.c | 2 +-
 target/riscv/cpu.h | 2 ++
 target/riscv/kvm.c | 8 +++-
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index cbf8ceec54..ddbf82f859 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -48,7 +48,7 @@ struct isa_ext_data {
 };
 
 #define ISA_EXT_DATA_ENTRY(_name, _min_ver, _prop) \
-{#_name, _min_ver, offsetof(struct RISCVCPUConfig, _prop)}
+{#_name, _min_ver, CPU_CFG_OFFSET(_prop)}
 
 /*
  * From vector_helper.c
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 6ea22e0eea..577abcd724 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -62,6 +62,8 @@
 const char *riscv_get_misa_ext_name(uint32_t bit);
 const char *riscv_get_misa_ext_description(uint32_t bit);
 
+#define CPU_CFG_OFFSET(_prop) offsetof(struct RISCVCPUConfig, _prop)
+
 /* Privileged specification version */
 enum {
 PRIV_VERSION_1_10_0 = 0,
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
index faee8536ef..7c6dec05e3 100644
--- a/target/riscv/kvm.c
+++ b/target/riscv/kvm.c
@@ -200,10 +200,8 @@ static void kvm_riscv_update_cpu_misa_ext(RISCVCPU *cpu, 
CPUState *cs)
 }
 }
 
-#define CPUCFG(_prop) offsetof(struct RISCVCPUConfig, _prop)
-
 #define KVM_EXT_CFG(_name, _prop, _reg_id) \
-{.name = _name, .offset = CPUCFG(_prop), \
+{.name = _name, .offset = CPU_CFG_OFFSET(_prop), \
  .kvm_reg_id = _reg_id}
 
 static KVMCPUConfig kvm_multi_ext_cfgs[] = {
@@ -280,13 +278,13 @@ static void kvm_cpu_set_multi_ext_cfg(Object *obj, 
Visitor *v,
 
 static KVMCPUConfig kvm_cbom_blocksize = {
 .name = "cbom_blocksize",
-.offset = CPUCFG(cbom_blocksize),
+.offset = CPU_CFG_OFFSET(cbom_blocksize),
 .kvm_reg_id = KVM_REG_RISCV_CONFIG_REG(zicbom_block_size)
 };
 
 static KVMCPUConfig kvm_cboz_blocksize = {
 .name = "cboz_blocksize",
-.offset = CPUCFG(cboz_blocksize),
+.offset = CPU_CFG_OFFSET(cboz_blocksize),
 .kvm_reg_id = KVM_REG_RISCV_CONFIG_REG(zicboz_block_size)
 };
 
-- 
2.41.0




[PATCH RESEND v8 19/20] target/riscv/cpu.c: honor user choice in cpu_cfg_ext_auto_update()

2023-08-24 Thread Daniel Henrique Barboza
Add a new cpu_cfg_ext_is_user_set() helper to check if an extension was
set by the user in the command line. Use it inside
cpu_cfg_ext_auto_update() to verify if the user set a certain extension
and, if that's the case, do not change its value.

This will make us honor user choice instead of overwriting the values.
Users will then be informed whether they're using an incompatible set of
extensions instead of QEMU setting a magic value that works.

For example, we'll now error out if the user explictly set 'zce' to true
and 'zca' to false:

$ ./build/qemu-system-riscv64 -M virt -cpu rv64,zce=true,zca=false -nographic
qemu-system-riscv64: Zcf/Zcd/Zcb/Zcmp/Zcmt extensions require Zca extension

This didn't happen before because we were enabling 'zca' if 'zce' was enabled
regardless if the user explictly set 'zca' to false.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index ae8c35402f..e07b2c73e7 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -196,6 +196,12 @@ static int cpu_cfg_ext_get_min_version(uint32_t ext_offset)
 return PRIV_VERSION_1_10_0;
 }
 
+static bool cpu_cfg_ext_is_user_set(uint32_t ext_offset)
+{
+return g_hash_table_contains(multi_ext_user_opts,
+ GUINT_TO_POINTER(ext_offset));
+}
+
 static void cpu_cfg_ext_auto_update(RISCVCPU *cpu, uint32_t ext_offset,
 bool value)
 {
@@ -207,6 +213,10 @@ static void cpu_cfg_ext_auto_update(RISCVCPU *cpu, 
uint32_t ext_offset,
 return;
 }
 
+if (cpu_cfg_ext_is_user_set(ext_offset)) {
+return;
+}
+
 if (value && env->priv_ver != PRIV_VERSION_LATEST) {
 /* Do not enable it if priv_ver is older than min_version */
 min_version = cpu_cfg_ext_get_min_version(ext_offset);
-- 
2.41.0




[PATCH RESEND v8 16/20] target/riscv/cpu.c: use cpu_cfg_ext_auto_update() during realize()

2023-08-24 Thread Daniel Henrique Barboza
Let's change the other instances in realize() where we're enabling an
extension based on a certain criteria (e.g. it's a dependency of another
extension).

We're leaving icsr and ifencei being enabled during RVG for later -
we'll want to error out in that case. Every other extension enablement
during realize is now done via cpu_cfg_ext_auto_update().

The end goal is that only cpu init() functions will handle extension
flags directly via "cpu->cfg.ext_N = true|false".

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.c | 50 +++---
 1 file changed, 25 insertions(+), 25 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index c56abf8395..0fe2ce0add 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1194,7 +1194,7 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, 
Error **errp)
 }
 
 if (cpu->cfg.ext_zfh) {
-cpu->cfg.ext_zfhmin = true;
+cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zfhmin), true);
 }
 
 if (cpu->cfg.ext_zfhmin && !riscv_has_ext(env, RVF)) {
@@ -1220,17 +1220,17 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, 
Error **errp)
 }
 
 /* The V vector extension depends on the Zve64d extension */
-cpu->cfg.ext_zve64d = true;
+cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve64d), true);
 }
 
 /* The Zve64d extension depends on the Zve64f extension */
 if (cpu->cfg.ext_zve64d) {
-cpu->cfg.ext_zve64f = true;
+cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve64f), true);
 }
 
 /* The Zve64f extension depends on the Zve32f extension */
 if (cpu->cfg.ext_zve64f) {
-cpu->cfg.ext_zve32f = true;
+cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve32f), true);
 }
 
 if (cpu->cfg.ext_zve64d && !riscv_has_ext(env, RVD)) {
@@ -1244,7 +1244,7 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, 
Error **errp)
 }
 
 if (cpu->cfg.ext_zvfh) {
-cpu->cfg.ext_zvfhmin = true;
+cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zvfhmin), true);
 }
 
 if (cpu->cfg.ext_zvfhmin && !cpu->cfg.ext_zve32f) {
@@ -1274,7 +1274,7 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, 
Error **errp)
 
 /* Set the ISA extensions, checks should have happened above */
 if (cpu->cfg.ext_zhinx) {
-cpu->cfg.ext_zhinxmin = true;
+cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zca), true);
 }
 
 if ((cpu->cfg.ext_zdinx || cpu->cfg.ext_zhinxmin) && !cpu->cfg.ext_zfinx) {
@@ -1295,12 +1295,12 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, 
Error **errp)
 }
 
 if (cpu->cfg.ext_zce) {
-cpu->cfg.ext_zca = true;
-cpu->cfg.ext_zcb = true;
-cpu->cfg.ext_zcmp = true;
-cpu->cfg.ext_zcmt = true;
+cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zca), true);
+cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zcb), true);
+cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zcmp), true);
+cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zcmt), true);
 if (riscv_has_ext(env, RVF) && env->misa_mxl_max == MXL_RV32) {
-cpu->cfg.ext_zcf = true;
+cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zcf), true);
 }
 }
 
@@ -1368,26 +1368,26 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, 
Error **errp)
 }
 
 if (cpu->cfg.ext_zk) {
-cpu->cfg.ext_zkn = true;
-cpu->cfg.ext_zkr = true;
-cpu->cfg.ext_zkt = true;
+cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zkn), true);
+cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zkr), true);
+cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zkt), true);
 }
 
 if (cpu->cfg.ext_zkn) {
-cpu->cfg.ext_zbkb = true;
-cpu->cfg.ext_zbkc = true;
-cpu->cfg.ext_zbkx = true;
-cpu->cfg.ext_zkne = true;
-cpu->cfg.ext_zknd = true;
-cpu->cfg.ext_zknh = true;
+cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zbkb), true);
+cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zbkc), true);
+cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zbkx), true);
+cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zkne), true);
+cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zknd), true);
+cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zknh), true);
 }
 
 if (cpu->cfg.ext_zks) {
-cpu->cfg.ext_zbkb = true;
-cpu->cfg.ext_zbkc = true;
-cpu->cfg.ext_zbkx = true;
-cpu->cfg.ext_zksed = true;
-cpu->cfg.ext_zksh = true;
+cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zbkb), true);
+cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zbkc), true);
+cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zbkx), true);
+cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zksed), true);
+

[PATCH RESEND v8 07/20] target/riscv/cpu.c: add riscv_cpu_add_qdev_prop_array()

2023-08-24 Thread Daniel Henrique Barboza
The code inside riscv_cpu_add_user_properties() became quite repetitive
after recent changes. Add a helper to hide the repetition away.

Signed-off-by: Daniel Henrique Barboza 
---
 target/riscv/cpu.c | 27 +++
 1 file changed, 11 insertions(+), 16 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 668522db01..4608fa2378 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1946,6 +1946,13 @@ static void cpu_set_cfg_unavailable(Object *obj, Visitor 
*v,
 }
 #endif
 
+static void riscv_cpu_add_qdev_prop_array(DeviceState *dev, Property *array)
+{
+for (Property *prop = array; prop && prop->name; prop++) {
+qdev_property_add_static(dev, prop);
+}
+}
+
 #ifndef CONFIG_USER_ONLY
 static void riscv_cpu_add_kvm_unavail_prop(Object *obj, const char *prop_name)
 {
@@ -2002,7 +2009,6 @@ static void riscv_cpu_add_kvm_properties(Object *obj)
  */
 static void riscv_cpu_add_user_properties(Object *obj)
 {
-Property *prop;
 DeviceState *dev = DEVICE(obj);
 
 #ifndef CONFIG_USER_ONLY
@@ -2016,21 +2022,10 @@ static void riscv_cpu_add_user_properties(Object *obj)
 
 riscv_cpu_add_misa_properties(obj);
 
-for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
-qdev_property_add_static(dev, prop);
-}
-
-for (prop = riscv_cpu_options; prop && prop->name; prop++) {
-qdev_property_add_static(dev, prop);
-}
-
-for (prop = riscv_cpu_vendor_exts; prop && prop->name; prop++) {
-qdev_property_add_static(dev, prop);
-}
-
-for (prop = riscv_cpu_experimental_exts; prop && prop->name; prop++) {
-qdev_property_add_static(dev, prop);
-}
+riscv_cpu_add_qdev_prop_array(dev, riscv_cpu_extensions);
+riscv_cpu_add_qdev_prop_array(dev, riscv_cpu_options);
+riscv_cpu_add_qdev_prop_array(dev, riscv_cpu_vendor_exts);
+riscv_cpu_add_qdev_prop_array(dev, riscv_cpu_experimental_exts);
 }
 
 static Property riscv_cpu_properties[] = {
-- 
2.41.0




[PATCH RESEND v8 18/20] target/riscv: use isa_ext_update_enabled() in init_max_cpu_extensions()

2023-08-24 Thread Daniel Henrique Barboza
Before adding support to detect if an extension was user set we need to
handle how we're enabling extensions in riscv_init_max_cpu_extensions().
object_property_set_bool() calls the set() callback for the property,
and we're going to use this callback to set the 'multi_ext_user_opts'
hash.

This means that, as is today, all extensions we're setting for the 'max'
CPU will be seen as user set in the future. Let's change set_bool() to
isa_ext_update_enabled() that will just enable/disable the flag on a
certain offset.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index adfe671bd4..ae8c35402f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -2163,24 +2163,24 @@ static void riscv_init_max_cpu_extensions(Object *obj)
 set_misa(env, env->misa_mxl, env->misa_ext | RVG | RVJ | RVV);
 
 for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
-object_property_set_bool(obj, prop->name, true, NULL);
+isa_ext_update_enabled(cpu, prop->offset, true);
 }
 
 /* set vector version */
 env->vext_ver = VEXT_VERSION_1_00_0;
 
 /* Zfinx is not compatible with F. Disable it */
-object_property_set_bool(obj, "zfinx", false, NULL);
-object_property_set_bool(obj, "zdinx", false, NULL);
-object_property_set_bool(obj, "zhinx", false, NULL);
-object_property_set_bool(obj, "zhinxmin", false, NULL);
+isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zfinx), false);
+isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zdinx), false);
+isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zhinx), false);
+isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zhinxmin), false);
 
-object_property_set_bool(obj, "zce", false, NULL);
-object_property_set_bool(obj, "zcmp", false, NULL);
-object_property_set_bool(obj, "zcmt", false, NULL);
+isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zce), false);
+isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zcmp), false);
+isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zcmt), false);
 
 if (env->misa_mxl != MXL_RV32) {
-object_property_set_bool(obj, "zcf", false, NULL);
+isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zcf), false);
 }
 }
 
-- 
2.41.0




[PATCH RESEND v8 11/20] avocado, risc-v: add opensbi tests for 'max' CPU

2023-08-24 Thread Daniel Henrique Barboza
Add smoke tests to ensure that we'll not break the 'max' CPU type when
adding new ratified extensions to be enabled.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
---
 tests/avocado/riscv_opensbi.py | 16 
 1 file changed, 16 insertions(+)

diff --git a/tests/avocado/riscv_opensbi.py b/tests/avocado/riscv_opensbi.py
index bfff9cc3c3..15fd57fe51 100644
--- a/tests/avocado/riscv_opensbi.py
+++ b/tests/avocado/riscv_opensbi.py
@@ -61,3 +61,19 @@ def test_riscv64_virt(self):
 :avocado: tags=machine:virt
 """
 self.boot_opensbi()
+
+def test_riscv32_virt_maxcpu(self):
+"""
+:avocado: tags=arch:riscv32
+:avocado: tags=machine:virt
+:avocado: tags=cpu:max
+"""
+self.boot_opensbi()
+
+def test_riscv64_virt_maxcpu(self):
+"""
+:avocado: tags=arch:riscv64
+:avocado: tags=machine:virt
+:avocado: tags=cpu:max
+"""
+self.boot_opensbi()
-- 
2.41.0




[PATCH RESEND v8 02/20] target/riscv/cpu.c: skip 'bool' check when filtering KVM props

2023-08-24 Thread Daniel Henrique Barboza
After the introduction of riscv_cpu_options[] all properties in
riscv_cpu_extensions[] are booleans. This check is now obsolete.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.c | 14 --
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 6a4f95991d..6aac3ba1d1 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1970,17 +1970,11 @@ static void riscv_cpu_add_user_properties(Object *obj)
  * Set the default to disabled for every extension
  * unknown to KVM and error out if the user attempts
  * to enable any of them.
- *
- * We're giving a pass for non-bool properties since they're
- * not related to the availability of extensions and can be
- * safely ignored as is.
  */
-if (prop->info == _prop_bool) {
-object_property_add(obj, prop->name, "bool",
-NULL, cpu_set_cfg_unavailable,
-NULL, (void *)prop->name);
-continue;
-}
+object_property_add(obj, prop->name, "bool",
+NULL, cpu_set_cfg_unavailable,
+NULL, (void *)prop->name);
+continue;
 }
 #endif
 qdev_property_add_static(dev, prop);
-- 
2.41.0




[PATCH RESEND v8 06/20] target/riscv/cpu.c: split vendor exts from riscv_cpu_extensions[]

2023-08-24 Thread Daniel Henrique Barboza
Our goal is to make riscv_cpu_extensions[] hold only ratified,
non-vendor extensions.

Create a new riscv_cpu_vendor_exts[] array for them, changing
riscv_cpu_add_user_properties() and riscv_cpu_add_kvm_properties()
accordingly.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.c | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 78eb2ac6bd..668522db01 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1860,7 +1860,10 @@ static Property riscv_cpu_extensions[] = {
 DEFINE_PROP_BOOL("zcmp", RISCVCPU, cfg.ext_zcmp, false),
 DEFINE_PROP_BOOL("zcmt", RISCVCPU, cfg.ext_zcmt, false),
 
-/* Vendor-specific custom extensions */
+DEFINE_PROP_END_OF_LIST(),
+};
+
+static Property riscv_cpu_vendor_exts[] = {
 DEFINE_PROP_BOOL("xtheadba", RISCVCPU, cfg.ext_xtheadba, false),
 DEFINE_PROP_BOOL("xtheadbb", RISCVCPU, cfg.ext_xtheadbb, false),
 DEFINE_PROP_BOOL("xtheadbs", RISCVCPU, cfg.ext_xtheadbs, false),
@@ -1973,6 +1976,10 @@ static void riscv_cpu_add_kvm_properties(Object *obj)
 riscv_cpu_add_kvm_unavail_prop(obj, prop->name);
 }
 
+for (prop = riscv_cpu_vendor_exts; prop && prop->name; prop++) {
+riscv_cpu_add_kvm_unavail_prop(obj, prop->name);
+}
+
 for (prop = riscv_cpu_experimental_exts; prop && prop->name; prop++) {
 riscv_cpu_add_kvm_unavail_prop(obj, prop->name);
 }
@@ -2017,6 +2024,10 @@ static void riscv_cpu_add_user_properties(Object *obj)
 qdev_property_add_static(dev, prop);
 }
 
+for (prop = riscv_cpu_vendor_exts; prop && prop->name; prop++) {
+qdev_property_add_static(dev, prop);
+}
+
 for (prop = riscv_cpu_experimental_exts; prop && prop->name; prop++) {
 qdev_property_add_static(dev, prop);
 }
-- 
2.41.0




[PATCH RESEND v8 10/20] target/riscv: add 'max' CPU type

2023-08-24 Thread Daniel Henrique Barboza
The 'max' CPU type is used by tooling to determine what's the most
capable CPU a current QEMU version implements. Other archs such as ARM
implements this type. Let's add it to RISC-V.

What we consider "most capable CPU" in this context are related to
ratified, non-vendor extensions. This means that we want the 'max' CPU
to enable all (possible) ratified extensions by default. The reasoning
behind this design is (1) vendor extensions can conflict with each other
and we won't play favorities deciding which one is default or not and
(2) non-ratified extensions are always prone to changes, not being
stable enough to be enabled by default.

All this said, we're still not able to enable all ratified extensions
due to conflicts between them. Zfinx and all its dependencies aren't
enabled because of a conflict with RVF. zce, zcmp and zcmt are also
disabled due to RVD conflicts. When running with 64 bits we're also
disabling zcf.

MISA bits RVG, RVJ and RVV are also being set manually since they're
default disabled.

This is the resulting 'riscv,isa' DT for this new CPU:

rv64imafdcvh_zicbom_zicboz_zicsr_zifencei_zihintpause_zawrs_zfa_
zfh_zfhmin_zca_zcb_zcd_zba_zbb_zbc_zbkb_zbkc_zbkx_zbs_zk_zkn_zknd_
zkne_zknh_zkr_zks_zksed_zksh_zkt_zve32f_zve64f_zve64d_
smstateen_sscofpmf_sstc_svadu_svinval_svnapot_svpbmt

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Weiwei Li 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu-qom.h |  1 +
 target/riscv/cpu.c | 56 ++
 2 files changed, 57 insertions(+)

diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
index 04af50983e..f3fbe37a2c 100644
--- a/target/riscv/cpu-qom.h
+++ b/target/riscv/cpu-qom.h
@@ -30,6 +30,7 @@
 #define CPU_RESOLVING_TYPE TYPE_RISCV_CPU
 
 #define TYPE_RISCV_CPU_ANY  RISCV_CPU_TYPE_NAME("any")
+#define TYPE_RISCV_CPU_MAX  RISCV_CPU_TYPE_NAME("max")
 #define TYPE_RISCV_CPU_BASE32   RISCV_CPU_TYPE_NAME("rv32")
 #define TYPE_RISCV_CPU_BASE64   RISCV_CPU_TYPE_NAME("rv64")
 #define TYPE_RISCV_CPU_BASE128  RISCV_CPU_TYPE_NAME("x-rv128")
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 5eb2d7f6da..8dc85f75bb 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -259,6 +259,7 @@ static const char * const riscv_intr_names[] = {
 };
 
 static void riscv_cpu_add_user_properties(Object *obj);
+static void riscv_init_max_cpu_extensions(Object *obj);
 
 const char *riscv_cpu_get_trap_name(target_ulong cause, bool async)
 {
@@ -396,6 +397,25 @@ static void riscv_any_cpu_init(Object *obj)
 cpu->cfg.pmp = true;
 }
 
+static void riscv_max_cpu_init(Object *obj)
+{
+RISCVCPU *cpu = RISCV_CPU(obj);
+CPURISCVState *env = >env;
+RISCVMXL mlx = MXL_RV64;
+
+#ifdef TARGET_RISCV32
+mlx = MXL_RV32;
+#endif
+set_misa(env, mlx, 0);
+riscv_cpu_add_user_properties(obj);
+riscv_init_max_cpu_extensions(obj);
+env->priv_ver = PRIV_VERSION_LATEST;
+#ifndef CONFIG_USER_ONLY
+set_satp_mode_max_supported(RISCV_CPU(obj), mlx == MXL_RV32 ?
+VM_1_10_SV32 : VM_1_10_SV57);
+#endif
+}
+
 #if defined(TARGET_RISCV64)
 static void rv64_base_cpu_init(Object *obj)
 {
@@ -2027,6 +2047,41 @@ static void riscv_cpu_add_user_properties(Object *obj)
 riscv_cpu_add_qdev_prop_array(dev, riscv_cpu_experimental_exts);
 }
 
+/*
+ * The 'max' type CPU will have all possible ratified
+ * non-vendor extensions enabled.
+ */
+static void riscv_init_max_cpu_extensions(Object *obj)
+{
+RISCVCPU *cpu = RISCV_CPU(obj);
+CPURISCVState *env = >env;
+Property *prop;
+
+/* Enable RVG, RVJ and RVV that are disabled by default */
+set_misa(env, env->misa_mxl, env->misa_ext | RVG | RVJ | RVV);
+
+for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
+object_property_set_bool(obj, prop->name, true, NULL);
+}
+
+/* set vector version */
+env->vext_ver = VEXT_VERSION_1_00_0;
+
+/* Zfinx is not compatible with F. Disable it */
+object_property_set_bool(obj, "zfinx", false, NULL);
+object_property_set_bool(obj, "zdinx", false, NULL);
+object_property_set_bool(obj, "zhinx", false, NULL);
+object_property_set_bool(obj, "zhinxmin", false, NULL);
+
+object_property_set_bool(obj, "zce", false, NULL);
+object_property_set_bool(obj, "zcmp", false, NULL);
+object_property_set_bool(obj, "zcmt", false, NULL);
+
+if (env->misa_mxl != MXL_RV32) {
+object_property_set_bool(obj, "zcf", false, NULL);
+}
+}
+
 static Property riscv_cpu_properties[] = {
 DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, true),
 
@@ -2365,6 +2420,7 @@ static const TypeInfo riscv_cpu_type_infos[] = {
 .abstract = true,
 },
 DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_ANY,  riscv_any_cpu_init),
+DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_MAX,  riscv_max_cpu_init),
 #if defined(CONFIG_KVM)
 DEFINE_CPU(TYPE_RISCV_CPU_HOST, riscv_host_cpu_init),
 

[PATCH RESEND v8 05/20] target/riscv/cpu.c: split non-ratified exts from riscv_cpu_extensions[]

2023-08-24 Thread Daniel Henrique Barboza
Create a new riscv_cpu_experimental_exts[] to store the non-ratified
extensions properties. Once they are ratified we'll move them back to
riscv_cpu_extensions[].

riscv_cpu_add_user_properties() and riscv_cpu_add_kvm_properties() are
changed to keep adding non-ratified properties to users.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.c | 14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 272edaadf0..78eb2ac6bd 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1874,7 +1874,11 @@ static Property riscv_cpu_extensions[] = {
 DEFINE_PROP_BOOL("xtheadsync", RISCVCPU, cfg.ext_xtheadsync, false),
 DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, 
false),
 
-/* These are experimental so mark with 'x-' */
+DEFINE_PROP_END_OF_LIST(),
+};
+
+/* These are experimental so mark with 'x-' */
+static Property riscv_cpu_experimental_exts[] = {
 DEFINE_PROP_BOOL("x-zicond", RISCVCPU, cfg.ext_zicond, false),
 
 /* ePMP 0.9.3 */
@@ -1969,6 +1973,10 @@ static void riscv_cpu_add_kvm_properties(Object *obj)
 riscv_cpu_add_kvm_unavail_prop(obj, prop->name);
 }
 
+for (prop = riscv_cpu_experimental_exts; prop && prop->name; prop++) {
+riscv_cpu_add_kvm_unavail_prop(obj, prop->name);
+}
+
 for (prop = riscv_cpu_options; prop && prop->name; prop++) {
 /* Check if KVM created the property already */
 if (object_property_find(obj, prop->name)) {
@@ -2008,6 +2016,10 @@ static void riscv_cpu_add_user_properties(Object *obj)
 for (prop = riscv_cpu_options; prop && prop->name; prop++) {
 qdev_property_add_static(dev, prop);
 }
+
+for (prop = riscv_cpu_experimental_exts; prop && prop->name; prop++) {
+qdev_property_add_static(dev, prop);
+}
 }
 
 static Property riscv_cpu_properties[] = {
-- 
2.41.0




[PATCH RESEND v8 20/20] target/riscv/cpu.c: consider user option with RVG

2023-08-24 Thread Daniel Henrique Barboza
Enabling RVG will enable a set of extensions that we're not checking if
the user was okay enabling or not. And in this case we want to error
out, instead of ignoring, otherwise we will be inconsistent enabling RVG
without all its extensions.

After this patch, disabling ifencei or icsr while enabling RVG will
result in error:

$ ./build/qemu-system-riscv64 -M virt -cpu rv64,g=true,Zifencei=false 
--nographic
qemu-system-riscv64: warning: Setting G will also set IMAFD_Zicsr_Zifencei
qemu-system-riscv64: RVG requires Zifencei but user set Zifencei to false

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.c | 18 --
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index e07b2c73e7..21ebdbf084 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1155,8 +1155,22 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, 
Error **errp)
   riscv_has_ext(env, RVD) &&
   cpu->cfg.ext_icsr && cpu->cfg.ext_ifencei)) {
 warn_report("Setting G will also set IMAFD_Zicsr_Zifencei");
-cpu->cfg.ext_icsr = true;
-cpu->cfg.ext_ifencei = true;
+
+if (cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_icsr)) &&
+!cpu->cfg.ext_icsr) {
+error_setg(errp, "RVG requires Zicsr but user set Zicsr to false");
+return;
+}
+
+if (cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_ifencei)) &&
+!cpu->cfg.ext_ifencei) {
+error_setg(errp, "RVG requires Zifencei but user set "
+   "Zifencei to false");
+return;
+}
+
+cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_icsr), true);
+cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_ifencei), true);
 
 env->misa_ext |= RVI | RVM | RVA | RVF | RVD;
 env->misa_ext_mask |= RVI | RVM | RVA | RVF | RVD;
-- 
2.41.0




[PATCH RESEND v8 15/20] target/riscv/cpu.c: introduce cpu_cfg_ext_auto_update()

2023-08-24 Thread Daniel Henrique Barboza
During realize() time we're activating a lot of extensions based on some
criteria, e.g.:

if (cpu->cfg.ext_zk) {
cpu->cfg.ext_zkn = true;
cpu->cfg.ext_zkr = true;
cpu->cfg.ext_zkt = true;
}

This practice resulted in at least one case where we ended up enabling
something we shouldn't: RVC enabling zca/zcd/zcf when using a CPU that
has priv_spec older than 1.12.0.

We're also not considering user choice. There's no way of doing it now
but this is about to change in the next few patches.

cpu_cfg_ext_auto_update() will check for priv version mismatches before
enabling extensions. If we have a mismatch between the current priv
version and the extension we want to enable, do not enable it. In the
near future, this same function will also consider user choice when
deciding if we're going to enable/disable an extension or not.

For now let's use it to handle zca/zcd/zcf enablement if RVC is enabled.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.c | 44 +---
 1 file changed, 41 insertions(+), 3 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index ddbf82f859..c56abf8395 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -177,6 +177,44 @@ static void isa_ext_update_enabled(RISCVCPU *cpu, uint32_t 
ext_offset,
 *ext_enabled = en;
 }
 
+static int cpu_cfg_ext_get_min_version(uint32_t ext_offset)
+{
+int i;
+
+for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
+if (isa_edata_arr[i].ext_enable_offset != ext_offset) {
+continue;
+}
+
+return isa_edata_arr[i].min_version;
+}
+
+/* Default to oldest priv spec if no match found */
+return PRIV_VERSION_1_10_0;
+}
+
+static void cpu_cfg_ext_auto_update(RISCVCPU *cpu, uint32_t ext_offset,
+bool value)
+{
+CPURISCVState *env = >env;
+bool prev_val = isa_ext_is_enabled(cpu, ext_offset);
+int min_version;
+
+if (prev_val == value) {
+return;
+}
+
+if (value && env->priv_ver != PRIV_VERSION_LATEST) {
+/* Do not enable it if priv_ver is older than min_version */
+min_version = cpu_cfg_ext_get_min_version(ext_offset);
+if (env->priv_ver < min_version) {
+return;
+}
+}
+
+isa_ext_update_enabled(cpu, ext_offset, value);
+}
+
 const char * const riscv_int_regnames[] = {
 "x0/zero", "x1/ra",  "x2/sp",  "x3/gp",  "x4/tp",  "x5/t0",   "x6/t1",
 "x7/t2",   "x8/s0",  "x9/s1",  "x10/a0", "x11/a1", "x12/a2",  "x13/a3",
@@ -1268,12 +1306,12 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, 
Error **errp)
 
 /* zca, zcd and zcf has a PRIV 1.12.0 restriction */
 if (riscv_has_ext(env, RVC) && env->priv_ver >= PRIV_VERSION_1_12_0) {
-cpu->cfg.ext_zca = true;
+cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zca), true);
 if (riscv_has_ext(env, RVF) && env->misa_mxl_max == MXL_RV32) {
-cpu->cfg.ext_zcf = true;
+cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zcf), true);
 }
 if (riscv_has_ext(env, RVD)) {
-cpu->cfg.ext_zcd = true;
+cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zcd), true);
 }
 }
 
-- 
2.41.0




[PATCH RESEND v8 03/20] target/riscv/cpu.c: split kvm prop handling to its own helper

2023-08-24 Thread Daniel Henrique Barboza
Future patches will split the existing Property arrays even further, and
the existing code in riscv_cpu_add_user_properties() will start to scale
bad with it because it's dealing with KVM constraints mixed in with TCG
constraints. We're going to pay a high price to share a couple of common
lines of code between the two.

Create a new riscv_cpu_add_kvm_properties() that will be forked from
riscv_cpu_add_user_properties() if we're running KVM. The helper
includes all properties that a KVM CPU will add. The rest of
riscv_cpu_add_user_properties() body will then be relieved from having
to deal with KVM constraints.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Weiwei Li 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.c | 65 ++
 1 file changed, 42 insertions(+), 23 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 6aac3ba1d1..a51b946804 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1937,6 +1937,46 @@ static void cpu_set_cfg_unavailable(Object *obj, Visitor 
*v,
 }
 #endif
 
+#ifndef CONFIG_USER_ONLY
+static void riscv_cpu_add_kvm_unavail_prop(Object *obj, const char *prop_name)
+{
+/* Check if KVM created the property already */
+if (object_property_find(obj, prop_name)) {
+return;
+}
+
+/*
+ * Set the default to disabled for every extension
+ * unknown to KVM and error out if the user attempts
+ * to enable any of them.
+ */
+object_property_add(obj, prop_name, "bool",
+NULL, cpu_set_cfg_unavailable,
+NULL, (void *)prop_name);
+}
+
+static void riscv_cpu_add_kvm_properties(Object *obj)
+{
+Property *prop;
+DeviceState *dev = DEVICE(obj);
+
+kvm_riscv_init_user_properties(obj);
+riscv_cpu_add_misa_properties(obj);
+
+for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
+riscv_cpu_add_kvm_unavail_prop(obj, prop->name);
+}
+
+for (int i = 0; i < ARRAY_SIZE(riscv_cpu_options); i++) {
+/* Check if KVM created the property already */
+if (object_property_find(obj, riscv_cpu_options[i].name)) {
+continue;
+}
+qdev_property_add_static(dev, _cpu_options[i]);
+}
+}
+#endif
+
 /*
  * Add CPU properties with user-facing flags.
  *
@@ -1952,39 +1992,18 @@ static void riscv_cpu_add_user_properties(Object *obj)
 riscv_add_satp_mode_properties(obj);
 
 if (kvm_enabled()) {
-kvm_riscv_init_user_properties(obj);
+riscv_cpu_add_kvm_properties(obj);
+return;
 }
 #endif
 
 riscv_cpu_add_misa_properties(obj);
 
 for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
-#ifndef CONFIG_USER_ONLY
-if (kvm_enabled()) {
-/* Check if KVM created the property already */
-if (object_property_find(obj, prop->name)) {
-continue;
-}
-
-/*
- * Set the default to disabled for every extension
- * unknown to KVM and error out if the user attempts
- * to enable any of them.
- */
-object_property_add(obj, prop->name, "bool",
-NULL, cpu_set_cfg_unavailable,
-NULL, (void *)prop->name);
-continue;
-}
-#endif
 qdev_property_add_static(dev, prop);
 }
 
 for (int i = 0; i < ARRAY_SIZE(riscv_cpu_options); i++) {
-/* Check if KVM created the property already */
-if (object_property_find(obj, riscv_cpu_options[i].name)) {
-continue;
-}
 qdev_property_add_static(dev, _cpu_options[i]);
 }
 }
-- 
2.41.0




[PATCH RESEND v8 09/20] target/riscv/cpu.c: limit cfg->vext_spec log message

2023-08-24 Thread Daniel Henrique Barboza
Inside riscv_cpu_validate_v() we're always throwing a log message if the
user didn't set a vector version via 'vext_spec'.

We're going to include one case with the 'max' CPU where env->vext_ver
will be set in the cpu_init(). But that alone will not stop the "vector
version is not specified" message from appearing. The usefulness of this
log message is debatable for the generic CPUs, but for a 'max' CPU type,
where we are supposed to deliver a CPU model with all features possible,
it's strange to force users to set 'vext_spec' to get rid of this
message.

Change riscv_cpu_validate_v() to not throw this log message if
env->vext_ver is already set.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
Reviewed-by: Weiwei Li 
---
 target/riscv/cpu.c | 9 -
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index d78c2c058f..5eb2d7f6da 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -959,8 +959,6 @@ static void riscv_cpu_disas_set_info(CPUState *s, 
disassemble_info *info)
 static void riscv_cpu_validate_v(CPURISCVState *env, RISCVCPUConfig *cfg,
  Error **errp)
 {
-int vext_version = VEXT_VERSION_1_00_0;
-
 if (!is_power_of_2(cfg->vlen)) {
 error_setg(errp, "Vector extension VLEN must be power of 2");
 return;
@@ -983,17 +981,18 @@ static void riscv_cpu_validate_v(CPURISCVState *env, 
RISCVCPUConfig *cfg,
 }
 if (cfg->vext_spec) {
 if (!g_strcmp0(cfg->vext_spec, "v1.0")) {
-vext_version = VEXT_VERSION_1_00_0;
+env->vext_ver = VEXT_VERSION_1_00_0;
 } else {
 error_setg(errp, "Unsupported vector spec version '%s'",
cfg->vext_spec);
 return;
 }
-} else {
+} else if (env->vext_ver == 0) {
 qemu_log("vector version is not specified, "
  "use the default value v1.0\n");
+
+env->vext_ver = VEXT_VERSION_1_00_0;
 }
-env->vext_ver = vext_version;
 }
 
 static void riscv_cpu_validate_priv_spec(RISCVCPU *cpu, Error **errp)
-- 
2.41.0




[PATCH RESEND v8 17/20] target/riscv/cpu.c: introduce RISCVCPUMultiExtConfig

2023-08-24 Thread Daniel Henrique Barboza
If we want to make better decisions when auto-enabling extensions during
realize() we need a way to tell if an user set an extension manually.
The RISC-V KVM driver has its own solution via a KVMCPUConfig struct
that has an 'user_set' flag that is set during the Property set()
callback. The set() callback also does init() time validations based on
the current KVM driver capabilities.

For TCG we would want a 'user_set' mechanic too, but we would look
ad-hoc via cpu_cfg_ext_auto_update() if a certain extension was user set
or not. If we copy what was made in the KVM side we would look for
'user_set' for one into 60+ extension structs spreaded in 3 arrays
(riscv_cpu_extensions, riscv_cpu_experimental_exts,
riscv_cpu_vendor_exts).

We'll still need an extension struct but we won't be using the
'user_set' flag:

- 'RISCVCPUMultiExtConfig' will be our specialized structure, similar to what
we're already doing with the MISA extensions in 'RISCVCPUMisaExtConfig'.
DEFINE_PROP_BOOL() for all 3 extensions arrays were replaced by
MULTI_EXT_CFG_BOOL(), a macro that will init our specialized struct;

- the 'multi_ext_user_opts' hash will be used to store the offset of each
extension that the user set via the set() callback, cpu_set_multi_ext_cfg().
For now we're just initializing and populating it - next patch will use
it to determine if a certain extension was user set;

- cpu_add_multi_ext_prop() is a new helper that will replace the
qdev_property_add_static() calls that our macros are doing to populate
user properties. The macro was renamed to ADD_CPU_MULTIEXT_PROPS_ARRAY()
for clarity. Note that the non-extension properties in
riscv_cpu_options[] still need to be declared via qdev().

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.c | 257 -
 1 file changed, 158 insertions(+), 99 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 0fe2ce0add..adfe671bd4 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -162,6 +162,9 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(xventanacondops, PRIV_VERSION_1_12_0, 
ext_XVentanaCondOps),
 };
 
+/* Hash that stores user set extensions */
+static GHashTable *multi_ext_user_opts;
+
 static bool isa_ext_is_enabled(RISCVCPU *cpu, uint32_t ext_offset)
 {
 bool *ext_enabled = (void *)>cfg + ext_offset;
@@ -1713,6 +1716,8 @@ static void riscv_cpu_init(Object *obj)
 qdev_init_gpio_in(DEVICE(cpu), riscv_cpu_set_irq,
   IRQ_LOCAL_MAX + IRQ_LOCAL_GUEST_MAX);
 #endif /* CONFIG_USER_ONLY */
+
+multi_ext_user_opts = g_hash_table_new(NULL, g_direct_equal);
 }
 
 typedef struct RISCVCPUMisaExtConfig {
@@ -1864,109 +1869,118 @@ static void riscv_cpu_add_misa_properties(Object 
*cpu_obj)
 }
 }
 
-static Property riscv_cpu_extensions[] = {
+typedef struct RISCVCPUMultiExtConfig {
+const char *name;
+uint32_t offset;
+bool enabled;
+} RISCVCPUMultiExtConfig;
+
+#define MULTI_EXT_CFG_BOOL(_name, _prop, _defval) \
+{.name = _name, .offset = CPU_CFG_OFFSET(_prop), \
+ .enabled = _defval}
+
+static RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
 /* Defaults for standard extensions */
-DEFINE_PROP_BOOL("sscofpmf", RISCVCPU, cfg.ext_sscofpmf, false),
-DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
-DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
-DEFINE_PROP_BOOL("Zihintntl", RISCVCPU, cfg.ext_zihintntl, true),
-DEFINE_PROP_BOOL("Zihintpause", RISCVCPU, cfg.ext_zihintpause, true),
-DEFINE_PROP_BOOL("Zawrs", RISCVCPU, cfg.ext_zawrs, true),
-DEFINE_PROP_BOOL("Zfa", RISCVCPU, cfg.ext_zfa, true),
-DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false),
-DEFINE_PROP_BOOL("Zfhmin", RISCVCPU, cfg.ext_zfhmin, false),
-DEFINE_PROP_BOOL("Zve32f", RISCVCPU, cfg.ext_zve32f, false),
-DEFINE_PROP_BOOL("Zve64f", RISCVCPU, cfg.ext_zve64f, false),
-DEFINE_PROP_BOOL("Zve64d", RISCVCPU, cfg.ext_zve64d, false),
-DEFINE_PROP_BOOL("sstc", RISCVCPU, cfg.ext_sstc, true),
-
-DEFINE_PROP_BOOL("smstateen", RISCVCPU, cfg.ext_smstateen, false),
-DEFINE_PROP_BOOL("svadu", RISCVCPU, cfg.ext_svadu, true),
-DEFINE_PROP_BOOL("svinval", RISCVCPU, cfg.ext_svinval, false),
-DEFINE_PROP_BOOL("svnapot", RISCVCPU, cfg.ext_svnapot, false),
-DEFINE_PROP_BOOL("svpbmt", RISCVCPU, cfg.ext_svpbmt, false),
-
-DEFINE_PROP_BOOL("zba", RISCVCPU, cfg.ext_zba, true),
-DEFINE_PROP_BOOL("zbb", RISCVCPU, cfg.ext_zbb, true),
-DEFINE_PROP_BOOL("zbc", RISCVCPU, cfg.ext_zbc, true),
-DEFINE_PROP_BOOL("zbkb", RISCVCPU, cfg.ext_zbkb, false),
-DEFINE_PROP_BOOL("zbkc", RISCVCPU, cfg.ext_zbkc, false),
-DEFINE_PROP_BOOL("zbkx", RISCVCPU, cfg.ext_zbkx, false),
-DEFINE_PROP_BOOL("zbs", RISCVCPU, cfg.ext_zbs, true),
-DEFINE_PROP_BOOL("zk", RISCVCPU, cfg.ext_zk, false),
-DEFINE_PROP_BOOL("zkn", RISCVCPU, cfg.ext_zkn, false),
-

[PATCH RESEND v8 01/20] target/riscv/cpu.c: split CPU options from riscv_cpu_extensions[]

2023-08-24 Thread Daniel Henrique Barboza
We'll add a new CPU type that will enable a considerable amount of
extensions. To make it easier for us we'll do a few cleanups in our
existing riscv_cpu_extensions[] array.

Start by splitting all CPU non-boolean options from it. Create a new
riscv_cpu_options[] array for them. Add all these properties in
riscv_cpu_add_user_properties() as it is already being done today.

'mmu' and 'pmp' aren't really extensions in the usual way we think about
RISC-V extensions. These are closer to CPU features/options, so move
both to riscv_cpu_options[] too. In the near future we'll need to match
all extensions with all entries in isa_edata_arr[], and so it happens
that both 'mmu' and 'pmp' do not have a riscv,isa string (thus, no priv
spec version restriction). This further emphasizes the point that these
are more a CPU option than an extension.

No functional changes made.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Weiwei Li 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.c | 33 +++--
 1 file changed, 23 insertions(+), 10 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 34ac26e3ae..6a4f95991d 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1804,7 +1804,6 @@ static void riscv_cpu_add_misa_properties(Object *cpu_obj)
 
 static Property riscv_cpu_extensions[] = {
 /* Defaults for standard extensions */
-DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
 DEFINE_PROP_BOOL("sscofpmf", RISCVCPU, cfg.ext_sscofpmf, false),
 DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
 DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
@@ -1817,15 +1816,8 @@ static Property riscv_cpu_extensions[] = {
 DEFINE_PROP_BOOL("Zve32f", RISCVCPU, cfg.ext_zve32f, false),
 DEFINE_PROP_BOOL("Zve64f", RISCVCPU, cfg.ext_zve64f, false),
 DEFINE_PROP_BOOL("Zve64d", RISCVCPU, cfg.ext_zve64d, false),
-DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
-DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
 DEFINE_PROP_BOOL("sstc", RISCVCPU, cfg.ext_sstc, true),
 
-DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
-DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
-DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128),
-DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64),
-
 DEFINE_PROP_BOOL("smstateen", RISCVCPU, cfg.ext_smstateen, false),
 DEFINE_PROP_BOOL("svadu", RISCVCPU, cfg.ext_svadu, true),
 DEFINE_PROP_BOOL("svinval", RISCVCPU, cfg.ext_svinval, false),
@@ -1856,9 +1848,7 @@ static Property riscv_cpu_extensions[] = {
 DEFINE_PROP_BOOL("zhinxmin", RISCVCPU, cfg.ext_zhinxmin, false),
 
 DEFINE_PROP_BOOL("zicbom", RISCVCPU, cfg.ext_icbom, true),
-DEFINE_PROP_UINT16("cbom_blocksize", RISCVCPU, cfg.cbom_blocksize, 64),
 DEFINE_PROP_BOOL("zicboz", RISCVCPU, cfg.ext_icboz, true),
-DEFINE_PROP_UINT16("cboz_blocksize", RISCVCPU, cfg.cboz_blocksize, 64),
 
 DEFINE_PROP_BOOL("zmmul", RISCVCPU, cfg.ext_zmmul, false),
 
@@ -1912,6 +1902,21 @@ static Property riscv_cpu_extensions[] = {
 DEFINE_PROP_END_OF_LIST(),
 };
 
+static Property riscv_cpu_options[] = {
+DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
+
+DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
+DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
+
+DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
+DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
+
+DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128),
+DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64),
+
+DEFINE_PROP_UINT16("cbom_blocksize", RISCVCPU, cfg.cbom_blocksize, 64),
+DEFINE_PROP_UINT16("cboz_blocksize", RISCVCPU, cfg.cboz_blocksize, 64),
+};
 
 #ifndef CONFIG_USER_ONLY
 static void cpu_set_cfg_unavailable(Object *obj, Visitor *v,
@@ -1980,6 +1985,14 @@ static void riscv_cpu_add_user_properties(Object *obj)
 #endif
 qdev_property_add_static(dev, prop);
 }
+
+for (int i = 0; i < ARRAY_SIZE(riscv_cpu_options); i++) {
+/* Check if KVM created the property already */
+if (object_property_find(obj, riscv_cpu_options[i].name)) {
+continue;
+}
+qdev_property_add_static(dev, _cpu_options[i]);
+}
 }
 
 static Property riscv_cpu_properties[] = {
-- 
2.41.0




[PATCH RESEND v8 00/20] riscv: 'max' CPU, detect user choice in TCG

2023-08-24 Thread Daniel Henrique Barboza
Hi,

This is a resend of these two patch sets because they no longer apply
into Alistair's riscv-to-apply.next:

[PATCH v8 00/12] riscv: add 'max' CPU, deprecate 'any'
https://lore.kernel.org/qemu-riscv/20230815223741.433763-1-dbarb...@ventanamicro.com/

[PATCH v3 0/8] riscv: detecting user choice in TCG extensions
https://lore.kernel.org/qemu-riscv/20230815224733.434682-1-dbarb...@ventanamicro.com/


They're being sent in a single package for convenience. No other changes
made from their old versions aside from the rebase.

Patches missing acks: 4,7,8

Changes from v7:
- patch 7:
  - add riscv_cpu_add_qdev_prop_array() function instead of a macro
- patch 8:
  - add riscv_cpu_add_kvm_unavail_prop_array() function instead of a
macro
- v7 link: 
https://lore.kernel.org/qemu-riscv/20230815201559.398643-1-dbarb...@ventanamicro.com/

Daniel Henrique Barboza (20):
  target/riscv/cpu.c: split CPU options from riscv_cpu_extensions[]
  target/riscv/cpu.c: skip 'bool' check when filtering KVM props
  target/riscv/cpu.c: split kvm prop handling to its own helper
  target/riscv: add DEFINE_PROP_END_OF_LIST() to riscv_cpu_options[]
  target/riscv/cpu.c: split non-ratified exts from
riscv_cpu_extensions[]
  target/riscv/cpu.c: split vendor exts from riscv_cpu_extensions[]
  target/riscv/cpu.c: add riscv_cpu_add_qdev_prop_array()
  target/riscv/cpu.c: add riscv_cpu_add_kvm_unavail_prop_array()
  target/riscv/cpu.c: limit cfg->vext_spec log message
  target/riscv: add 'max' CPU type
  avocado, risc-v: add opensbi tests for 'max' CPU
  target/riscv: deprecate the 'any' CPU type
  target/riscv/cpu.c: use offset in isa_ext_is_enabled/update_enabled
  target/riscv: make CPUCFG() macro public
  target/riscv/cpu.c: introduce cpu_cfg_ext_auto_update()
  target/riscv/cpu.c: use cpu_cfg_ext_auto_update() during realize()
  target/riscv/cpu.c: introduce RISCVCPUMultiExtConfig
  target/riscv: use isa_ext_update_enabled() in
init_max_cpu_extensions()
  target/riscv/cpu.c: honor user choice in cpu_cfg_ext_auto_update()
  target/riscv/cpu.c: consider user option with RVG

 docs/about/deprecated.rst  |  12 +
 target/riscv/cpu-qom.h |   1 +
 target/riscv/cpu.c | 555 +++--
 target/riscv/cpu.h |   2 +
 target/riscv/kvm.c |   8 +-
 tests/avocado/riscv_opensbi.py |  16 +
 6 files changed, 425 insertions(+), 169 deletions(-)

-- 
2.41.0




[PATCH RESEND v8 08/20] target/riscv/cpu.c: add riscv_cpu_add_kvm_unavail_prop_array()

2023-08-24 Thread Daniel Henrique Barboza
Use a helper in riscv_cpu_add_kvm_properties() to eliminate some of its
code repetition.

Signed-off-by: Daniel Henrique Barboza 
---
 target/riscv/cpu.c | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 4608fa2378..d78c2c058f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1971,6 +1971,14 @@ static void riscv_cpu_add_kvm_unavail_prop(Object *obj, 
const char *prop_name)
 NULL, (void *)prop_name);
 }
 
+static void riscv_cpu_add_kvm_unavail_prop_array(Object *obj,
+ Property *array)
+{
+for (Property *prop = array; prop && prop->name; prop++) {
+riscv_cpu_add_kvm_unavail_prop(obj, prop->name);
+}
+}
+
 static void riscv_cpu_add_kvm_properties(Object *obj)
 {
 Property *prop;
@@ -1979,17 +1987,9 @@ static void riscv_cpu_add_kvm_properties(Object *obj)
 kvm_riscv_init_user_properties(obj);
 riscv_cpu_add_misa_properties(obj);
 
-for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
-riscv_cpu_add_kvm_unavail_prop(obj, prop->name);
-}
-
-for (prop = riscv_cpu_vendor_exts; prop && prop->name; prop++) {
-riscv_cpu_add_kvm_unavail_prop(obj, prop->name);
-}
-
-for (prop = riscv_cpu_experimental_exts; prop && prop->name; prop++) {
-riscv_cpu_add_kvm_unavail_prop(obj, prop->name);
-}
+riscv_cpu_add_kvm_unavail_prop_array(obj, riscv_cpu_extensions);
+riscv_cpu_add_kvm_unavail_prop_array(obj, riscv_cpu_vendor_exts);
+riscv_cpu_add_kvm_unavail_prop_array(obj, riscv_cpu_experimental_exts);
 
 for (prop = riscv_cpu_options; prop && prop->name; prop++) {
 /* Check if KVM created the property already */
-- 
2.41.0




[PATCH RESEND v8 04/20] target/riscv: add DEFINE_PROP_END_OF_LIST() to riscv_cpu_options[]

2023-08-24 Thread Daniel Henrique Barboza
Add DEFINE_PROP_END_OF_LIST() and eliminate the ARRAY_SIZE() usage when
iterating in the riscv_cpu_options[] array, making it similar to what
we already do when working with riscv_cpu_extensions[].

We also have a more sophisticated motivation behind this change. In the
future we might need to export riscv_cpu_options[] to other files, and
ARRAY_LIST() doesn't work properly in that case because the array size
isn't exposed to the header file. Here's a future sight of what we would
deal with:

./target/riscv/kvm.c:1057:5: error: nested extern declaration of 
'riscv_cpu_add_misa_properties' [-Werror=nested-externs]
n file included from ../target/riscv/kvm.c:19:
home/danielhb/work/qemu/include/qemu/osdep.h:473:31: error: invalid application 
of 'sizeof' to incomplete type 'const RISCVCPUMultiExtConfig[]'
 473 | #define ARRAY_SIZE(x) ((sizeof(x) / sizeof((x)[0])) + \
 |   ^
./target/riscv/kvm.c:1047:29: note: in expansion of macro 'ARRAY_SIZE'
1047 | for (int i = 0; i < ARRAY_SIZE(_array); i++) { \
 | ^~
./target/riscv/kvm.c:1059:5: note: in expansion of macro 
'ADD_UNAVAIL_KVM_PROP_ARRAY'
1059 | ADD_UNAVAIL_KVM_PROP_ARRAY(obj, riscv_cpu_extensions);
 | ^~
home/danielhb/work/qemu/include/qemu/osdep.h:473:31: error: invalid application 
of 'sizeof' to incomplete type 'const RISCVCPUMultiExtConfig[]'
 473 | #define ARRAY_SIZE(x) ((sizeof(x) / sizeof((x)[0])) + \
 |   ^
./target/riscv/kvm.c:1047:29: note: in expansion of macro 'ARRAY_SIZE'
1047 | for (int i = 0; i < ARRAY_SIZE(_array); i++) { \

Homogenize the present and change the future by using
DEFINE_PROP_END_OF_LIST() in riscv_cpu_options[].

Signed-off-by: Daniel Henrique Barboza 
---
 target/riscv/cpu.c | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index a51b946804..272edaadf0 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1916,6 +1916,8 @@ static Property riscv_cpu_options[] = {
 
 DEFINE_PROP_UINT16("cbom_blocksize", RISCVCPU, cfg.cbom_blocksize, 64),
 DEFINE_PROP_UINT16("cboz_blocksize", RISCVCPU, cfg.cboz_blocksize, 64),
+
+DEFINE_PROP_END_OF_LIST(),
 };
 
 #ifndef CONFIG_USER_ONLY
@@ -1967,12 +1969,12 @@ static void riscv_cpu_add_kvm_properties(Object *obj)
 riscv_cpu_add_kvm_unavail_prop(obj, prop->name);
 }
 
-for (int i = 0; i < ARRAY_SIZE(riscv_cpu_options); i++) {
+for (prop = riscv_cpu_options; prop && prop->name; prop++) {
 /* Check if KVM created the property already */
-if (object_property_find(obj, riscv_cpu_options[i].name)) {
+if (object_property_find(obj, prop->name)) {
 continue;
 }
-qdev_property_add_static(dev, _cpu_options[i]);
+qdev_property_add_static(dev, prop);
 }
 }
 #endif
@@ -2003,8 +2005,8 @@ static void riscv_cpu_add_user_properties(Object *obj)
 qdev_property_add_static(dev, prop);
 }
 
-for (int i = 0; i < ARRAY_SIZE(riscv_cpu_options); i++) {
-qdev_property_add_static(dev, _cpu_options[i]);
+for (prop = riscv_cpu_options; prop && prop->name; prop++) {
+qdev_property_add_static(dev, prop);
 }
 }
 
-- 
2.41.0




Re: [PATCH V3 00/10] fix migration of suspended runstate

2023-08-24 Thread Steven Sistare
On 8/17/2023 2:23 PM, Peter Xu wrote:
> On Mon, Aug 14, 2023 at 11:54:26AM -0700, Steve Sistare wrote:
>> Migration of a guest in the suspended runstate is broken.  The incoming
>> migration code automatically tries to wake the guest, which is wrong;
>> the guest should end migration in the same runstate it started.  Further,
>> for a restored snapshot, the automatic wakeup fails.  The runstate is
>> RUNNING, but the guest is not.  See the commit messages for the details.
> 
> Hi Steve,
> 
> I drafted two small patches to show what I meant, on top of this series.
> Before applying these two, one needs to revert patch 1 in this series.
> 
> After applied, it should also pass all three new suspend tests.  We can
> continue the discussion here based on the patches.

Your 2 patches look good.  I suggest we keep patch 1, and I squash patch 2
into the other patches.

There is one more fix needed: on the sending side, if the state is suspended,
then ticks must be disabled so the tick globals are updated before they are
written to vmstate.  Otherwise, tick starts at 0 in the receiver when
cpu_enable_ticks is called.

---
diff --git a/migration/migration.c b/migration/migration.c
index b004475..89d56a8 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -63,6 +63,7 @@
 #include "sysemu/cpus.h"
 #include "yank_functions.h"
 #include "sysemu/qtest.h"
+#include "sysemu/cpu-timers.h"
 #include "options.h"
 #include "sysemu/dirtylimit.h"

@@ -2125,6 +2126,9 @@ static int postcopy_start(MigrationState *ms, Error **errp
 trace_postcopy_start_set_run();

 global_state_store();
+if (runstate_check(RUN_STATE_SUSPENDED)) {
+cpu_disable_ticks();
+}
 ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE);
 if (ret < 0) {
 goto fail;
@@ -2333,6 +2337,9 @@ static void migration_completion(MigrationState *s)
 s->vm_old_state = runstate_get();
 global_state_store();

+if (runstate_check(RUN_STATE_SUSPENDED)) {
+cpu_disable_ticks();
+}
 ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE);
 trace_migration_completion_vm_stop(ret);
 if (ret >= 0) {
diff --git a/migration/savevm.c b/migration/savevm.c
index 7b9c477..eff6976 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -58,6 +58,7 @@
 #include "qemu/cutils.h"
 #include "io/channel-buffer.h"
 #include "io/channel-file.h"
+#include "sysemu/cpu-timers.h"
 #include "sysemu/replay.h"
 #include "sysemu/runstate.h"
 #include "sysemu/sysemu.h"
@@ -2969,6 +2970,9 @@ bool save_snapshot(const char *name, bool overwrite, const
 saved_vm_running = runstate_is_running();

 global_state_store();
+if (runstate_check(RUN_STATE_SUSPENDED)) {
+cpu_disable_ticks();
+}
 vm_stop(RUN_STATE_SAVE_VM);

 bdrv_drain_all_begin();
@@ -3037,6 +3041,8 @@ bool save_snapshot(const char *name, bool overwrite, const

 if (saved_vm_running) {
 vm_start();
+} else if (runstate_check(RUN_STATE_SUSPENDED)) {
+cpu_enable_ticks();
 }
 return ret == 0;
 }

---

- Steve



Re: [PATCH V3 01/10] vl: start on wakeup request

2023-08-24 Thread Steven Sistare
On 8/17/2023 2:27 PM, Peter Xu wrote:
> On Mon, Aug 14, 2023 at 11:54:27AM -0700, Steve Sistare wrote:
>> +void vm_wakeup(void)
>> +{
>> +if (!vm_started) {
>> +vm_start();
> 
> (irrelevant of the global var that I wanted to remove..)
> 
> Calling vm_start() is wrong here, IMHO.
> 
> I think we need to notify everyone on the wakeup before really waking up
> the vcpus:
> 
> notifier_list_notify(_notifiers, _reason);
> 
> There's resume_all_vcpus() after that.  I don't know the side effect of
> resuming vcpus without such notifications, at least some acpi fields do not
> seem to be updated so the vcpu can see stale values (acpi_notify_wakeup()).

Agreed, good catch.

- Steve

>> +} else {
>> +runstate_set(RUN_STATE_RUNNING);
>>  }
>>  }
> 



Re: [PATCH V1 2/3] migration: fix suspended runstate

2023-08-24 Thread Steven Sistare
On 8/17/2023 2:19 PM, Peter Xu wrote:
> On Wed, Aug 16, 2023 at 01:48:13PM -0400, Steven Sistare wrote:
>> On 8/14/2023 3:37 PM, Peter Xu wrote:
>>> On Mon, Aug 14, 2023 at 02:53:56PM -0400, Steven Sistare wrote:
> Can we just call vm_state_notify() earlier?

 We cannot.  The guest is not running yet, and will not be until later.
 We cannot call notifiers that perform actions that complete, or react to, 
 the guest entering a running state.
>>>
>>> I tried to look at a few examples of the notifees and most of them I read
>>> do not react to "vcpu running" but "vm running" (in which case I think
>>> "suspended" mode falls into "vm running" case); most of them won't care on
>>> the RunState parameter passed in, but only the bool "running".
>>>
>>> In reality, when running=true, it must be RUNNING so far.
>>>
>>> In that case does it mean we should notify right after the switchover,
>>> since after migration the vm is indeed running only if the vcpus are not
>>> during suspend?
>>
>> I cannot parse your question, but maybe this answers it.
>> If the outgoing VM is running and not suspended, then the incoming side
>> tests for autostart==true and calls vm_start, which calls the notifiers,
>> right after the switchover.
> 
> I meant IMHO SUSPENDED should be seen as "vm running" case to me, just like
> RUNNING.  Then, we should invoke vm_prepare_start(), just need some touch
> ups.
> 
>>
>>> One example (of possible issue) is vfio_vmstate_change(), where iiuc if we
>>> try to suspend a VM it should keep to be VFIO_DEVICE_STATE_RUNNING for that
>>> device; this kind of prove to me that SUSPEND is actually one of
>>> running=true states.
>>>
>>> If we postpone all notifiers here even after we switched over to dest qemu
>>> to the next upcoming suspend wakeup, I think it means these devices will
>>> not be in VFIO_DEVICE_STATE_RUNNING after switchover but perhaps
>>> VFIO_DEVICE_STATE_STOP.
>>
>> or VFIO_DEVICE_STATE_RESUMING, which is set in vfio_load_setup.
>> AFAIK it is OK to remain in that state until wakeup is called later.
> 
> So let me provide another clue of why I think we should call
> vm_prepare_start()..
> 
> Firstly, I think RESUME event should always be there right after we
> switched over, no matter suspeneded or not.  I just noticed that your test
> case would work because you put "wakeup" to be before RESUME.  I'm not sure
> whether that's correct.  I'd bet people could rely on that RESUME to
> identify the switchover.

Yes, possibly.

> More importantly, I'm wondering whether RTC should still be running during
> the suspended mode?  Sorry again if my knowledge over there is just
> limited, so correct me otherwise - but my understanding is during suspend
> mode (s1 or s3, frankly I can't tell which one this belongs..), rtc should
> still be running along with the system clock.  It means we _should_ at
> least call cpu_enable_ticks() to enable rtc:

Agreed.  The comment above cpu_get_ticks says:
  * return the time elapsed in VM between vm_start and vm_stop
Suspending a guest does not call vm_stop, so ticks keeps running.
I also verified that experimentally.

> /*
>  * enable cpu_get_ticks()
>  * Caller must hold BQL which serves as mutex for vm_clock_seqlock.
>  */
> void cpu_enable_ticks(void)
> 
> I think that'll enable cpu_get_tsc() and make it start to work right.
> 
>>
>>> Ideally I think we should here call vm_state_notify() with running=true and
>>> state=SUSPEND, but since I do see some hooks are not well prepared for
>>> SUSPEND over running=true, I'd think we should on the safe side call
>>> vm_state_notify(running=true, state=RUNNING) even for SUSPEND at switch
>>> over phase.  With that IIUC it'll naturally work (e.g. when wakeup again
>>> later we just need to call no notifiers).
>>
>> Notifiers are just one piece, all the code in vm_prepare_start must be 
>> called.
>> Is it correct to call all of that long before we actually resume the CPUs in
>> wakeup?  I don't know, but what is the point?
> 
> The point is not only for cleaness (again, I really, really don't like that
> new global.. sorry), but also now I think we should make the vm running.

I do believe it is safe to call vm_prepare_start immediately, since the vcpus
are never running when it is called.

>> The wakeup code still needs
>> modification to conditionally resume the vcpus.  The scheme would be roughly:
>>
>> loadvm_postcopy_handle_run_bh()
>> runstat = global_state_get_runstate();
>> if (runstate == RUN_STATE_RUNNING) {
>> vm_start()
>> } else if (runstate == RUN_STATE_SUSPENDED)
>> vm_prepare_start();   // the start of vm_start()
>> }
>>
>> qemu_system_wakeup_request()
>> if (some condition)
>> resume_all_vcpus();   // the remainder of vm_start()
>> else
>> runstate_set(RUN_STATE_RUNNING)
> 
> No it doesn't.  wakeup_reason is set there, main loop does the resuming.
> See:
> 
> if 

Re: [Qemu PATCH v2 9/9] hw/mem/cxl_type3: Add dpa range validation for accesses to dc regions

2023-08-24 Thread Fan Ni
On Mon, Aug 07, 2023 at 09:53:42AM +0100, Jonathan Cameron wrote:
> On Tue, 25 Jul 2023 18:39:56 +
> Fan Ni  wrote:
>
> > From: Fan Ni 
> >
> > Not all dpa range in the dc regions is valid to access until an extent
> > covering the range has been added. Add a bitmap for each region to
> > record whether a dc block in the region has been backed by dc extent.
> > For the bitmap, a bit in the bitmap represents a dc block. When a dc
> > extent is added, all the bits of the blocks in the extent will be set,
> > which will be cleared when the extent is released.
> >
> > Signed-off-by: Fan Ni 
> Hi Fan,
>
> A few of the bits of feedback apply broadly across the series.  Given I'm
> rebasing this anyway to give myself something to test I'll tidy things up
> (feel free to disagree with and revert any changes !)
> and push a tree out in next day or two.  I'll message when I've done so.
>
> Jonathan

Hi Jonathan,
I tried DCD with your branch "cxl-2023-08-07", and noticed the
following,
1. You made some changes to the bitmap functionality, now it is only
used to validate extents when adding/releasing dc extents. My original
thought of adding the bitmap is to 1) validating extents for extent
add/release as you do; 2) Add validating when doing read/write to the dc
regions since some address region may not have valid extent added yet.
Do you think 2) is not necessary?

2. Your change introduced a bug in the code.
https://gitlab.com/jic23/qemu/-/blob/cxl-2023-08-07/hw/cxl/cxl-mailbox-utils.c?ref_type=heads#L1394
ct3d->dc.num_regions should be ct3d->dc.num_regions-1.

Thanks,
Fan

>
> > ---
> >  hw/mem/cxl_type3.c  | 155 
> >  include/hw/cxl/cxl_device.h |   1 +
> >  2 files changed, 156 insertions(+)
> >
> > diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c
> > index 41a828598a..51943a36fc 100644
> > --- a/hw/mem/cxl_type3.c
> > +++ b/hw/mem/cxl_type3.c
> > @@ -787,13 +787,37 @@ static int cxl_create_dc_regions(CXLType3Dev *ct3d)
> >  /* dsmad_handle is set when creating cdat table entries */
> >  region->flags = 0;
> >
> > +region->blk_bitmap = bitmap_new(region->len / region->block_size);
>
> In common with many allocators in qemu if this fails it calls abort()
> internally so no need to handle potential errors.
>
> > +if (!region->blk_bitmap) {
> > +break;
> > +}
> > +
> >  region_base += region->len;
> >  }
> > +
> > +if (i < ct3d->dc.num_regions) {
> > +while (--i >= 0) {
> > +g_free(ct3d->dc.regions[i].blk_bitmap);
> > +}
> > +return -1;
> > +}
> > +
> >  QTAILQ_INIT(>dc.extents);
> >
> >  return 0;
> >  }
> >
> > +static void cxl_destroy_dc_regions(CXLType3Dev *ct3d)
> > +{
> > +int i;
> > +struct CXLDCD_Region *region;
> > +
> > +for (i = 0; i < ct3d->dc.num_regions; i++) {
> > +region = >dc.regions[i];
> > +g_free(region->blk_bitmap);
> > +}
> > +}
> > +
> >  static bool cxl_setup_memory(CXLType3Dev *ct3d, Error **errp)
> >  {
> >  DeviceState *ds = DEVICE(ct3d);
> > @@ -1021,6 +1045,7 @@ err_free_special_ops:
> >  g_free(regs->special_ops);
> >  err_address_space_free:
> >  if (ct3d->dc.host_dc) {
> > +cxl_destroy_dc_regions(ct3d);
> >  address_space_destroy(>dc.host_dc_as);
> >  }
> >  if (ct3d->hostpmem) {
> > @@ -1043,6 +1068,7 @@ static void ct3_exit(PCIDevice *pci_dev)
> >  spdm_sock_fini(ct3d->doe_spdm.socket);
> >  g_free(regs->special_ops);
> >  if (ct3d->dc.host_dc) {
> > +cxl_destroy_dc_regions(ct3d);
> >  address_space_destroy(>dc.host_dc_as);
> >  }
> >  if (ct3d->hostpmem) {
> > @@ -1053,6 +1079,110 @@ static void ct3_exit(PCIDevice *pci_dev)
> >  }
> >  }
> >
> > +/*
> > + * This function will marked the dpa range [dpa, dap + len) to be backed 
> > and
> > + * accessible, this happens when a dc extent is added and accepted by the
> > + * host.
> > + */
> > +static void set_region_block_backed(CXLType3Dev *ct3d, uint64_t dpa,
> > +uint64_t len)
> > +{
> > +int i;
> > +CXLDCD_Region *region = >dc.regions[0];
> > +
> > +if (dpa < region->base
> > +|| dpa >= region->base + ct3d->dc.total_capacity)
> > +return;
> > +
> > +/*
> > + * spec 3.0 9.13.3: Regions are used in increasing-DPA order, with
> > + * Region 0 being used for the lowest DPA of Dynamic Capacity and
> > + * Region 7 for the highest DPA.
> > + * So we check from the last region to find where the dpa belongs.
> > + * access across multiple regions is not allowed.
> > + **/
> > +for (i = ct3d->dc.num_regions - 1; i >= 0; i--) {
> > +region = >dc.regions[i];
> > +if (dpa >= region->base) {
> > +break;
> > +}
> > +}
> > +
> > +bitmap_set(region->blk_bitmap, (dpa - region->base) / 
> > region->block_size,
> > +len / region->block_size);
> > +}
> > 

[PATCH] qemu-nbd: Restore "qemu-nbd -v --fork" output

2023-08-24 Thread Eric Blake
Closing stderr earlier is good for daemonized qemu-nbd under ssh
earlier, but breaks the case where -v is being used to track what is
happening in the server, as in iotest 233.

When we know we are verbose, we do NOT want qemu_daemon to close
stderr.  For management purposes, we still need to temporarily
override the daemon child's stderr with the pipe to the parent until
after the pid file is created; but since qemu_daemon would normally
set stdout to /dev/null had we not been verbose, we can use stdout as
a place to stash our original stderr.  Thus, whether normal or vebose,
when the management handoff is complete, copying stdout back to stderr
does the right thing for the rest of the life of the daemon child.

Note that while the error messages expected by iotest 233 are now
restored, the change in file descriptors means they now show up
earlier in the testsuite output.

Reported-by: Kevin Wolf 
CC: Denis V. Lunev 
CC: qemu-sta...@nongnu.org
Fixes: 5c56dd27a2 ("qemu-nbd: fix regression with qemu-nbd --fork run over ssh")
Signed-off-by: Eric Blake 
---
 qemu-nbd.c | 21 -
 tests/qemu-iotests/233.out | 20 ++--
 2 files changed, 30 insertions(+), 11 deletions(-)

diff --git a/qemu-nbd.c b/qemu-nbd.c
index aaccaa33184..a105094fb17 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -944,9 +944,24 @@ int main(int argc, char **argv)

 close(stderr_fd[0]);

-ret = qemu_daemon(1, 0);
+ret = qemu_daemon(1, verbose);
 saved_errno = errno;/* dup2 will overwrite error below */

+if (verbose) {
+/* We want stdin at /dev/null when qemu_daemon didn't do it */
+stdin = freopen("/dev/null", "r", stdin);
+if (stdin == NULL) {
+error_report("Failed to redirect stdin: %s",
+ strerror(errno));
+exit(EXIT_FAILURE);
+}
+/* To keep the parent's stderr alive, copy it to stdout */
+if (dup2(STDOUT_FILENO, STDERR_FILENO) < 0) {
+error_report("Failed to redirect stdout: %s",
+ strerror(errno));
+exit(EXIT_FAILURE);
+}
+}
 /* Temporarily redirect stderr to the parent's pipe...  */
 if (dup2(stderr_fd[1], STDERR_FILENO) < 0) {
 char str[256];
@@ -1180,6 +1195,10 @@ int main(int argc, char **argv)
 }

 if (fork_process) {
+/*
+ * See above. If verbose is false, stdout is /dev/null (thanks
+ * to qemu_daemon); otherwise, stdout is the parent's stderr.
+ */
 if (dup2(STDOUT_FILENO, STDERR_FILENO) < 0) {
 error_report("Could not set stderr to /dev/null: %s",
  strerror(errno));
diff --git a/tests/qemu-iotests/233.out b/tests/qemu-iotests/233.out
index 237c82767ea..b09a197020a 100644
--- a/tests/qemu-iotests/233.out
+++ b/tests/qemu-iotests/233.out
@@ -41,8 +41,10 @@ exports available: 1
   min block: 1

 == check TLS fail over TCP with mismatched hostname ==
+qemu-nbd: option negotiation failed: Failed to read opts magic: Cannot read 
from TLS channel: Software caused connection abort
 qemu-img: Could not open 'driver=nbd,host=localhost,port=PORT,tls-creds=tls0': 
Certificate does not match the hostname localhost
 qemu-nbd: Certificate does not match the hostname localhost
+qemu-nbd: option negotiation failed: Failed to read opts magic: Cannot read 
from TLS channel: Software caused connection abort

 == check TLS works over TCP with mismatched hostname and override ==
 image: nbd://localhost:PORT
@@ -55,7 +57,9 @@ exports available: 1
   min block: 1

 == check TLS with different CA fails ==
+qemu-nbd: option negotiation failed: Verify failed: No certificate was found.
 qemu-img: Could not open 'driver=nbd,host=127.0.0.1,port=PORT,tls-creds=tls0': 
The certificate hasn't got a known issuer
+qemu-nbd: option negotiation failed: Verify failed: No certificate was found.
 qemu-nbd: The certificate hasn't got a known issuer

 == perform I/O over TLS ==
@@ -67,11 +71,15 @@ read 1048576/1048576 bytes at offset 1048576
 1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)

 == check TLS with authorization ==
+qemu-nbd: option negotiation failed: TLS x509 authz check for C=South 
Pacific,L=R'lyeh,O=Cthulhu Dark Lord Enterprises client1,CN=localhost is denied
 qemu-img: Could not open 'driver=nbd,host=127.0.0.1,port=PORT,tls-creds=tls0': 
Failed to read option reply: Cannot read from TLS channel: Software caused 
connection abort
+qemu-nbd: option negotiation failed: TLS x509 authz check for C=South 
Pacific,L=R'lyeh,O=Cthulhu Dark Lord Enterprises client3,CN=localhost is denied
 qemu-img: Could not open 'driver=nbd,host=127.0.0.1,port=PORT,tls-creds=tls0': 
Failed to read option reply: Cannot read from TLS channel: Software caused 
connection abort

 

Re: [PATCH] util/iov: Avoid dynamic stack allocation

2023-08-24 Thread Eric Blake
On Thu, Aug 24, 2023 at 05:47:06PM +0100, Peter Maydell wrote:
> From: Philippe Mathieu-Daudé 
> 
> Use autofree heap allocation instead of variable-length array on the
> stack.
> 
> The codebase has very few VLAs, and if we can get rid of them all we
> can make the compiler error on new additions.  This is a defensive
> measure against security bugs where an on-stack dynamic allocation
> isn't correctly size-checked (e.g.  CVE-2021-3527).
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> Signed-off-by: Peter Maydell 
> ---
> Usual "only tested with make check/make check-avocado" caveat.
> 
>  util/iov.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Reviewed-by: Eric Blake 

> 
> diff --git a/util/iov.c b/util/iov.c
> index 866fb577f30..7e73948f5e3 100644
> --- a/util/iov.c
> +++ b/util/iov.c
> @@ -571,7 +571,7 @@ static int sortelem_cmp_src_index(const void *a, const 
> void *b)
>   */
>  void qemu_iovec_clone(QEMUIOVector *dest, const QEMUIOVector *src, void *buf)
>  {
> -IOVectorSortElem sortelems[src->niov];
> +g_autofree IOVectorSortElem *sortelems = g_new(IOVectorSortElem, 
> src->niov);
>  void *last_end;
>  int i;
>  
> -- 
> 2.34.1
> 

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.
Virtualization:  qemu.org | libguestfs.org




Re: [PATCH v2 12/12] gdbstub: move comment for gdb_register_coprocessor

2023-08-24 Thread Richard Henderson

On 8/24/23 09:39, Alex Bennée wrote:

Use proper kdoc style comments for this API function.

Signed-off-by: Alex Bennée
---
  include/exec/gdbstub.h | 10 ++
  gdbstub/gdbstub.c  |  6 --
  2 files changed, 10 insertions(+), 6 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH v2 11/12] gdbstub: replace global gdb_has_xml with a function

2023-08-24 Thread Richard Henderson

On 8/24/23 09:39, Alex Bennée wrote:

Try and make the self reported global hack a little less hackish by
providing a query function instead. As gdb_has_xml was always set if
we negotiated XML we can now use the presence of ->target_xml as the
test instead.

Signed-off-by: Alex Bennée
---
  gdbstub/internals.h|  1 +
  include/exec/gdbstub.h | 10 +-
  gdbstub/gdbstub.c  | 12 +++-
  gdbstub/softmmu.c  |  1 -
  gdbstub/user.c |  1 -
  target/arm/gdbstub.c   |  8 
  target/ppc/gdbstub.c   |  4 ++--
  7 files changed, 19 insertions(+), 18 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH v2 10/12] gdbstub: refactor get_feature_xml

2023-08-24 Thread Richard Henderson

On 8/24/23 09:39, Alex Bennée wrote:

Try to bring up the code to more modern standards by:

   - use dynamic GString built xml over a fixed buffer
   - use autofree to save on explicit g_free() calls
   - don't hand hack strstr to find the delimiter

Signed-off-by: Alex Bennée 

---
v2
   - avoid needless g_strndup for copy of annex
---
  gdbstub/internals.h |  2 +-
  gdbstub/gdbstub.c   | 63 +
  2 files changed, 31 insertions(+), 34 deletions(-)

diff --git a/gdbstub/internals.h b/gdbstub/internals.h
index f2b46cce41..4876ebd74f 100644
--- a/gdbstub/internals.h
+++ b/gdbstub/internals.h
@@ -33,7 +33,7 @@ typedef struct GDBProcess {
  uint32_t pid;
  bool attached;
  
-char target_xml[1024];

+char *target_xml;
  } GDBProcess;
  
  enum RSState {

diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
index 8e9bc17e07..31a2451f27 100644
--- a/gdbstub/gdbstub.c
+++ b/gdbstub/gdbstub.c
@@ -354,54 +354,51 @@ static CPUState *gdb_get_cpu(uint32_t pid, uint32_t tid)
  static const char *get_feature_xml(const char *p, const char **newp,
 GDBProcess *process)
  {
-size_t len;
  int i;
  const char *name;
  CPUState *cpu = gdb_get_first_cpu_in_process(process);
  CPUClass *cc = CPU_GET_CLASS(cpu);
  
-len = 0;

-while (p[len] && p[len] != ':')
-len++;
-*newp = p + len;
+/* ‘qXfer:features:read:annex:offset,length' */


This is misleading, because "...:read:" has already been consumed.


+char *term = g_strstr_len(p, -1, ":");


This is strchr(p, ':').


+g_autofree char *annex = g_strndup(p, len);
+/* leave newp at offset,length for the rest of the params */
+*newp = term + 1;
  
-name = NULL;

-if (strncmp(p, "target.xml", len) == 0) {
-char *buf = process->target_xml;
-const size_t buf_sz = sizeof(process->target_xml);
  
-/* Generate the XML description for this CPU.  */

-if (!buf[0]) {
+name = NULL;
+if (g_strcmp0(annex, "target.xml") == 0) {


Why the change to g_strcmp0?  There's no null pointer to be handled.
If you keep the strncmp, you don't have to allocate memory early.


  if (cc->gdb_get_dynamic_xml) {
-char *xmlname = g_strndup(p, len);
-const char *xml = cc->gdb_get_dynamic_xml(cpu, xmlname);
-
-g_free(xmlname);
+const char *xml = cc->gdb_get_dynamic_xml(cpu, annex);


You can leave the g_strndup (and autofree) to here.



r~



[PULL v2 00/48] tcg patch queue

2023-08-24 Thread Richard Henderson

Dangit, missed the PULL tag for v2.
The only change is fixing Anton's --author.

r~

On 8/24/23 11:28, Richard Henderson wrote:

The following changes since commit 50e7a40af372ee5931c99ef7390f5d3d6fbf6ec4:

   Merge tag 'pull-target-arm-20230824' of 
https://git.linaro.org/people/pmaydell/qemu-arm into staging (2023-08-24 
10:08:33 -0400)

are available in the Git repository at:

   https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20230823-2

for you to fetch changes up to 4daad8d9d6b9d426beb8ce505d2164ba36ea3168:

   tcg: spelling fixes (2023-08-24 11:22:42 -0700)


accel/*: Widen pc/saved_insn for *_sw_breakpoint
accel/tcg: Replace remaining target_ulong in system-mode accel
tcg: spelling fixes
tcg: Document bswap, hswap, wswap byte patterns
tcg: Introduce negsetcond opcodes
tcg: Fold deposit with zero to and
tcg: Unify TCG_TARGET_HAS_extr[lh]_i64_i32
tcg/i386: Drop BYTEH deposits for 64-bit
tcg/i386: Allow immediate as input to deposit
target/*: Use tcg_gen_negsetcond_*


Anton Johansson (9):
   accel/kvm: Widen pc/saved_insn for kvm_sw_breakpoint
   accel/hvf: Widen pc/saved_insn for hvf_sw_breakpoint
   sysemu/kvm: Use vaddr for kvm_arch_[insert|remove]_hw_breakpoint
   sysemu/hvf: Use vaddr for hvf_arch_[insert|remove]_hw_breakpoint
   include/exec: Replace target_ulong with abi_ptr in cpu_[st|ld]*()
   include/exec: typedef abi_ptr to vaddr in softmmu
   include/exec: Widen tlb_hit/tlb_hit_page()
   accel/tcg: Widen address arg in tlb_compare_set()
   accel/tcg: Update run_on_cpu_data static assert

Mark Cave-Ayland (1):
   docs/devel/tcg-ops: fix missing newlines in "Host vector operations"

Michael Tokarev (1):
   tcg: spelling fixes

Philippe Mathieu-Daudé (9):
   docs/devel/tcg-ops: Bury mentions of trunc_shr_i64_i32()
   tcg/tcg-op: Document bswap16_i32() byte pattern
   tcg/tcg-op: Document bswap16_i64() byte pattern
   tcg/tcg-op: Document bswap32_i32() byte pattern
   tcg/tcg-op: Document bswap32_i64() byte pattern
   tcg/tcg-op: Document bswap64_i64() byte pattern
   tcg/tcg-op: Document hswap_i32/64() byte pattern
   tcg/tcg-op: Document wswap_i64() byte pattern
   target/cris: Fix a typo in gen_swapr()

Richard Henderson (28):
   target/m68k: Use tcg_gen_deposit_i32 in gen_partset_reg
   tcg/i386: Drop BYTEH deposits for 64-bit
   tcg: Fold deposit with zero to and
   tcg/i386: Allow immediate as input to deposit_*
   tcg: Unify TCG_TARGET_HAS_extr[lh]_i64_i32
   tcg: Introduce negsetcond opcodes
   tcg: Use tcg_gen_negsetcond_*
   target/alpha: Use tcg_gen_movcond_i64 in gen_fold_mzero
   target/arm: Use tcg_gen_negsetcond_*
   target/m68k: Use tcg_gen_negsetcond_*
   target/openrisc: Use tcg_gen_negsetcond_*
   target/ppc: Use tcg_gen_negsetcond_*
   target/sparc: Use tcg_gen_movcond_i64 in gen_edge
   target/tricore: Replace gen_cond_w with tcg_gen_negsetcond_tl
   tcg/ppc: Implement negsetcond_*
   tcg/ppc: Use the Set Boolean Extension
   tcg/aarch64: Implement negsetcond_*
   tcg/arm: Implement negsetcond_i32
   tcg/riscv: Implement negsetcond_*
   tcg/s390x: Implement negsetcond_*
   tcg/sparc64: Implement negsetcond_*
   tcg/i386: Merge tcg_out_brcond{32,64}
   tcg/i386: Merge tcg_out_setcond{32,64}
   tcg/i386: Merge tcg_out_movcond{32,64}
   tcg/i386: Use CMP+SBB in tcg_out_setcond
   tcg/i386: Clear dest first in tcg_out_setcond if possible
   tcg/i386: Use shift in tcg_out_setcond
   tcg/i386: Implement negsetcond_*

  docs/devel/tcg-ops.rst |  15 +-
  accel/tcg/atomic_template.h|  16 +-
  include/exec/cpu-all.h |   4 +-
  include/exec/cpu_ldst.h|  28 +--
  include/sysemu/hvf.h   |  12 +-
  include/sysemu/kvm.h   |  12 +-
  include/tcg/tcg-op-common.h|   4 +
  include/tcg/tcg-op.h   |   2 +
  include/tcg/tcg-opc.h  |   6 +-
  include/tcg/tcg.h  |   4 +-
  tcg/aarch64/tcg-target.h   |   5 +-
  tcg/arm/tcg-target.h   |   1 +
  tcg/i386/tcg-target-con-set.h  |   2 +-
  tcg/i386/tcg-target-con-str.h  |   1 -
  tcg/i386/tcg-target.h  |   9 +-
  tcg/loongarch64/tcg-target.h   |   6 +-
  tcg/mips/tcg-target.h  |   5 +-
  tcg/ppc/tcg-target.h   |   5 +-
  tcg/riscv/tcg-target.h |   5 +-
  tcg/s390x/tcg-target.h |   5 +-
  tcg/sparc64/tcg-target.h   |   5 +-
  tcg/tci/tcg-target.h   |   5 +-
  accel/hvf/hvf-accel-ops.c  |   4 +-
  accel/hvf

Re: [PATCH v7 00/12] Add VIRTIO sound card

2023-08-24 Thread Alex Bennée


Emmanouil Pitsidianakis  writes:

> This patch series adds an audio device implementing the recent virtio 
> sound spec (1.2) and a corresponding PCI wrapper device.
>
> v7 can be found online at:
>
> https://github.com/epilys/qemu-virtio-snd/tree/virtio-snd-v7
>
> Main differences with v6 patch series [^v6]
> :
>
> - Removed minor stale/duplicate code.
> - Addressed [^v6] review comments.
>   Notably, the audio driver name is now `virtio` instead of 
>   `virtio-sound`.
> - Fixed some invalid pointer logic.
> - Fixed minor typos and updated documentation.

I'm seeing a bunch of CI failures:

  https://gitlab.com/stsquad/qemu/-/pipelines/979444077

Most of them will probably clear up when you fix the missing parameter
names.


-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [PATCH v7 03/12] virtio-sound: handle control messages and streams

2023-08-24 Thread Alex Bennée


Emmanouil Pitsidianakis  writes:

> Receive guest requests in the control (CTRL) queue of the virtio sound
> device and reply with a NOT SUPPORTED error to all control commands.
>
> The receiving handler is virtio_snd_handle_ctrl(). It stores all control
> messages in the queue in the device's command queue. Then it calls
> virtio_snd_process_cmdq() to handle each message.
>
> The handler is process_cmd() which replies with VIRTIO_SND_S_NOT_SUPP.
>
> Signed-off-by: Emmanouil Pitsidianakis 
> ---
>  hw/virtio/trace-events |   4 +
>  hw/virtio/virtio-snd.c | 227 -
>  include/hw/virtio/virtio-snd.h |  70 +-
>  3 files changed, 292 insertions(+), 9 deletions(-)
>
> diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
> index 3ed7da35f2..8a223e36e9 100644
> --- a/hw/virtio/trace-events
> +++ b/hw/virtio/trace-events
> @@ -163,3 +163,7 @@ virtio_snd_vm_state_running(void) "vm state running"
>  virtio_snd_vm_state_stopped(void) "vm state stopped"
>  virtio_snd_realize(void *snd) "snd %p: realize"
>  virtio_snd_unrealize(void *snd) "snd %p: unrealize"
> +virtio_snd_handle_ctrl(void *vdev, void *vq) "snd %p: handle ctrl event for 
> queue %p"
> +virtio_snd_handle_code(uint32_t val, const char *code) "ctrl code msg val = 
> %"PRIu32" == %s"
> +virtio_snd_handle_chmap_info(void) "VIRTIO_SND_CHMAP_INFO called"
> +virtio_snd_handle_event(void) "event queue callback called"
> diff --git a/hw/virtio/virtio-snd.c b/hw/virtio/virtio-snd.c
> index 0498e660a5..b23f8040e1 100644
> --- a/hw/virtio/virtio-snd.c
> +++ b/hw/virtio/virtio-snd.c
> @@ -30,6 +30,29 @@
>  #define VIRTIO_SOUND_CHMAP_DEFAULT 0
>  #define VIRTIO_SOUND_HDA_FN_NID 0
>  
> +static const char *print_code(uint32_t code)
> +{
> +#define CASE(CODE)\
> +case VIRTIO_SND_R_##CODE: \
> +return "VIRTIO_SND_R_"#CODE
> +
> +switch (code) {
> +CASE(JACK_INFO);
> +CASE(JACK_REMAP);
> +CASE(PCM_INFO);
> +CASE(PCM_SET_PARAMS);
> +CASE(PCM_PREPARE);
> +CASE(PCM_RELEASE);
> +CASE(PCM_START);
> +CASE(PCM_STOP);
> +CASE(CHMAP_INFO);
> +default:
> +return "invalid code";
> +}
> +
> +#undef CASE
> +};
> +
>  static const VMStateDescription vmstate_virtio_snd_device = {
>  .name = TYPE_VIRTIO_SND,
>  .version_id = VIRTIO_SOUND_VM_VERSION,
> @@ -88,12 +111,148 @@ virtio_snd_set_config(VirtIODevice *vdev, const uint8_t 
> *config)
>  }
>  
>  /*
> - * Queue handler stub.
> + * The actual processing done in virtio_snd_process_cmdq().
> + *
> + * @s: VirtIOSound device
> + * @cmd: control command request
> + */
> +static inline void
> +process_cmd(VirtIOSound *s, virtio_snd_ctrl_command *cmd)
> +{
> +size_t sz = iov_to_buf(cmd->elem->out_sg,
> +   cmd->elem->out_num,
> +   0,
> +   >ctrl,
> +   sizeof(cmd->ctrl));
> +if (sz != sizeof(cmd->ctrl)) {
> +qemu_log_mask(LOG_GUEST_ERROR,
> +"%s: virtio-snd command size incorrect %zu vs \
> +%zu\n", __func__, sz, sizeof(cmd->ctrl));
> +return;
> +}
> +
> +trace_virtio_snd_handle_code(cmd->ctrl.code,
> + print_code(cmd->ctrl.code));
> +
> +switch (cmd->ctrl.code) {
> +case VIRTIO_SND_R_JACK_INFO:
> +case VIRTIO_SND_R_JACK_REMAP:
> +qemu_log_mask(LOG_UNIMP,
> + "virtio_snd: jack functionality is unimplemented.");
> +cmd->resp.code = VIRTIO_SND_S_NOT_SUPP;
> +break;
> +case VIRTIO_SND_R_PCM_INFO:
> +case VIRTIO_SND_R_PCM_SET_PARAMS:
> +case VIRTIO_SND_R_PCM_PREPARE:
> +case VIRTIO_SND_R_PCM_START:
> +case VIRTIO_SND_R_PCM_STOP:
> +case VIRTIO_SND_R_PCM_RELEASE:
> +cmd->resp.code = VIRTIO_SND_S_NOT_SUPP;
> +break;
> +case VIRTIO_SND_R_CHMAP_INFO:
> +qemu_log_mask(LOG_UNIMP,
> + "virtio_snd: chmap info functionality is 
> unimplemented.");
> +trace_virtio_snd_handle_chmap_info();
> +cmd->resp.code = VIRTIO_SND_S_NOT_SUPP;
> +break;
> +default:
> +/* error */
> +error_report("virtio snd header not recognized: %"PRIu32,
> + cmd->ctrl.code);
> +cmd->resp.code = VIRTIO_SND_S_BAD_MSG;
> +}
> +
> +iov_from_buf(cmd->elem->in_sg,
> + cmd->elem->in_num,
> + 0,
> + >resp,
> + sizeof(cmd->resp));
> +virtqueue_push(cmd->vq, cmd->elem, sizeof(cmd->elem));
> +virtio_notify(VIRTIO_DEVICE(s), cmd->vq);
> +}
> +
> +/*
> + * Consume all elements in command queue.
> + *
> + * @s: VirtIOSound device
> + */
> +static void virtio_snd_process_cmdq(VirtIOSound *s)
> +{
> +virtio_snd_ctrl_command *cmd;
> +
> +if (unlikely(qatomic_read(>processing_cmdq))) {
> +return;
> +}
> +
> +WITH_QEMU_LOCK_GUARD(>cmdq_mutex) {
> +   

[PATCH v3 4/8] hw/misc/xlnx-versal-cfu: Introduce a model of Xilinx Versal's CFU_SFR

2023-08-24 Thread Francisco Iglesias
Introduce a model of Xilinx Versal's Configuration Frame Unit's Single
Frame Read port (CFU_SFR).

Signed-off-by: Francisco Iglesias 
Reviewed-by: Peter Maydell 
---
 hw/misc/xlnx-versal-cfu.c | 87 +++
 include/hw/misc/xlnx-versal-cfu.h | 15 ++
 2 files changed, 102 insertions(+)

diff --git a/hw/misc/xlnx-versal-cfu.c b/hw/misc/xlnx-versal-cfu.c
index 255c1bf4b8..8e588ac1d8 100644
--- a/hw/misc/xlnx-versal-cfu.c
+++ b/hw/misc/xlnx-versal-cfu.c
@@ -264,6 +264,31 @@ static void cfu_stream_write(void *opaque, hwaddr addr, 
uint64_t value,
 }
 }
 
+static uint64_t cfu_sfr_read(void *opaque, hwaddr addr, unsigned size)
+{
+qemu_log_mask(LOG_GUEST_ERROR, "%s: Unsupported read from addr=%"
+  HWADDR_PRIx "\n", __func__, addr);
+return 0;
+}
+
+static void cfu_sfr_write(void *opaque, hwaddr addr, uint64_t value,
+  unsigned size)
+{
+XlnxVersalCFUSFR *s = XLNX_VERSAL_CFU_SFR(opaque);
+uint32_t wfifo[WFIFO_SZ];
+
+if (update_wfifo(addr, value, s->wfifo, wfifo)) {
+uint8_t row_addr = extract32(wfifo[0], 23, 5);
+uint32_t frame_addr = extract32(wfifo[0], 0, 23);
+XlnxCfiPacket pkt = { .reg_addr = CFRAME_SFR,
+  .data[0] = frame_addr };
+
+if (s->cfg.cfu) {
+cfu_transfer_cfi_packet(s->cfg.cfu, row_addr, );
+}
+}
+}
+
 static uint64_t cfu_fdro_read(void *opaque, hwaddr addr, unsigned size)
 {
 XlnxVersalCFUFDRO *s = XLNX_VERSAL_CFU_FDRO(opaque);
@@ -293,6 +318,16 @@ static const MemoryRegionOps cfu_stream_ops = {
 },
 };
 
+static const MemoryRegionOps cfu_sfr_ops = {
+.read = cfu_sfr_read,
+.write = cfu_sfr_write,
+.endianness = DEVICE_LITTLE_ENDIAN,
+.valid = {
+.min_access_size = 4,
+.max_access_size = 4,
+},
+};
+
 static const MemoryRegionOps cfu_fdro_ops = {
 .read = cfu_fdro_read,
 .write = cfu_fdro_write,
@@ -334,6 +369,23 @@ static void cfu_apb_init(Object *obj)
 sysbus_init_irq(sbd, >irq_cfu_imr);
 }
 
+static void cfu_sfr_init(Object *obj)
+{
+XlnxVersalCFUSFR *s = XLNX_VERSAL_CFU_SFR(obj);
+SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+
+memory_region_init_io(>iomem_sfr, obj, _sfr_ops, s,
+  TYPE_XLNX_VERSAL_CFU_SFR, KEYHOLE_STREAM_4K);
+sysbus_init_mmio(sbd, >iomem_sfr);
+}
+
+static void cfu_sfr_reset_enter(Object *obj, ResetType type)
+{
+XlnxVersalCFUSFR *s = XLNX_VERSAL_CFU_SFR(obj);
+
+memset(s->wfifo, 0, WFIFO_SZ * sizeof(uint32_t));
+}
+
 static void cfu_fdro_init(Object *obj)
 {
 XlnxVersalCFUFDRO *s = XLNX_VERSAL_CFU_FDRO(obj);
@@ -401,6 +453,12 @@ static Property cfu_props[] = {
 DEFINE_PROP_END_OF_LIST(),
 };
 
+static Property cfu_sfr_props[] = {
+DEFINE_PROP_LINK("cfu", XlnxVersalCFUSFR, cfg.cfu,
+ TYPE_XLNX_VERSAL_CFU_APB, XlnxVersalCFUAPB *),
+DEFINE_PROP_END_OF_LIST(),
+};
+
 static const VMStateDescription vmstate_cfu_apb = {
 .name = TYPE_XLNX_VERSAL_CFU_APB,
 .version_id = 1,
@@ -423,6 +481,16 @@ static const VMStateDescription vmstate_cfu_fdro = {
 }
 };
 
+static const VMStateDescription vmstate_cfu_sfr = {
+.name = TYPE_XLNX_VERSAL_CFU_SFR,
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32_ARRAY(wfifo, XlnxVersalCFUSFR, 4),
+VMSTATE_END_OF_LIST(),
+}
+};
+
 static void cfu_apb_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
@@ -443,6 +511,16 @@ static void cfu_fdro_class_init(ObjectClass *klass, void 
*data)
 rc->phases.enter = cfu_fdro_reset_enter;
 }
 
+static void cfu_sfr_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+ResettableClass *rc = RESETTABLE_CLASS(klass);
+
+device_class_set_props(dc, cfu_sfr_props);
+dc->vmsd = _cfu_sfr;
+rc->phases.enter = cfu_sfr_reset_enter;
+}
+
 static const TypeInfo cfu_apb_info = {
 .name  = TYPE_XLNX_VERSAL_CFU_APB,
 .parent= TYPE_SYS_BUS_DEVICE,
@@ -467,10 +545,19 @@ static const TypeInfo cfu_fdro_info = {
 }
 };
 
+static const TypeInfo cfu_sfr_info = {
+.name  = TYPE_XLNX_VERSAL_CFU_SFR,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(XlnxVersalCFUSFR),
+.class_init= cfu_sfr_class_init,
+.instance_init = cfu_sfr_init,
+};
+
 static void cfu_apb_register_types(void)
 {
 type_register_static(_apb_info);
 type_register_static(_fdro_info);
+type_register_static(_sfr_info);
 }
 
 type_init(cfu_apb_register_types)
diff --git a/include/hw/misc/xlnx-versal-cfu.h 
b/include/hw/misc/xlnx-versal-cfu.h
index 73e9a21af4..86fb841053 100644
--- a/include/hw/misc/xlnx-versal-cfu.h
+++ b/include/hw/misc/xlnx-versal-cfu.h
@@ -28,6 +28,9 @@ OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalCFUAPB, 
XLNX_VERSAL_CFU_APB)
 #define TYPE_XLNX_VERSAL_CFU_FDRO 

[PATCH v3 7/8] hw/arm/xlnx-versal: Connect the CFU_APB, CFU_FDRO and CFU_SFR

2023-08-24 Thread Francisco Iglesias
Connect the Configuration Frame Unit (CFU_APB, CFU_FDRO and CFU_SFR) to
the Versal machine.

Signed-off-by: Francisco Iglesias 
Acked-by: Edgar E. Iglesias 
Reviewed-by: Peter Maydell 
---
 hw/arm/xlnx-versal.c | 42 
 include/hw/arm/xlnx-versal.h | 16 ++
 2 files changed, 58 insertions(+)

diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
index 60bf5fe657..3f4b4b1560 100644
--- a/hw/arm/xlnx-versal.c
+++ b/hw/arm/xlnx-versal.c
@@ -570,6 +570,47 @@ static void versal_create_ospi(Versal *s, qemu_irq *pic)
 qdev_connect_gpio_out(orgate, 0, pic[VERSAL_OSPI_IRQ]);
 }
 
+static void versal_create_cfu(Versal *s, qemu_irq *pic)
+{
+SysBusDevice *sbd;
+
+/* CFU FDRO */
+object_initialize_child(OBJECT(s), "cfu-fdro", >pmc.cfu_fdro,
+TYPE_XLNX_VERSAL_CFU_FDRO);
+sbd = SYS_BUS_DEVICE(>pmc.cfu_fdro);
+
+sysbus_realize(sbd, _fatal);
+memory_region_add_subregion(>mr_ps, MM_PMC_CFU_FDRO,
+sysbus_mmio_get_region(sbd, 0));
+
+/* CFU APB */
+object_initialize_child(OBJECT(s), "cfu-apb", >pmc.cfu_apb,
+TYPE_XLNX_VERSAL_CFU_APB);
+sbd = SYS_BUS_DEVICE(>pmc.cfu_apb);
+
+sysbus_realize(sbd, _fatal);
+memory_region_add_subregion(>mr_ps, MM_PMC_CFU_APB,
+sysbus_mmio_get_region(sbd, 0));
+memory_region_add_subregion(>mr_ps, MM_PMC_CFU_STREAM,
+sysbus_mmio_get_region(sbd, 1));
+memory_region_add_subregion(>mr_ps, MM_PMC_CFU_STREAM_2,
+sysbus_mmio_get_region(sbd, 2));
+sysbus_connect_irq(sbd, 0, pic[VERSAL_CFU_IRQ_0]);
+
+/* CFU SFR */
+object_initialize_child(OBJECT(s), "cfu-sfr", >pmc.cfu_sfr,
+TYPE_XLNX_VERSAL_CFU_SFR);
+
+sbd = SYS_BUS_DEVICE(>pmc.cfu_sfr);
+
+object_property_set_link(OBJECT(>pmc.cfu_sfr),
+"cfu", OBJECT(>pmc.cfu_apb), _abort);
+
+sysbus_realize(sbd, _fatal);
+memory_region_add_subregion(>mr_ps, MM_PMC_CFU_SFR,
+sysbus_mmio_get_region(sbd, 0));
+}
+
 static void versal_create_crl(Versal *s, qemu_irq *pic)
 {
 SysBusDevice *sbd;
@@ -763,6 +804,7 @@ static void versal_realize(DeviceState *dev, Error **errp)
 versal_create_pmc_iou_slcr(s, pic);
 versal_create_ospi(s, pic);
 versal_create_crl(s, pic);
+versal_create_cfu(s, pic);
 versal_map_ddr(s);
 versal_unimp(s);
 
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
index 39ee31185c..29b9c60301 100644
--- a/include/hw/arm/xlnx-versal.h
+++ b/include/hw/arm/xlnx-versal.h
@@ -32,6 +32,7 @@
 #include "hw/misc/xlnx-versal-crl.h"
 #include "hw/misc/xlnx-versal-pmc-iou-slcr.h"
 #include "hw/net/xlnx-versal-canfd.h"
+#include "hw/misc/xlnx-versal-cfu.h"
 
 #define TYPE_XLNX_VERSAL "xlnx-versal"
 OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
@@ -117,6 +118,9 @@ struct Versal {
 XlnxEFuse efuse;
 XlnxVersalEFuseCtrl efuse_ctrl;
 XlnxVersalEFuseCache efuse_cache;
+XlnxVersalCFUAPB cfu_apb;
+XlnxVersalCFUFDRO cfu_fdro;
+XlnxVersalCFUSFR cfu_sfr;
 
 OrIRQState apb_irq_orgate;
 } pmc;
@@ -147,6 +151,7 @@ struct Versal {
 #define VERSAL_GEM1_WAKE_IRQ_0 59
 #define VERSAL_ADMA_IRQ_0  60
 #define VERSAL_XRAM_IRQ_0  79
+#define VERSAL_CFU_IRQ_0   120
 #define VERSAL_PMC_APB_IRQ 121
 #define VERSAL_OSPI_IRQ124
 #define VERSAL_SD0_IRQ_0   126
@@ -240,6 +245,17 @@ struct Versal {
 #define MM_PMC_EFUSE_CACHE  0xf125
 #define MM_PMC_EFUSE_CACHE_SIZE 0x00C00
 
+#define MM_PMC_CFU_APB  0xf12b
+#define MM_PMC_CFU_APB_SIZE 0x1
+#define MM_PMC_CFU_STREAM   0xf12c
+#define MM_PMC_CFU_STREAM_SIZE  0x1000
+#define MM_PMC_CFU_SFR  0xf12c1000
+#define MM_PMC_CFU_SFR_SIZE 0x1000
+#define MM_PMC_CFU_FDRO 0xf12c2000
+#define MM_PMC_CFU_FDRO_SIZE0x1000
+#define MM_PMC_CFU_STREAM_2 0xf1f8
+#define MM_PMC_CFU_STREAM_2_SIZE0x4
+
 #define MM_PMC_CRP  0xf126U
 #define MM_PMC_CRP_SIZE 0x1
 #define MM_PMC_RTC  0xf12a
-- 
2.34.1




[PATCH v3 1/8] hw/misc: Introduce the Xilinx CFI interface

2023-08-24 Thread Francisco Iglesias
Introduce the Xilinx Configuration Frame Interface (CFI) for transmitting
CFI data packets between the Xilinx Configuration Frame Unit models
(CFU_APB, CFU_FDRO and CFU_SFR), the Xilinx CFRAME controller (CFRAME_REG)
and the Xilinx CFRAME broadcast controller (CFRAME_BCAST_REG) models (when
emulating bitstream programming and readback).

Signed-off-by: Francisco Iglesias 
Reviewed-by: Sai Pavan Boddu 
Acked-by: Edgar E. Iglesias 
---
 MAINTAINERS   |  6 
 hw/misc/meson.build   |  1 +
 hw/misc/xlnx-cfi-if.c | 34 
 include/hw/misc/xlnx-cfi-if.h | 59 +++
 4 files changed, 100 insertions(+)
 create mode 100644 hw/misc/xlnx-cfi-if.c
 create mode 100644 include/hw/misc/xlnx-cfi-if.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 6111b6b4d9..e0cd365462 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1034,6 +1034,12 @@ S: Maintained
 F: hw/ssi/xlnx-versal-ospi.c
 F: include/hw/ssi/xlnx-versal-ospi.h
 
+Xilinx Versal CFI
+M: Francisco Iglesias 
+S: Maintained
+F: hw/misc/xlnx-cfi-if.c
+F: include/hw/misc/xlnx-cfi-if.h
+
 STM32F100
 M: Alexandre Iooss 
 L: qemu-...@nongnu.org
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index 892f8b91c5..0c562f5e3e 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -97,6 +97,7 @@ specific_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: 
files('xlnx-versal-crl.c'))
 system_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files(
   'xlnx-versal-xramc.c',
   'xlnx-versal-pmc-iou-slcr.c',
+  'xlnx-cfi-if.c',
 ))
 system_ss.add(when: 'CONFIG_STM32F2XX_SYSCFG', if_true: 
files('stm32f2xx_syscfg.c'))
 system_ss.add(when: 'CONFIG_STM32F4XX_SYSCFG', if_true: 
files('stm32f4xx_syscfg.c'))
diff --git a/hw/misc/xlnx-cfi-if.c b/hw/misc/xlnx-cfi-if.c
new file mode 100644
index 00..c45f05c4aa
--- /dev/null
+++ b/hw/misc/xlnx-cfi-if.c
@@ -0,0 +1,34 @@
+/*
+ * Xilinx CFI interface
+ *
+ * Copyright (C) 2023, Advanced Micro Devices, Inc.
+ *
+ * Written by Francisco Iglesias 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include "qemu/osdep.h"
+#include "hw/misc/xlnx-cfi-if.h"
+
+void xlnx_cfi_transfer_packet(XlnxCfiIf *cfi_if, XlnxCfiPacket *pkt)
+{
+XlnxCfiIfClass *xcic = XLNX_CFI_IF_GET_CLASS(cfi_if);
+
+if (xcic->cfi_transfer_packet) {
+xcic->cfi_transfer_packet(cfi_if, pkt);
+}
+}
+
+static const TypeInfo xlnx_cfi_if_info = {
+.name  = TYPE_XLNX_CFI_IF,
+.parent= TYPE_INTERFACE,
+.class_size = sizeof(XlnxCfiIfClass),
+};
+
+static void xlnx_cfi_if_register_types(void)
+{
+type_register_static(_cfi_if_info);
+}
+
+type_init(xlnx_cfi_if_register_types)
+
diff --git a/include/hw/misc/xlnx-cfi-if.h b/include/hw/misc/xlnx-cfi-if.h
new file mode 100644
index 00..f9bd12292d
--- /dev/null
+++ b/include/hw/misc/xlnx-cfi-if.h
@@ -0,0 +1,59 @@
+/*
+ * Xilinx CFI interface
+ *
+ * Copyright (C) 2023, Advanced Micro Devices, Inc.
+ *
+ * Written by Francisco Iglesias 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#ifndef XLNX_CFI_IF_H
+#define XLNX_CFI_IF_H 1
+
+#include "qemu/help-texts.h"
+#include "hw/hw.h"
+#include "qom/object.h"
+
+#define TYPE_XLNX_CFI_IF "xlnx-cfi-if"
+typedef struct XlnxCfiIfClass XlnxCfiIfClass;
+DECLARE_CLASS_CHECKERS(XlnxCfiIfClass, XLNX_CFI_IF, TYPE_XLNX_CFI_IF)
+
+#define XLNX_CFI_IF(obj) \
+ INTERFACE_CHECK(XlnxCfiIf, (obj), TYPE_XLNX_CFI_IF)
+
+typedef enum {
+PACKET_TYPE_CFU = 0x52,
+PACKET_TYPE_CFRAME = 0xA1,
+} xlnx_cfi_packet_type;
+
+typedef enum {
+CFRAME_FAR = 1,
+CFRAME_SFR = 2,
+CFRAME_FDRI = 4,
+CFRAME_CMD = 6,
+} xlnx_cfi_reg_addr;
+
+typedef struct XlnxCfiPacket {
+uint8_t reg_addr;
+uint32_t data[4];
+} XlnxCfiPacket;
+
+typedef struct XlnxCfiIf {
+Object Parent;
+} XlnxCfiIf;
+
+typedef struct XlnxCfiIfClass {
+InterfaceClass parent;
+
+void (*cfi_transfer_packet)(XlnxCfiIf *cfi_if, XlnxCfiPacket *pkt);
+} XlnxCfiIfClass;
+
+/**
+ * Transfer a XlnxCfiPacket.
+ *
+ * @cfi_if: the object implementing this interface
+ * @XlnxCfiPacket: a pointer to the XlnxCfiPacket to transfer
+ */
+void xlnx_cfi_transfer_packet(XlnxCfiIf *cfi_if, XlnxCfiPacket *pkt);
+
+#endif /* XLNX_CFI_IF_H */
-- 
2.34.1




[PATCH v3 5/8] hw/misc: Introduce a model of Xilinx Versal's CFRAME_REG

2023-08-24 Thread Francisco Iglesias
Introduce a model of Xilinx Versal's Configuration Frame controller
(CFRAME_REG).

Signed-off-by: Francisco Iglesias 
---
 MAINTAINERS  |   2 +
 hw/misc/meson.build  |   1 +
 hw/misc/xlnx-versal-cframe-reg.c | 685 +++
 include/hw/misc/xlnx-versal-cframe-reg.h | 286 ++
 4 files changed, 974 insertions(+)
 create mode 100644 hw/misc/xlnx-versal-cframe-reg.c
 create mode 100644 include/hw/misc/xlnx-versal-cframe-reg.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 847b997d73..645374c1d9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1041,6 +1041,8 @@ F: hw/misc/xlnx-cfi-if.c
 F: include/hw/misc/xlnx-cfi-if.h
 F: hw/misc/xlnx-versal-cfu.c
 F: include/hw/misc/xlnx-versal-cfu.h
+F: hw/misc/xlnx-versal-cframe-reg.c
+F: include/hw/misc/xlnx-versal-cframe-reg.h
 
 STM32F100
 M: Alexandre Iooss 
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index d95cc3fd87..1b425b03bd 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -99,6 +99,7 @@ system_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files(
   'xlnx-versal-pmc-iou-slcr.c',
   'xlnx-versal-cfu.c',
   'xlnx-cfi-if.c',
+  'xlnx-versal-cframe-reg.c',
 ))
 system_ss.add(when: 'CONFIG_STM32F2XX_SYSCFG', if_true: 
files('stm32f2xx_syscfg.c'))
 system_ss.add(when: 'CONFIG_STM32F4XX_SYSCFG', if_true: 
files('stm32f4xx_syscfg.c'))
diff --git a/hw/misc/xlnx-versal-cframe-reg.c b/hw/misc/xlnx-versal-cframe-reg.c
new file mode 100644
index 00..4c9afb184d
--- /dev/null
+++ b/hw/misc/xlnx-versal-cframe-reg.c
@@ -0,0 +1,685 @@
+/*
+ * QEMU model of the Configuration Frame Control module
+ *
+ * Copyright (C) 2023, Advanced Micro Devices, Inc.
+ *
+ * Written by Francisco Iglesias 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "hw/register.h"
+#include "hw/registerfields.h"
+#include "qemu/bitops.h"
+#include "qemu/log.h"
+#include "qemu/units.h"
+#include "qapi/error.h"
+#include "hw/qdev-properties.h"
+#include "migration/vmstate.h"
+#include "hw/irq.h"
+#include "hw/misc/xlnx-versal-cframe-reg.h"
+
+#ifndef XLNX_VERSAL_CFRAME_REG_ERR_DEBUG
+#define XLNX_VERSAL_CFRAME_REG_ERR_DEBUG 0
+#endif
+
+#define KEYHOLE_STREAM_4K (4 * KiB)
+#define N_WORDS_128BIT 4
+
+#define MAX_BLOCKTYPE 6
+#define MAX_BLOCKTYPE_FRAMES 0xF
+
+enum {
+CFRAME_CMD_WCFG = 1,
+CFRAME_CMD_ROWON = 2,
+CFRAME_CMD_ROWOFF = 3,
+CFRAME_CMD_RCFG = 4,
+CFRAME_CMD_DLPARK = 5,
+};
+
+static gint int_cmp(gconstpointer a, gconstpointer b, gpointer user_data)
+{
+guint ua = GPOINTER_TO_UINT(a);
+guint ub = GPOINTER_TO_UINT(b);
+return (ua > ub) - (ua < ub);
+}
+
+static void cfrm_imr_update_irq(XlnxVersalCFrameReg *s)
+{
+bool pending = s->regs[R_CFRM_ISR0] & ~s->regs[R_CFRM_IMR0];
+qemu_set_irq(s->irq_cfrm_imr, pending);
+}
+
+static void cfrm_isr_postw(RegisterInfo *reg, uint64_t val64)
+{
+XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(reg->opaque);
+cfrm_imr_update_irq(s);
+}
+
+static uint64_t cfrm_ier_prew(RegisterInfo *reg, uint64_t val64)
+{
+XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(reg->opaque);
+
+s->regs[R_CFRM_IMR0] &= ~s->regs[R_CFRM_IER0];
+s->regs[R_CFRM_IER0] = 0;
+cfrm_imr_update_irq(s);
+return 0;
+}
+
+static uint64_t cfrm_idr_prew(RegisterInfo *reg, uint64_t val64)
+{
+XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(reg->opaque);
+
+s->regs[R_CFRM_IMR0] |= s->regs[R_CFRM_IDR0];
+s->regs[R_CFRM_IDR0] = 0;
+cfrm_imr_update_irq(s);
+return 0;
+}
+
+static uint64_t cfrm_itr_prew(RegisterInfo *reg, uint64_t val64)
+{
+XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(reg->opaque);
+
+s->regs[R_CFRM_ISR0] |= s->regs[R_CFRM_ITR0];
+s->regs[R_CFRM_ITR0] = 0;
+cfrm_imr_update_irq(s);
+return 0;
+}
+
+static void cframe_incr_far(XlnxVersalCFrameReg *s)
+{
+uint32_t faddr = ARRAY_FIELD_EX32(s->regs, FAR0, FRAME_ADDR);
+uint32_t blktype = ARRAY_FIELD_EX32(s->regs, FAR0, BLOCKTYPE);
+
+assert(blktype <= MAX_BLOCKTYPE);
+
+faddr++;
+if (faddr > s->cfg.blktype_num_frames[blktype]) {
+/* Restart from 0 and increment block type */
+faddr = 0;
+blktype++;
+
+assert(blktype <= MAX_BLOCKTYPE);
+
+ARRAY_FIELD_DP32(s->regs, FAR0, BLOCKTYPE, blktype);
+}
+
+ARRAY_FIELD_DP32(s->regs, FAR0, FRAME_ADDR, faddr);
+}
+
+static void cfrm_fdri_post_write(RegisterInfo *reg, uint64_t val)
+{
+XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(reg->opaque);
+
+if (s->row_configured && s->rowon && s->wcfg) {
+
+if (fifo32_num_free(>new_f_data) >= N_WORDS_128BIT) {
+fifo32_push(>new_f_data, s->regs[R_FDRI0]);
+fifo32_push(>new_f_data, s->regs[R_FDRI1]);
+fifo32_push(>new_f_data, s->regs[R_FDRI2]);
+fifo32_push(>new_f_data, s->regs[R_FDRI3]);
+}
+
+if (fifo32_is_full(>new_f_data)) {
+

Re: [PATCH v2 5/8] hw/misc: Introduce a model of Xilinx Versal's CFRAME_REG

2023-08-24 Thread Francisco Iglesias

Hi Peter,

On 2023-08-21 15:34, Peter Maydell wrote:

On Thu, 10 Aug 2023 at 20:16, Francisco Iglesias
 wrote:


Introduce a model of Xilinx Versal's Configuration Frame controller
(CFRAME_REG).

Signed-off-by: Francisco Iglesias 
---
  MAINTAINERS  |   2 +
  hw/misc/meson.build  |   1 +
  hw/misc/xlnx-versal-cframe-reg.c | 753 +++
  include/hw/misc/xlnx-versal-cframe-reg.h | 289 +
  4 files changed, 1045 insertions(+)
  create mode 100644 hw/misc/xlnx-versal-cframe-reg.c
  create mode 100644 include/hw/misc/xlnx-versal-cframe-reg.h



+static XlnxCFrame *cframes_get_frame(XlnxVersalCFrameReg *s, uint32_t addr)
+{
+for (int i = 0; i < s->cframes->len; i++) {
+XlnxCFrame *f = _array_index(s->cframes, XlnxCFrame, i);
+
+if (f->addr == addr) {
+return f;
+}
+}
+return NULL;
+}


The handling of this and especially how it turns out in
the migration support still feels quite awkward to me.

The operations we want here seem to be:
  * find a cframe given the 'addr'
  * insert a new cframe for a given 'addr', overwriting any
old data
  * iterate through n cframes starting at a given 'addr'

You can do this with a GTree
https://developer-old.gnome.org/glib/stable/glib-Balanced-Binary-Trees.html
You can use GUINT_TO_POINTER(addr) as the keys, and use
a Fifo32 as your data. Insert-with-overwrite is
g_tree_replace_node(). Find-a-frame is g_tree_lookup().
Iterate through n cframes is
  for (node = g_tree_lookup(...), i = 0; i < n; node =
g_tree_node_next(node), i++) {
 ...
  }

GTrees are supported by the migration code, there is a
VMSTATE_GTREE_DIRECT_KEY_V() macro, so you don't need to
do any pre-save or post-load hooks. (This to me is one
of the main benefits of using it rather than a GArray.)

Is the data in each cframe fixed-size, or can it vary?
The impression I get is that each cframe is always the
same amount of data, and we use a fifo purely to handle
the "guest writes the frame data a word at a time and
when it's all arrived we put it into the cframe data
structure". If so, it might be simpler to use a fifo32
for the new_f, but have the data in the gtree structure
be a simple fixed-size block of memory.



Thank you very much for the suggestionA I'll switch to a GTree in v3! 
(And it is correct above, both regarding required operations and that 
the cframes are fixed sized).



+
+static void cframe_alloc(XlnxCFrame *f)
+{
+f->addr = 0;
+fifo32_create(>data, FRAME_NUM_WORDS);
+}
+
+static void cframe_move(XlnxCFrame *dst, XlnxCFrame *src)
+{
+fifo32_destroy(>data);
+dst[0] = src[0];
+}
+
+static void cfrm_fdri_post_write(RegisterInfo *reg, uint64_t val)
+{
+XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(reg->opaque);
+
+if (s->row_configured && s->rowon && s->wcfg) {
+XlnxCFrame *new_f = >new_f;
+
+if (fifo32_num_free(_f->data) >= N_WORDS_128BIT) {
+fifo32_push(_f->data, s->regs[R_FDRI0]);
+fifo32_push(_f->data, s->regs[R_FDRI1]);
+fifo32_push(_f->data, s->regs[R_FDRI2]);
+fifo32_push(_f->data, s->regs[R_FDRI3]);
+}
+
+if (fifo32_is_full(_f->data)) {
+XlnxCFrame *cur_f;
+
+/* Include block type and frame address */
+new_f->addr = extract32(s->regs[R_FAR0], 0, 23);
+
+cur_f = cframes_get_frame(s, new_f->addr);
+
+if (cur_f) {
+cframe_move(cur_f, new_f);
+} else {
+g_array_append_val(s->cframes, new_f[0]);
+}
+
+cframe_incr_far(s);
+
+/* Realloc new_f */
+cframe_alloc(new_f);
+}
+}
+}
+
+static void cfrm_readout_frames(XlnxVersalCFrameReg *s, uint32_t start_addr,
+uint32_t end_addr)
+{
+for (uint32_t addr = start_addr; addr < end_addr; addr++) {
+XlnxCFrame *f = cframes_get_frame(s, addr);
+
+/* Transmit the data if a frame was found */
+if (f) {
+Fifo32 data = f->data;
+
+while (!fifo32_is_empty()) {
+XlnxCfiPacket pkt = {};
+
+g_assert(fifo32_num_used() >= N_WORDS_128BIT);
+
+pkt.data[0] = fifo32_pop();
+pkt.data[1] = fifo32_pop();
+pkt.data[2] = fifo32_pop();
+pkt.data[3] = fifo32_pop();
+
+if (s->cfg.cfu_fdro) {
+xlnx_cfi_transfer_packet(s->cfg.cfu_fdro, );
+}
+}
+}
+}
+}
+
+static void cfrm_frcnt_post_write(RegisterInfo *reg, uint64_t val)
+{
+XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(reg->opaque);
+
+if (s->row_configured && s->rowon && s->rcfg) {
+uint32_t start_addr = extract32(s->regs[R_FAR0], 0, 23);
+uint32_t end_addr = start_addr + s->regs[R_FRCNT0] / FRAME_NUM_QWORDS;
+
+cfrm_readout_frames(s, start_addr, 

[PATCH v3 6/8] hw/misc: Introduce a model of Xilinx Versal's CFRAME_BCAST_REG

2023-08-24 Thread Francisco Iglesias
Introduce a model of Xilinx Versal's Configuration Frame broadcast
controller (CFRAME_BCAST_REG).

Signed-off-by: Francisco Iglesias 
Reviewed-by: Peter Maydell 
---
 hw/misc/xlnx-versal-cframe-reg.c | 161 +++
 include/hw/misc/xlnx-versal-cframe-reg.h |  17 +++
 2 files changed, 178 insertions(+)

diff --git a/hw/misc/xlnx-versal-cframe-reg.c b/hw/misc/xlnx-versal-cframe-reg.c
index 4c9afb184d..2ce62c1b2e 100644
--- a/hw/misc/xlnx-versal-cframe-reg.c
+++ b/hw/misc/xlnx-versal-cframe-reg.c
@@ -557,6 +557,83 @@ static const MemoryRegionOps cframe_reg_fdri_ops = {
 },
 };
 
+static uint64_t cframes_bcast_reg_read(void *opaque, hwaddr addr, unsigned 
size)
+{
+qemu_log_mask(LOG_GUEST_ERROR, "%s: Unsupported read from addr=%"
+  HWADDR_PRIx "\n", __func__, addr);
+return 0;
+}
+
+static void cframes_bcast_write(XlnxVersalCFrameBcastReg *s, uint8_t reg_addr,
+uint32_t *wfifo)
+{
+XlnxCfiPacket pkt = {
+.reg_addr = reg_addr,
+.data[0] = wfifo[0],
+.data[1] = wfifo[1],
+.data[2] = wfifo[2],
+.data[3] = wfifo[3]
+};
+
+for (int i = 0; i < ARRAY_SIZE(s->cfg.cframe); i++) {
+if (s->cfg.cframe[i]) {
+xlnx_cfi_transfer_packet(s->cfg.cframe[i], );
+}
+}
+}
+
+static void cframes_bcast_reg_write(void *opaque, hwaddr addr, uint64_t value,
+  unsigned size)
+{
+XlnxVersalCFrameBcastReg *s = XLNX_VERSAL_CFRAME_BCAST_REG(opaque);
+uint32_t wfifo[WFIFO_SZ];
+
+if (update_wfifo(addr, value, s->wfifo, wfifo)) {
+uint8_t reg_addr = extract32(addr, 4, 6);
+
+cframes_bcast_write(s, reg_addr, wfifo);
+}
+}
+
+static uint64_t cframes_bcast_fdri_read(void *opaque, hwaddr addr,
+unsigned size)
+{
+qemu_log_mask(LOG_GUEST_ERROR, "%s: Unsupported read from addr=%"
+  HWADDR_PRIx "\n", __func__, addr);
+return 0;
+}
+
+static void cframes_bcast_fdri_write(void *opaque, hwaddr addr, uint64_t value,
+  unsigned size)
+{
+XlnxVersalCFrameBcastReg *s = XLNX_VERSAL_CFRAME_BCAST_REG(opaque);
+uint32_t wfifo[WFIFO_SZ];
+
+if (update_wfifo(addr, value, s->wfifo, wfifo)) {
+cframes_bcast_write(s, CFRAME_FDRI, wfifo);
+}
+}
+
+static const MemoryRegionOps cframes_bcast_reg_reg_ops = {
+.read = cframes_bcast_reg_read,
+.write = cframes_bcast_reg_write,
+.endianness = DEVICE_LITTLE_ENDIAN,
+.valid = {
+.min_access_size = 4,
+.max_access_size = 4,
+},
+};
+
+static const MemoryRegionOps cframes_bcast_reg_fdri_ops = {
+.read = cframes_bcast_fdri_read,
+.write = cframes_bcast_fdri_write,
+.endianness = DEVICE_LITTLE_ENDIAN,
+.valid = {
+.min_access_size = 4,
+.max_access_size = 4,
+},
+};
+
 static void cframe_reg_realize(DeviceState *dev, Error **errp)
 {
 XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(dev);
@@ -651,6 +728,71 @@ static Property cframe_regs_props[] = {
 DEFINE_PROP_END_OF_LIST(),
 };
 
+static void cframe_bcast_reg_init(Object *obj)
+{
+XlnxVersalCFrameBcastReg *s = XLNX_VERSAL_CFRAME_BCAST_REG(obj);
+SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+
+memory_region_init_io(>iomem_reg, obj, _bcast_reg_reg_ops, s,
+  TYPE_XLNX_VERSAL_CFRAME_BCAST_REG, 
KEYHOLE_STREAM_4K);
+memory_region_init_io(>iomem_fdri, obj, _bcast_reg_fdri_ops, s,
+  TYPE_XLNX_VERSAL_CFRAME_BCAST_REG "-fdri",
+  KEYHOLE_STREAM_4K);
+sysbus_init_mmio(sbd, >iomem_reg);
+sysbus_init_mmio(sbd, >iomem_fdri);
+}
+
+static void cframe_bcast_reg_reset_enter(Object *obj, ResetType type)
+{
+XlnxVersalCFrameBcastReg *s = XLNX_VERSAL_CFRAME_BCAST_REG(obj);
+
+memset(s->wfifo, 0, WFIFO_SZ * sizeof(uint32_t));
+}
+
+static const VMStateDescription vmstate_cframe_bcast_reg = {
+.name = TYPE_XLNX_VERSAL_CFRAME_BCAST_REG,
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32_ARRAY(wfifo, XlnxVersalCFrameBcastReg, 4),
+VMSTATE_END_OF_LIST(),
+}
+};
+
+static Property cframe_bcast_regs_props[] = {
+DEFINE_PROP_LINK("cframe0", XlnxVersalCFrameBcastReg, cfg.cframe[0],
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
+DEFINE_PROP_LINK("cframe1", XlnxVersalCFrameBcastReg, cfg.cframe[1],
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
+DEFINE_PROP_LINK("cframe2", XlnxVersalCFrameBcastReg, cfg.cframe[2],
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
+DEFINE_PROP_LINK("cframe3", XlnxVersalCFrameBcastReg, cfg.cframe[3],
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
+DEFINE_PROP_LINK("cframe4", XlnxVersalCFrameBcastReg, cfg.cframe[4],
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
+DEFINE_PROP_LINK("cframe5", XlnxVersalCFrameBcastReg, cfg.cframe[5],
+  

[PATCH v3 0/8] Xilinx Versal CFI support

2023-08-24 Thread Francisco Iglesias
Hi,

This series adds support for the Configuration Frame Unit (CFU) and the
Configuration Frame controllers (CFRAME) to the Xilinx Versal machine
([1], chapter 21) for emulaing bitstream loading and readback.

The series starts by introducing the Xilinx CFI interface that is
thereafter used by the Xilinx CFU components, the Xilinx CFRAME and Xilinx
CFRAME broadcast models for transfering CFI packets between each other.
Thereafter a model of the CFU_APB, CFU_FDRO and CFU_SFR are introduced and
also models of the CFRAME controller and CFRAME broadcast controller.

The series thereafter ends with connecting the models to Xilinx Versal
machine.

Best regards,
Francisco Iglesias

References:
[1] https://docs.xilinx.com/r/en-US/am011-versal-acap-trm/PSM-Local-Registers


Changelog:
v2->v3:
 [PATCH 5]
   * Swap to store the CFrames in a GTree instead of GArray
   * Rename new_f to new_f_data and also add it to the vmstate 
   * Removed unnecessary 'switch' braces in cframe_reg_cfi_transfer_packet
   * Correct the reset of new_f_data and the cframes GTree


v1->v2:
 [PATCH 2]
   * Use KiB when defining KEYHOLE_STREAM_4K/KEYHOLE_STREAM_256K
   * Updated to be able to share wfifo code 
 [PATCH 3]
   * Swap to use Fifo32 instead of GArray in the CFU_FDRO model
   * Add device reset to the CFU_FDRO model
 [PATCH 4]
   * Add device reset to the CFU_SFR model
 [PATCH 5]
   * Use KiB when defining KEYHOLE_STREAM_4K
   * Add comma after CFRAME_CMD_DLPARK
   * Remove backwards compatibility comment (and the 'cfu' alias propname for
 cfg.cfu_fdro)
   * Use Fifo32 inside the XlnxCFrame structure
   * Reworked cframes_reg_pre_save / cframes_reg_post_load
 [PATCH 6]
   * Add device reset to the CFrame broadcast reg model
 [PATCH 8]
   * Switch to use g_autofree instead of explicit g_free


Francisco Iglesias (8):
  hw/misc: Introduce the Xilinx CFI interface
  hw/misc: Introduce a model of Xilinx Versal's CFU_APB
  hw/misc/xlnx-versal-cfu: Introduce a model of Xilinx Versal CFU_FDRO
  hw/misc/xlnx-versal-cfu: Introduce a model of Xilinx Versal's CFU_SFR
  hw/misc: Introduce a model of Xilinx Versal's CFRAME_REG
  hw/misc: Introduce a model of Xilinx Versal's CFRAME_BCAST_REG
  hw/arm/xlnx-versal: Connect the CFU_APB, CFU_FDRO and CFU_SFR
  hw/arm/versal: Connect the CFRAME_REG and CFRAME_BCAST_REG

 MAINTAINERS  |  10 +
 hw/arm/xlnx-versal.c | 155 -
 hw/misc/meson.build  |   3 +
 hw/misc/xlnx-cfi-if.c|  34 +
 hw/misc/xlnx-versal-cframe-reg.c | 846 +++
 hw/misc/xlnx-versal-cfu.c| 563 +++
 include/hw/arm/xlnx-versal.h |  85 +++
 include/hw/misc/xlnx-cfi-if.h|  59 ++
 include/hw/misc/xlnx-versal-cframe-reg.h | 303 
 include/hw/misc/xlnx-versal-cfu.h| 258 +++
 10 files changed, 2315 insertions(+), 1 deletion(-)
 create mode 100644 hw/misc/xlnx-cfi-if.c
 create mode 100644 hw/misc/xlnx-versal-cframe-reg.c
 create mode 100644 hw/misc/xlnx-versal-cfu.c
 create mode 100644 include/hw/misc/xlnx-cfi-if.h
 create mode 100644 include/hw/misc/xlnx-versal-cframe-reg.h
 create mode 100644 include/hw/misc/xlnx-versal-cfu.h

-- 
2.34.1




[PATCH v3 2/8] hw/misc: Introduce a model of Xilinx Versal's CFU_APB

2023-08-24 Thread Francisco Iglesias
Introduce a model of the software programming interface (CFU_APB) of
Xilinx Versal's Configuration Frame Unit.

Signed-off-by: Francisco Iglesias 
Reviewed-by: Peter Maydell 
---
 MAINTAINERS   |   2 +
 hw/misc/meson.build   |   1 +
 hw/misc/xlnx-versal-cfu.c | 380 ++
 include/hw/misc/xlnx-versal-cfu.h | 231 ++
 4 files changed, 614 insertions(+)
 create mode 100644 hw/misc/xlnx-versal-cfu.c
 create mode 100644 include/hw/misc/xlnx-versal-cfu.h

diff --git a/MAINTAINERS b/MAINTAINERS
index e0cd365462..847b997d73 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1039,6 +1039,8 @@ M: Francisco Iglesias 
 S: Maintained
 F: hw/misc/xlnx-cfi-if.c
 F: include/hw/misc/xlnx-cfi-if.h
+F: hw/misc/xlnx-versal-cfu.c
+F: include/hw/misc/xlnx-versal-cfu.h
 
 STM32F100
 M: Alexandre Iooss 
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index 0c562f5e3e..d95cc3fd87 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -97,6 +97,7 @@ specific_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: 
files('xlnx-versal-crl.c'))
 system_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files(
   'xlnx-versal-xramc.c',
   'xlnx-versal-pmc-iou-slcr.c',
+  'xlnx-versal-cfu.c',
   'xlnx-cfi-if.c',
 ))
 system_ss.add(when: 'CONFIG_STM32F2XX_SYSCFG', if_true: 
files('stm32f2xx_syscfg.c'))
diff --git a/hw/misc/xlnx-versal-cfu.c b/hw/misc/xlnx-versal-cfu.c
new file mode 100644
index 00..b2dc6ab211
--- /dev/null
+++ b/hw/misc/xlnx-versal-cfu.c
@@ -0,0 +1,380 @@
+/*
+ * QEMU model of the CFU Configuration Unit.
+ *
+ * Copyright (C) 2023, Advanced Micro Devices, Inc.
+ *
+ * Written by Edgar E. Iglesias ,
+ *Sai Pavan Boddu ,
+ *Francisco Iglesias 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "hw/register.h"
+#include "hw/irq.h"
+#include "qemu/bitops.h"
+#include "qemu/log.h"
+#include "qemu/units.h"
+#include "migration/vmstate.h"
+#include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
+#include "hw/misc/xlnx-versal-cfu.h"
+
+#ifndef XLNX_VERSAL_CFU_APB_ERR_DEBUG
+#define XLNX_VERSAL_CFU_APB_ERR_DEBUG 0
+#endif
+
+#define KEYHOLE_STREAM_4K (4 * KiB)
+#define KEYHOLE_STREAM_256K (256 * KiB)
+#define CFRAME_BROADCAST_ROW 0x1F
+
+bool update_wfifo(hwaddr addr, uint64_t value,
+  uint32_t *wfifo, uint32_t *wfifo_ret)
+{
+unsigned int idx = extract32(addr, 2, 2);
+
+wfifo[idx] = value;
+
+if (idx == 3) {
+memcpy(wfifo_ret, wfifo, WFIFO_SZ * sizeof(uint32_t));
+memset(wfifo, 0, WFIFO_SZ * sizeof(uint32_t));
+return true;
+}
+
+return false;
+}
+
+static void cfu_imr_update_irq(XlnxVersalCFUAPB *s)
+{
+bool pending = s->regs[R_CFU_ISR] & ~s->regs[R_CFU_IMR];
+qemu_set_irq(s->irq_cfu_imr, pending);
+}
+
+static void cfu_isr_postw(RegisterInfo *reg, uint64_t val64)
+{
+XlnxVersalCFUAPB *s = XLNX_VERSAL_CFU_APB(reg->opaque);
+cfu_imr_update_irq(s);
+}
+
+static uint64_t cfu_ier_prew(RegisterInfo *reg, uint64_t val64)
+{
+XlnxVersalCFUAPB *s = XLNX_VERSAL_CFU_APB(reg->opaque);
+uint32_t val = val64;
+
+s->regs[R_CFU_IMR] &= ~val;
+cfu_imr_update_irq(s);
+return 0;
+}
+
+static uint64_t cfu_idr_prew(RegisterInfo *reg, uint64_t val64)
+{
+XlnxVersalCFUAPB *s = XLNX_VERSAL_CFU_APB(reg->opaque);
+uint32_t val = val64;
+
+s->regs[R_CFU_IMR] |= val;
+cfu_imr_update_irq(s);
+return 0;
+}
+
+static uint64_t cfu_itr_prew(RegisterInfo *reg, uint64_t val64)
+{
+XlnxVersalCFUAPB *s = XLNX_VERSAL_CFU_APB(reg->opaque);
+uint32_t val = val64;
+
+s->regs[R_CFU_ISR] |= val;
+cfu_imr_update_irq(s);
+return 0;
+}
+
+static void cfu_fgcr_postw(RegisterInfo *reg, uint64_t val64)
+{
+XlnxVersalCFUAPB *s = XLNX_VERSAL_CFU_APB(reg->opaque);
+uint32_t val = (uint32_t)val64;
+
+/* Do a scan. It always looks good. */
+if (FIELD_EX32(val, CFU_FGCR, SC_HBC_TRIGGER)) {
+ARRAY_FIELD_DP32(s->regs, CFU_STATUS, SCAN_CLEAR_PASS, 1);
+ARRAY_FIELD_DP32(s->regs, CFU_STATUS, SCAN_CLEAR_DONE, 1);
+}
+}
+
+static const RegisterAccessInfo cfu_apb_regs_info[] = {
+{   .name = "CFU_ISR",  .addr = A_CFU_ISR,
+.rsvd = 0xfc00,
+.w1c = 0x3ff,
+.post_write = cfu_isr_postw,
+},{ .name = "CFU_IMR",  .addr = A_CFU_IMR,
+.reset = 0x3ff,
+.rsvd = 0xfc00,
+.ro = 0x3ff,
+},{ .name = "CFU_IER",  .addr = A_CFU_IER,
+.rsvd = 0xfc00,
+.pre_write = cfu_ier_prew,
+},{ .name = "CFU_IDR",  .addr = A_CFU_IDR,
+.rsvd = 0xfc00,
+.pre_write = cfu_idr_prew,
+},{ .name = "CFU_ITR",  .addr = A_CFU_ITR,
+.rsvd = 0xfc00,
+.pre_write = cfu_itr_prew,
+},{ .name = "CFU_PROTECT",  .addr = A_CFU_PROTECT,
+.reset = 0x1,
+},{ .name = "CFU_FGCR",  .addr = A_CFU_FGCR,
+.rsvd = 0x8000,
+

[PATCH v3 3/8] hw/misc/xlnx-versal-cfu: Introduce a model of Xilinx Versal CFU_FDRO

2023-08-24 Thread Francisco Iglesias
Introduce a model of Xilinx Versal's Configuration Frame Unit's data out
port (CFU_FDRO).

Signed-off-by: Francisco Iglesias 
Reviewed-by: Peter Maydell 
---
 hw/misc/xlnx-versal-cfu.c | 96 +++
 include/hw/misc/xlnx-versal-cfu.h | 12 
 2 files changed, 108 insertions(+)

diff --git a/hw/misc/xlnx-versal-cfu.c b/hw/misc/xlnx-versal-cfu.c
index b2dc6ab211..255c1bf4b8 100644
--- a/hw/misc/xlnx-versal-cfu.c
+++ b/hw/misc/xlnx-versal-cfu.c
@@ -264,6 +264,25 @@ static void cfu_stream_write(void *opaque, hwaddr addr, 
uint64_t value,
 }
 }
 
+static uint64_t cfu_fdro_read(void *opaque, hwaddr addr, unsigned size)
+{
+XlnxVersalCFUFDRO *s = XLNX_VERSAL_CFU_FDRO(opaque);
+uint64_t ret = 0;
+
+if (!fifo32_is_empty(>fdro_data)) {
+ret = fifo32_pop(>fdro_data);
+}
+
+return ret;
+}
+
+static void cfu_fdro_write(void *opaque, hwaddr addr, uint64_t value,
+   unsigned size)
+{
+qemu_log_mask(LOG_GUEST_ERROR, "%s: Unsupported write from addr=%"
+  HWADDR_PRIx "\n", __func__, addr);
+}
+
 static const MemoryRegionOps cfu_stream_ops = {
 .read = cfu_stream_read,
 .write = cfu_stream_write,
@@ -274,6 +293,16 @@ static const MemoryRegionOps cfu_stream_ops = {
 },
 };
 
+static const MemoryRegionOps cfu_fdro_ops = {
+.read = cfu_fdro_read,
+.write = cfu_fdro_write,
+.endianness = DEVICE_LITTLE_ENDIAN,
+.valid = {
+.min_access_size = 4,
+.max_access_size = 4,
+},
+};
+
 static void cfu_apb_init(Object *obj)
 {
 XlnxVersalCFUAPB *s = XLNX_VERSAL_CFU_APB(obj);
@@ -305,6 +334,39 @@ static void cfu_apb_init(Object *obj)
 sysbus_init_irq(sbd, >irq_cfu_imr);
 }
 
+static void cfu_fdro_init(Object *obj)
+{
+XlnxVersalCFUFDRO *s = XLNX_VERSAL_CFU_FDRO(obj);
+SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+
+memory_region_init_io(>iomem_fdro, obj, _fdro_ops, s,
+  TYPE_XLNX_VERSAL_CFU_FDRO, KEYHOLE_STREAM_4K);
+sysbus_init_mmio(sbd, >iomem_fdro);
+fifo32_create(>fdro_data, 8 * KiB / sizeof(uint32_t));
+}
+
+static void cfu_fdro_reset_enter(Object *obj, ResetType type)
+{
+XlnxVersalCFUFDRO *s = XLNX_VERSAL_CFU_FDRO(obj);
+
+fifo32_reset(>fdro_data);
+}
+
+static void cfu_fdro_cfi_transfer_packet(XlnxCfiIf *cfi_if, XlnxCfiPacket *pkt)
+{
+XlnxVersalCFUFDRO *s = XLNX_VERSAL_CFU_FDRO(cfi_if);
+
+if (fifo32_num_free(>fdro_data) >= ARRAY_SIZE(pkt->data)) {
+for (int i = 0; i < ARRAY_SIZE(pkt->data); i++) {
+fifo32_push(>fdro_data, pkt->data[i]);
+}
+} else {
+/* It is a programming error to fill the fifo. */
+qemu_log_mask(LOG_GUEST_ERROR,
+  "CFU_FDRO: CFI data dropped due to full read fifo\n");
+}
+}
+
 static Property cfu_props[] = {
 DEFINE_PROP_LINK("cframe0", XlnxVersalCFUAPB, cfg.cframe[0],
  TYPE_XLNX_CFI_IF, XlnxCfiIf *),
@@ -351,6 +413,16 @@ static const VMStateDescription vmstate_cfu_apb = {
 }
 };
 
+static const VMStateDescription vmstate_cfu_fdro = {
+.name = TYPE_XLNX_VERSAL_CFU_FDRO,
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_FIFO32(fdro_data, XlnxVersalCFUFDRO),
+VMSTATE_END_OF_LIST(),
+}
+};
+
 static void cfu_apb_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
@@ -360,6 +432,17 @@ static void cfu_apb_class_init(ObjectClass *klass, void 
*data)
 device_class_set_props(dc, cfu_props);
 }
 
+static void cfu_fdro_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+ResettableClass *rc = RESETTABLE_CLASS(klass);
+XlnxCfiIfClass *xcic = XLNX_CFI_IF_CLASS(klass);
+
+dc->vmsd = _cfu_fdro;
+xcic->cfi_transfer_packet = cfu_fdro_cfi_transfer_packet;
+rc->phases.enter = cfu_fdro_reset_enter;
+}
+
 static const TypeInfo cfu_apb_info = {
 .name  = TYPE_XLNX_VERSAL_CFU_APB,
 .parent= TYPE_SYS_BUS_DEVICE,
@@ -372,9 +455,22 @@ static const TypeInfo cfu_apb_info = {
 }
 };
 
+static const TypeInfo cfu_fdro_info = {
+.name  = TYPE_XLNX_VERSAL_CFU_FDRO,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(XlnxVersalCFUFDRO),
+.class_init= cfu_fdro_class_init,
+.instance_init = cfu_fdro_init,
+.interfaces = (InterfaceInfo[]) {
+{ TYPE_XLNX_CFI_IF },
+{ }
+}
+};
+
 static void cfu_apb_register_types(void)
 {
 type_register_static(_apb_info);
+type_register_static(_fdro_info);
 }
 
 type_init(cfu_apb_register_types)
diff --git a/include/hw/misc/xlnx-versal-cfu.h 
b/include/hw/misc/xlnx-versal-cfu.h
index 62d10caf27..73e9a21af4 100644
--- a/include/hw/misc/xlnx-versal-cfu.h
+++ b/include/hw/misc/xlnx-versal-cfu.h
@@ -20,10 +20,14 @@
 #include "hw/sysbus.h"
 #include "hw/register.h"
 #include "hw/misc/xlnx-cfi-if.h"
+#include 

[PATCH v3 8/8] hw/arm/versal: Connect the CFRAME_REG and CFRAME_BCAST_REG

2023-08-24 Thread Francisco Iglesias
Connect the Configuration Frame controller (CFRAME_REG) and the
Configuration Frame broadcast controller (CFRAME_BCAST_REG) to the
Versal machine.

Signed-off-by: Francisco Iglesias 
Reviewed-by: Peter Maydell 
---
 hw/arm/xlnx-versal.c | 113 ++-
 include/hw/arm/xlnx-versal.h |  69 +
 2 files changed, 181 insertions(+), 1 deletion(-)

diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
index 3f4b4b1560..fa556d8764 100644
--- a/hw/arm/xlnx-versal.c
+++ b/hw/arm/xlnx-versal.c
@@ -27,7 +27,7 @@
 #define XLNX_VERSAL_RCPU_TYPE ARM_CPU_TYPE_NAME("cortex-r5f")
 #define GEM_REVISION0x40070106
 
-#define VERSAL_NUM_PMC_APB_IRQS 3
+#define VERSAL_NUM_PMC_APB_IRQS 18
 #define NUM_OSPI_IRQ_LINES 3
 
 static void versal_create_apu_cpus(Versal *s)
@@ -341,6 +341,7 @@ static void versal_create_pmc_apb_irq_orgate(Versal *s, 
qemu_irq *pic)
  *  - RTC
  *  - BBRAM
  *  - PMC SLCR
+ *  - CFRAME regs (input 3 - 17 to the orgate)
  */
 object_initialize_child(OBJECT(s), "pmc-apb-irq-orgate",
 >pmc.apb_irq_orgate, TYPE_OR_IRQ);
@@ -573,6 +574,42 @@ static void versal_create_ospi(Versal *s, qemu_irq *pic)
 static void versal_create_cfu(Versal *s, qemu_irq *pic)
 {
 SysBusDevice *sbd;
+DeviceState *dev;
+int i;
+const struct {
+uint64_t reg_base;
+uint64_t fdri_base;
+} cframe_addr[] = {
+{ MM_PMC_CFRAME0_REG, MM_PMC_CFRAME0_FDRI },
+{ MM_PMC_CFRAME1_REG, MM_PMC_CFRAME1_FDRI },
+{ MM_PMC_CFRAME2_REG, MM_PMC_CFRAME2_FDRI },
+{ MM_PMC_CFRAME3_REG, MM_PMC_CFRAME3_FDRI },
+{ MM_PMC_CFRAME4_REG, MM_PMC_CFRAME4_FDRI },
+{ MM_PMC_CFRAME5_REG, MM_PMC_CFRAME5_FDRI },
+{ MM_PMC_CFRAME6_REG, MM_PMC_CFRAME6_FDRI },
+{ MM_PMC_CFRAME7_REG, MM_PMC_CFRAME7_FDRI },
+{ MM_PMC_CFRAME8_REG, MM_PMC_CFRAME8_FDRI },
+{ MM_PMC_CFRAME9_REG, MM_PMC_CFRAME9_FDRI },
+{ MM_PMC_CFRAME10_REG, MM_PMC_CFRAME10_FDRI },
+{ MM_PMC_CFRAME11_REG, MM_PMC_CFRAME11_FDRI },
+{ MM_PMC_CFRAME12_REG, MM_PMC_CFRAME12_FDRI },
+{ MM_PMC_CFRAME13_REG, MM_PMC_CFRAME13_FDRI },
+{ MM_PMC_CFRAME14_REG, MM_PMC_CFRAME14_FDRI },
+};
+const struct {
+uint32_t blktype0_frames;
+uint32_t blktype1_frames;
+uint32_t blktype2_frames;
+uint32_t blktype3_frames;
+uint32_t blktype4_frames;
+uint32_t blktype5_frames;
+uint32_t blktype6_frames;
+} cframe_cfg[] = {
+[0] = { 34111, 3528, 12800, 11, 5, 1, 1 },
+[1] = { 38498, 3841, 15361, 13, 7, 3, 1 },
+[2] = { 38498, 3841, 15361, 13, 7, 3, 1 },
+[3] = { 38498, 3841, 15361, 13, 7, 3, 1 },
+};
 
 /* CFU FDRO */
 object_initialize_child(OBJECT(s), "cfu-fdro", >pmc.cfu_fdro,
@@ -583,10 +620,84 @@ static void versal_create_cfu(Versal *s, qemu_irq *pic)
 memory_region_add_subregion(>mr_ps, MM_PMC_CFU_FDRO,
 sysbus_mmio_get_region(sbd, 0));
 
+/* CFRAME REG */
+for (i = 0; i < ARRAY_SIZE(s->pmc.cframe); i++) {
+g_autofree char *name = g_strdup_printf("cframe%d", i);
+
+object_initialize_child(OBJECT(s), name, >pmc.cframe[i],
+TYPE_XLNX_VERSAL_CFRAME_REG);
+
+sbd = SYS_BUS_DEVICE(>pmc.cframe[i]);
+dev = DEVICE(>pmc.cframe[i]);
+
+if (i < ARRAY_SIZE(cframe_cfg)) {
+object_property_set_int(OBJECT(dev), "blktype0-frames",
+cframe_cfg[i].blktype0_frames,
+_abort);
+object_property_set_int(OBJECT(dev), "blktype1-frames",
+cframe_cfg[i].blktype1_frames,
+_abort);
+object_property_set_int(OBJECT(dev), "blktype2-frames",
+cframe_cfg[i].blktype2_frames,
+_abort);
+object_property_set_int(OBJECT(dev), "blktype3-frames",
+cframe_cfg[i].blktype3_frames,
+_abort);
+object_property_set_int(OBJECT(dev), "blktype4-frames",
+cframe_cfg[i].blktype4_frames,
+_abort);
+object_property_set_int(OBJECT(dev), "blktype5-frames",
+cframe_cfg[i].blktype5_frames,
+_abort);
+object_property_set_int(OBJECT(dev), "blktype6-frames",
+cframe_cfg[i].blktype6_frames,
+_abort);
+}
+object_property_set_link(OBJECT(dev), "cfu-fdro",
+ OBJECT(>pmc.cfu_fdro), _fatal);
+
+sysbus_realize(SYS_BUS_DEVICE(dev), _fatal);
+
+memory_region_add_subregion(>mr_ps, 

Re: Failing avocado tests in CI (was: Re: [PULL 00/24] tcg + linux-user queue for 8.1-rc3)

2023-08-24 Thread Richard Henderson

On 8/24/23 08:31, Alex Bennée wrote:

It's some sort of timing issue, which sometimes goes away when re-run.
I was re-running tests *a lot* in order to get them to go green while
running the 8.1 release.


There is a definite regression point for the test_pc_q35 case:


Not exactly "definite" because it does vanish.


which bisects to:

   commit f7eaf9d702efdd02481d5f1c25f7d8e0ffb64c6e (HEAD, refs/bisect/bad)
   Author: Richard Henderson 
   Date:   Tue Aug 1 10:46:03 2023 -0700

   accel/tcg: Do not issue misaligned i/o


Well, since you can reproduce it, would you please debug it.


r~



[PATCH v2 00/48] tcg patch queue

2023-08-24 Thread Richard Henderson
The following changes since commit 50e7a40af372ee5931c99ef7390f5d3d6fbf6ec4:

  Merge tag 'pull-target-arm-20230824' of 
https://git.linaro.org/people/pmaydell/qemu-arm into staging (2023-08-24 
10:08:33 -0400)

are available in the Git repository at:

  https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20230823-2

for you to fetch changes up to 4daad8d9d6b9d426beb8ce505d2164ba36ea3168:

  tcg: spelling fixes (2023-08-24 11:22:42 -0700)


accel/*: Widen pc/saved_insn for *_sw_breakpoint
accel/tcg: Replace remaining target_ulong in system-mode accel
tcg: spelling fixes
tcg: Document bswap, hswap, wswap byte patterns
tcg: Introduce negsetcond opcodes
tcg: Fold deposit with zero to and
tcg: Unify TCG_TARGET_HAS_extr[lh]_i64_i32
tcg/i386: Drop BYTEH deposits for 64-bit
tcg/i386: Allow immediate as input to deposit
target/*: Use tcg_gen_negsetcond_*


Anton Johansson (9):
  accel/kvm: Widen pc/saved_insn for kvm_sw_breakpoint
  accel/hvf: Widen pc/saved_insn for hvf_sw_breakpoint
  sysemu/kvm: Use vaddr for kvm_arch_[insert|remove]_hw_breakpoint
  sysemu/hvf: Use vaddr for hvf_arch_[insert|remove]_hw_breakpoint
  include/exec: Replace target_ulong with abi_ptr in cpu_[st|ld]*()
  include/exec: typedef abi_ptr to vaddr in softmmu
  include/exec: Widen tlb_hit/tlb_hit_page()
  accel/tcg: Widen address arg in tlb_compare_set()
  accel/tcg: Update run_on_cpu_data static assert

Mark Cave-Ayland (1):
  docs/devel/tcg-ops: fix missing newlines in "Host vector operations"

Michael Tokarev (1):
  tcg: spelling fixes

Philippe Mathieu-Daudé (9):
  docs/devel/tcg-ops: Bury mentions of trunc_shr_i64_i32()
  tcg/tcg-op: Document bswap16_i32() byte pattern
  tcg/tcg-op: Document bswap16_i64() byte pattern
  tcg/tcg-op: Document bswap32_i32() byte pattern
  tcg/tcg-op: Document bswap32_i64() byte pattern
  tcg/tcg-op: Document bswap64_i64() byte pattern
  tcg/tcg-op: Document hswap_i32/64() byte pattern
  tcg/tcg-op: Document wswap_i64() byte pattern
  target/cris: Fix a typo in gen_swapr()

Richard Henderson (28):
  target/m68k: Use tcg_gen_deposit_i32 in gen_partset_reg
  tcg/i386: Drop BYTEH deposits for 64-bit
  tcg: Fold deposit with zero to and
  tcg/i386: Allow immediate as input to deposit_*
  tcg: Unify TCG_TARGET_HAS_extr[lh]_i64_i32
  tcg: Introduce negsetcond opcodes
  tcg: Use tcg_gen_negsetcond_*
  target/alpha: Use tcg_gen_movcond_i64 in gen_fold_mzero
  target/arm: Use tcg_gen_negsetcond_*
  target/m68k: Use tcg_gen_negsetcond_*
  target/openrisc: Use tcg_gen_negsetcond_*
  target/ppc: Use tcg_gen_negsetcond_*
  target/sparc: Use tcg_gen_movcond_i64 in gen_edge
  target/tricore: Replace gen_cond_w with tcg_gen_negsetcond_tl
  tcg/ppc: Implement negsetcond_*
  tcg/ppc: Use the Set Boolean Extension
  tcg/aarch64: Implement negsetcond_*
  tcg/arm: Implement negsetcond_i32
  tcg/riscv: Implement negsetcond_*
  tcg/s390x: Implement negsetcond_*
  tcg/sparc64: Implement negsetcond_*
  tcg/i386: Merge tcg_out_brcond{32,64}
  tcg/i386: Merge tcg_out_setcond{32,64}
  tcg/i386: Merge tcg_out_movcond{32,64}
  tcg/i386: Use CMP+SBB in tcg_out_setcond
  tcg/i386: Clear dest first in tcg_out_setcond if possible
  tcg/i386: Use shift in tcg_out_setcond
  tcg/i386: Implement negsetcond_*

 docs/devel/tcg-ops.rst |  15 +-
 accel/tcg/atomic_template.h|  16 +-
 include/exec/cpu-all.h |   4 +-
 include/exec/cpu_ldst.h|  28 +--
 include/sysemu/hvf.h   |  12 +-
 include/sysemu/kvm.h   |  12 +-
 include/tcg/tcg-op-common.h|   4 +
 include/tcg/tcg-op.h   |   2 +
 include/tcg/tcg-opc.h  |   6 +-
 include/tcg/tcg.h  |   4 +-
 tcg/aarch64/tcg-target.h   |   5 +-
 tcg/arm/tcg-target.h   |   1 +
 tcg/i386/tcg-target-con-set.h  |   2 +-
 tcg/i386/tcg-target-con-str.h  |   1 -
 tcg/i386/tcg-target.h  |   9 +-
 tcg/loongarch64/tcg-target.h   |   6 +-
 tcg/mips/tcg-target.h  |   5 +-
 tcg/ppc/tcg-target.h   |   5 +-
 tcg/riscv/tcg-target.h |   5 +-
 tcg/s390x/tcg-target.h |   5 +-
 tcg/sparc64/tcg-target.h   |   5 +-
 tcg/tci/tcg-target.h   |   5 +-
 accel/hvf/hvf-accel-ops.c  |   4 +-
 accel/hvf/hvf-all.c|   2 +-
 accel/kvm/kvm-all.c|   3 +-
 accel/tcg/cputlb.c |  17 +-
 target/alpha/translate.c   |   7 +-
 targ

Re: [PATCH 2/2] io: follow coroutine AioContext in qio_channel_yield()

2023-08-24 Thread Stefan Hajnoczi
On Thu, Aug 24, 2023 at 12:26:05PM +0100, Daniel P. Berrangé wrote:
> On Wed, Aug 23, 2023 at 07:45:04PM -0400, Stefan Hajnoczi wrote:
> > The ongoing QEMU multi-queue block layer effort makes it possible for 
> > multiple
> > threads to process I/O in parallel. The nbd block driver is not compatible 
> > with
> > the multi-queue block layer yet because QIOChannel cannot be used easily 
> > from
> > coroutines running in multiple threads. This series changes the QIOChannel 
> > API
> > to make that possible.
> > 
> > In the current API, calling qio_channel_attach_aio_context() sets the
> > AioContext where qio_channel_yield() installs an fd handler prior to 
> > yielding:
> > 
> >   qio_channel_attach_aio_context(ioc, my_ctx);
> >   ...
> >   qio_channel_yield(ioc); // my_ctx is used here
> >   ...
> >   qio_channel_detach_aio_context(ioc);
> > 
> > This API design has limitations: reading and writing must be done in the 
> > same
> > AioContext and moving between AioContexts involves a cumbersome sequence of 
> > API
> > calls that is not suitable for doing on a per-request basis.
> > 
> > There is no fundamental reason why a QIOChannel needs to run within the
> > same AioContext every time qio_channel_yield() is called. QIOChannel
> > only uses the AioContext while inside qio_channel_yield(). The rest of
> > the time, QIOChannel is independent of any AioContext.
> > 
> > In the new API, qio_channel_yield() queries the AioContext from the current
> > coroutine using qemu_coroutine_get_aio_context(). There is no need to
> > explicitly attach/detach AioContexts anymore and
> > qio_channel_attach_aio_context() and qio_channel_detach_aio_context() are 
> > gone.
> > One coroutine can read from the QIOChannel while another coroutine writes 
> > from
> > a different AioContext.
> > 
> > This API change allows the nbd block driver to use QIOChannel from any 
> > thread.
> > It's important to keep in mind that the block driver already synchronizes
> > QIOChannel access and ensures that two coroutines never read simultaneously 
> > or
> > write simultaneously.
> > 
> > This patch updates all users of qio_channel_attach_aio_context() to the
> > new API. Most conversions are simple, but vhost-user-server requires a
> > new qemu_coroutine_yield() call to quiesce the vu_client_trip()
> > coroutine when not attached to any AioContext.
> > 
> > While the API is has become simpler, there is one wart: QIOChannel has a
> > special case for the iohandler AioContext (used for handlers that must not 
> > run
> > in nested event loops). I didn't find an elegant way preserve that 
> > behavior, so
> > I added a new API called qio_channel_set_follow_coroutine_ctx(ioc, 
> > true|false)
> > for opting in to the new AioContext model. By default QIOChannel uses the
> > iohandler AioHandler. Code that formerly called
> > qio_channel_attach_aio_context() now calls
> > qio_channel_set_follow_coroutine_ctx(ioc, true) once after the QIOChannel is
> > created.
> 
> I wonder if it is better to just pass the AioContext object into
> qio_channel_yield explicitly eg have
> 
>   qio_channel_yield(QIOChannel *ioc,
> AioContext *ctx,
> GIOCondition cond);
> 
> With semantics that if 'ctx == NULL', then we assume the default
> global iohandler context, and for non-default context it must
> be non-NULL ?
> 
> That could nicely de-couple the API  from relying on global
> coroutine/thread state for querying an AioContext, which
> makes it easier to reason about IMHO.

Hi Dan,
I've done most of the audit necessary to understand which AioContext is
used where. The call graph is large because qio_channel_yield() is used
internally by qio_channel_readv_full_all_eof(),
qio_channel_writev_full_all(), and their variants. They would all need
a new AioContext argument.

I think it's not worth passing AioContext explicitly everywhere since
this involves a lot of code changes and more verbosity to achieve what
we already have.

However, If you think the QIOChannel API should pass AioContext
explicitly then I'll go ahead and make the changes.

Here is what I've explored so far:

qio_channel_readv_full_all_eof
  mpqemu_read - should be doable
  qio_channel_readv_all_eof
qio_channel_read_all_eof
  multifd_recv_thread - NULL non-coroutine
vu_message_read - coroutine AioContext
  qio_channel_readv_full_all
hw/virtio/vhost-user.c:backend_read() - NULL non-coroutine
qio_channel_readv_all
  nbd_co_receive_offset_data_payload - coroutine AioContext
  nbd_co_do_receive_one_chunk - coroutine AioContext
  qio_channel_read_all
hw/virtio/vhost-user.c:backend_read() - NULL non-coroutine
tpm_emulator_unix_tx_bufs - NULL non-coroutine
nbd_read - ?
zlib_recv_pages - NULL non-coroutine
zstd_recv_pages - NULL non-coroutine
multifd_initial_recv_packet - NULL non-coroutine
nbd_opt_read - iohandler
pr_manager_helper_read - NULL non-coroutine
   

Re: [PATCH 1/2] io: check there are no qio_channel_yield() coroutines during ->finalize()

2023-08-24 Thread Eric Blake
On Wed, Aug 23, 2023 at 07:45:03PM -0400, Stefan Hajnoczi wrote:
> Callers must clean up their coroutines before calling
> object_unref(OBJECT(ioc)) to prevent an fd handler leak. Add an
> assertion to check this.
> 
> This patch is preparation for the fd handler changes that follow.
> 
> Signed-off-by: Stefan Hajnoczi 
> ---
>  io/channel.c | 4 
>  1 file changed, 4 insertions(+)

Reviewed-by: Eric Blake 

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.
Virtualization:  qemu.org | libguestfs.org




[RFC PATCH 0/2] target/sh4: Disable decode_gusa when plugins enabled

2023-08-24 Thread Richard Henderson
Alex, perhaps this will DTRT for your plugin test case.

r~

Richard Henderson (2):
  accel/tcg: Add plugin_enabled to DisasContextBase
  target/sh4: Disable decode_gusa when plugins enabled

 include/exec/translator.h |  2 ++
 accel/tcg/translator.c|  1 +
 target/sh4/translate.c| 41 +++
 3 files changed, 32 insertions(+), 12 deletions(-)

-- 
2.34.1




  1   2   3   4   >