Re: [PATCH v4 00/15] vfio: VFIO migration support with vIOMMU

2024-06-10 Thread Cédric Le Goater

On 6/7/24 5:10 PM, Joao Martins wrote:

On 06/06/2024 16:43, Cédric Le Goater wrote:

Hello Joao,

On 6/22/23 23:48, Joao Martins wrote:

Hey,

This series introduces support for vIOMMU with VFIO device migration,
particurlarly related to how we do the dirty page tracking.

Today vIOMMUs serve two purposes: 1) enable interrupt remaping 2)
provide dma translation services for guests to provide some form of
guest kernel managed DMA e.g. for nested virt based usage; (1) is specially
required for big VMs with VFs with more than 255 vcpus. We tackle both
and remove the migration blocker when vIOMMU is present provided the
conditions are met. I have both use-cases here in one series, but I am happy
to tackle them in separate series.

As I found out we don't necessarily need to expose the whole vIOMMU
functionality in order to just support interrupt remapping. x86 IOMMUs
on Windows Server 2018[2] and Linux >=5.10, with qemu 7.1+ (or really
Linux guests with commit c40c10 and since qemu commit 8646d9c773d8)
can instantiate a IOMMU just for interrupt remapping without needing to
be advertised/support DMA translation. AMD IOMMU in theory can provide
the same, but Linux doesn't quite support the IR-only part there yet,
only intel-iommu.

The series is organized as following:

Patches 1-5: Today we can't gather vIOMMU details before the guest
establishes their first DMA mapping via the vIOMMU. So these first four
patches add a way for vIOMMUs to be asked of their properties at start
of day. I choose the least churn possible way for now (as opposed to a
treewide conversion) and allow easy conversion a posteriori. As
suggested by Peter Xu[7], I have ressurected Yi's patches[5][6] which
allows us to fetch PCI backing vIOMMU attributes, without necessarily
tieing the caller (VFIO or anyone else) to an IOMMU MR like I
was doing in v3.

Patches 6-8: Handle configs with vIOMMU interrupt remapping but without
DMA translation allowed. Today the 'dma-translation' attribute is
x86-iommu only, but the way this series is structured nothing stops from
other vIOMMUs supporting it too as long as they use
pci_setup_iommu_ops() and the necessary IOMMU MR get_attr attributes
are handled. The blocker is thus relaxed when vIOMMUs are able to toggle
the toggle/report DMA_TRANSLATION attribute. With the patches up to this set,
we've then tackled item (1) of the second paragraph.

Patches 9-15: Simplified a lot from v2 (patch 9) to only track the complete
IOVA address space, leveraging the logic we use to compose the dirty ranges.
The blocker is once again relaxed for vIOMMUs that advertise their IOVA
addressing limits. This tackles item (2). So far I mainly use it with
intel-iommu, although I have a small set of patches for virtio-iommu per
Alex's suggestion in v2.

Comments, suggestions welcome. Thanks for the review!



I spent sometime refreshing your series on upstream QEMU (See [1]) and
gave migration a try with CX-7 VF. LGTM. It doesn't seem we are far
from acceptance in QEMU 9.1. Are we ?


Yeah.

There was a comment from Zhenzhong on the vfio_viommu_preset() here[0]. But I
was looking at that to remind myself what was it that we had to change, but even
with re-reading the thread I can't spot any flaw that needs change.

[0]
https://lore.kernel.org/qemu-devel/de2b72d2-f56b-9350-ce0f-70edfb58e...@intel.com/#r


I introduced a vfio_devices_all_viommu_preset() routine to check all devices
in a container and a simplified version of vfio_viommu_get_max_iova()
returning the space max_iova.



First, I will resend these with the changes I made :

   vfio/common: Extract vIOMMU code from vfio_sync_dirty_bitmap()
   vfio/common: Move dirty tracking ranges update to helper()

I guess the PCIIOMMUOps::get_iommu_attr needs a close review. Is
IOMMU_ATTR_DMA_TRANSLATION a must have ?


It's sort of the 'correct way' of relaxing vIOMMU checks, because you are 100%
guaranteed that the guest won't do DMA. The other outstanding thing related to
that is for older kernels which is to use the directmap for dirty page tracking,
but the moment a mapping is attempted the migration doesn't start or if it's in
progress it gets aborted[*]:

https://lore.kernel.org/qemu-devel/20230908120521.50903-1-joao.m.mart...@oracle.com/

The above link and DMA_TRANSLATION is mostly for the usecase we use that only
cares about vIOMMU for interrupt remapping only and no DMA translation services.
But we can't just disable dma-translation in qemu because it may crash older
kernels, so it supports both old and new this way.

[*] Recently I noticed you improved error reporting, so
vfio_set_migration_error(-EOPNOTSUPP) probably has a better way of getting 
there.


Yes. So, I did a little more change to improve vfio_dirty_tracking_init().


The rest is mostly VFIO internals for dirty tracking.


Right.

I derailed with other work and also stuff required for iommu dirty tracking that
I forgot about these patches, sorry.


That's fine.

I am trying to sort out which patc

Re: [PATCH] aspeed/smc: Reintroduce "dram-base" property for AST2700

2024-06-10 Thread Cédric Le Goater

On 5/27/24 2:43 PM, Cédric Le Goater wrote:

The Aspeed SMC device model use to have a 'sdram_base' property. It
was removed by commit d177892d4a48 ("aspeed/smc: Remove unused
"sdram-base" property") because previous changes simplified the DMA
transaction model to use an offset in RAM and not the physical
address.

The AST2700 SoC has larger address space (64-bit) and a new register
DMA DRAM Side Address High Part (0x7C) is introduced to deal with the
high bits of the DMA address. To be able to compute the offset of the
DMA transaction, as done on the other SoCs, we will need to know where
the DRAM is mapped in the address space. Re-introduce a "dram-base"
property to hold this value.

Signed-off-by: Cédric Le Goater 
---
  include/hw/ssi/aspeed_smc.h | 1 +
  hw/ssi/aspeed_smc.c | 1 +
  2 files changed, 2 insertions(+)



Applied to aspeed-next.

Thanks,

C.




Re: [PATCH] MAINTAINERS: Add reviewers for ASPEED BMCs

2024-06-10 Thread Cédric Le Goater

On 6/5/24 8:03 AM, Jamin Lin wrote:

Add ASPEED members "Steven Lee", "Troy Lee" and "Jamin Lin"
to be reviewers of ASPEED BMCs.

Signed-off-by: Jamin Lin 
Signed-off-by: Troy Lee 
Signed-off-by: Steven Lee 
---
  MAINTAINERS | 3 +++
  1 file changed, 3 insertions(+)


Applied to aspeed-next.

Thanks,

C.







Re: [PATCH v5 00/17] Add AST2700 support

2024-06-10 Thread Cédric Le Goater

On 6/4/24 7:44 AM, Jamin Lin wrote:

Changes from v1:
The patch series supports WDT, SDMC, SMC, SCU, SLI and INTC for AST2700 SoC.

Changes from v2:
- replace is_aarch64 with is_bus64bit for sdmc patch review.
- fix incorrect dram size for AST2700

Changes from v3:
- Add AST2700 Evaluation board in ASPEED document
- Add avocado test cases for AST2700 Evaluation board
- Fix reviewers review issues and add reviewers suggestions
- Implement INTC model GICINT 128 to GICINT136 for AST2700

Changes from v4:
- support 64 bits dma dram address associated with review issues
- support dma start length and 1 byte length unit associated with review issues
- refactor intc model to fix serial console stuck issue and associated with 
review issues

Changes from v5:
- sdmc: incrementing the version of vmstate to 2.
- smc: support different memory region ops for SMC flash region
introduce a new "const MemoryRegionOps *" attribute in AspeedSMCClass 
and
use it in aspeed_smc_flash_realize function.
- intc: fix associated with review issues
- dram size detect: change to use address space API and simplify with write
 transaction on the DRAM memory region of the SoC.
- ast27x0_soc: update aspeed_soc_ast2700_gic function associated with review 
issues
and rename to aspeed_soc_ast2700_gic_realize

Test Version:
qemu commit:
https://github.com/qemu/qemu/commit/74abb45dac6979e7ff76172b7f0a24e869405184
applied patch:
https://patchew.org/QEMU/20240527124315.35356-1-...@redhat.com/

Test steps:
1. Download the latest openbmc image for AST2700 from AspeedTech-BMC/openbmc
repository, https://github.com/AspeedTech-BMC/openbmc/releases/tag/v09.01
link: 
https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.01/ast2700-default-obmc.tar.gz
2. untar ast2700-default-obmc.tar.gz
```
tar -xf ast2700-default-obmc.tar.gz
```
3. Run and the contents of scripts as following
IMGDIR=ast2700-default
UBOOT_SIZE=$(stat --format=%s -L ${IMGDIR}/u-boot-nodtb.bin)
UBOOT_DTB_ADDR=$((0x4 + ${UBOOT_SIZE}))

qemu-system-aarch64 -M ast2700-evb -nographic\
  -device loader,addr=0x4,file=${IMGDIR}/u-boot-nodtb.bin,force-raw=on\
  -device loader,addr=${UBOOT_DTB_ADDR},file=${IMGDIR}/u-boot.dtb,force-raw=on\
  -device loader,addr=0x43000,file=${IMGDIR}/bl31.bin,force-raw=on\
  -device loader,addr=0x43008,file=${IMGDIR}/optee/tee-raw.bin,force-raw=on\
  -device loader,addr=0x43000,cpu-num=0\
  -device loader,addr=0x43000,cpu-num=1\
  -device loader,addr=0x43000,cpu-num=2\
  -device loader,addr=0x43000,cpu-num=3\
  -smp 4\
  -drive file=${IMGDIR}/image-bmc,format=raw,if=mtd\
  -serial mon:stdio\
  -snapshot

Jamin Lin (17):
   aspeed/wdt: Add AST2700 support
   aspeed/sli: Add AST2700 support
   aspeed/sdmc: remove redundant macros
   aspeed/sdmc: fix coding style
   aspeed/sdmc: Add AST2700 support
   aspeed/smc: correct device description
   aspeed/smc: support dma start length and 1 byte length unit
   aspeed/smc: support 64 bits dma dram address
   aspeed/smc: support different memory region ops for SMC flash region
   aspeed/smc: Add AST2700 support
   aspeed/scu: Add AST2700 support
   aspeed/intc: Add AST2700 support
   aspeed/soc: Add AST2700 support
   aspeed: Add an AST2700 eval board
   aspeed/soc: fix incorrect dram size for AST2700
   test/avocado/machine_aspeed.py: Add AST2700 test case
   docs:aspeed: Add AST2700 Evaluation board

  docs/system/arm/aspeed.rst   |  39 +-
  hw/arm/aspeed.c  |  32 ++
  hw/arm/aspeed_ast27x0.c  | 648 +++
  hw/arm/meson.build   |   1 +
  hw/intc/aspeed_intc.c| 360 +
  hw/intc/meson.build  |   1 +
  hw/intc/trace-events |  13 +
  hw/misc/aspeed_scu.c | 306 ++-
  hw/misc/aspeed_sdmc.c| 220 +--
  hw/misc/aspeed_sli.c | 177 +
  hw/misc/meson.build  |   3 +-
  hw/misc/trace-events |  11 +
  hw/ssi/aspeed_smc.c  | 346 -
  hw/ssi/trace-events  |   2 +-
  hw/watchdog/wdt_aspeed.c |  24 ++
  include/hw/arm/aspeed_soc.h  |  30 +-
  include/hw/intc/aspeed_intc.h|  44 +++
  include/hw/misc/aspeed_scu.h |  47 ++-
  include/hw/misc/aspeed_sdmc.h|   5 +-
  include/hw/misc/aspeed_sli.h |  27 ++
  include/hw/ssi/aspeed_smc.h  |   2 +
  include/hw/watchdog/wdt_aspeed.h |   3 +-
  tests/avocado/machine_aspeed.py  |  62 +++
  23 files changed, 2345 insertions(+), 58 deletions(-)
  create mode 100644 hw/arm/aspeed_ast27x0.c
  create mode 100644 hw/intc/aspeed_intc.c
  create mode 100644 hw/misc/aspeed_sli.c
  create mode 100644 include/hw/intc/aspeed_intc.h
  create mode 100644 include/hw/misc/aspeed_sli.h




Applied to aspeed-next.

Thanks,

C.






Re: [PATCH 00/26] hw/ppc: Prefer HumanReadableText over Monitor

2024-06-10 Thread Cédric Le Goater

On 6/10/24 8:20 AM, Philippe Mathieu-Daudé wrote:

Hi,

This series remove uses of Monitor in hw/ppc/,
replacing by the more generic HumanReadableText.
Care is taken to keep the commit bisectables by
updating functions one by one, also easing review.


Did you do any testing ? POWER[8-10] CPUs on pseries and powernv machines
should be checked. A bit tedious I agree but not that long.

Thanks,

C.




For rationale see previous series from Daniel:
https://lore.kernel.org/qemu-devel/20211028155457.967291-1-berra...@redhat.com/

Regards,

Phil.

Philippe Mathieu-Daudé (26):
   hw/ppc: Avoid using Monitor in pnv_phb3_msi_pic_print_info()
   hw/ppc: Avoid using Monitor in icp_pic_print_info()
   hw/ppc: Avoid using Monitor in xive_tctx_pic_print_info()
   hw/ppc: Avoid using Monitor in ics_pic_print_info()
   hw/ppc: Avoid using Monitor in PnvChipClass::intc_print_info()
   hw/ppc: Avoid using Monitor in xive_end_queue_pic_print_info()
   hw/ppc: Avoid using Monitor in spapr_xive_end_pic_print_info()
   hw/ppc: Avoid using Monitor in spapr_xive_pic_print_info()
   hw/ppc: Avoid using Monitor in xive_source_pic_print_info()
   hw/ppc: Avoid using Monitor in pnv_phb4_pic_print_info()
   hw/ppc: Avoid using Monitor in xive_eas_pic_print_info()
   hw/ppc: Avoid using Monitor in xive_end_pic_print_info()
   hw/ppc: Avoid using Monitor in xive_end_eas_pic_print_info()
   hw/ppc: Avoid using Monitor in xive_nvt_pic_print_info()
   hw/ppc: Avoid using Monitor in pnv_xive_pic_print_info()
   hw/ppc: Avoid using Monitor in pnv_psi_pic_print_info()
   hw/ppc: Avoid using Monitor in xive2_eas_pic_print_info()
   hw/ppc: Avoid using Monitor in xive2_end_eas_pic_print_info()
   hw/ppc: Avoid using Monitor in xive2_end_queue_pic_print_info()
   hw/ppc: Avoid using Monitor in xive2_end_pic_print_info()
   hw/ppc: Avoid using Monitor in xive2_nvp_pic_print_info()
   hw/ppc: Avoid using Monitor in pnv_xive2_pic_print_info()
   hw/ppc: Avoid using Monitor in
 SpaprInterruptControllerClass::print_info()
   hw/ppc: Avoid using Monitor in spapr_irq_print_info()
   hw/ppc: Avoid using Monitor in pnv_chip_power9_pic_print_info_child()
   hw/ppc: Avoid using Monitor in pic_print_info()

  include/hw/pci-host/pnv_phb3.h |   2 +-
  include/hw/pci-host/pnv_phb4.h |   2 +-
  include/hw/ppc/pnv_chip.h  |   4 +-
  include/hw/ppc/pnv_psi.h   |   2 +-
  include/hw/ppc/pnv_xive.h  |   4 +-
  include/hw/ppc/spapr_irq.h |   4 +-
  include/hw/ppc/xics.h  |   4 +-
  include/hw/ppc/xive.h  |   4 +-
  include/hw/ppc/xive2_regs.h|   8 +--
  include/hw/ppc/xive_regs.h |   8 +--
  hw/intc/pnv_xive.c |  38 ++--
  hw/intc/pnv_xive2.c|  48 +++
  hw/intc/spapr_xive.c   |  41 ++---
  hw/intc/xics.c |  25 
  hw/intc/xics_spapr.c   |   7 +--
  hw/intc/xive.c | 108 -
  hw/intc/xive2.c|  87 +-
  hw/pci-host/pnv_phb3_msi.c |  21 +++
  hw/pci-host/pnv_phb4.c |  17 +++---
  hw/ppc/pnv.c   |  52 
  hw/ppc/pnv_psi.c   |   9 ++-
  hw/ppc/spapr.c |  11 +++-
  hw/ppc/spapr_irq.c |   4 +-
  23 files changed, 256 insertions(+), 254 deletions(-)






Re: [PATCH 00/26] hw/ppc: Prefer HumanReadableText over Monitor

2024-06-10 Thread Cédric Le Goater

On 6/10/24 8:20 AM, Philippe Mathieu-Daudé wrote:

Hi,

This series remove uses of Monitor in hw/ppc/,
replacing by the more generic HumanReadableText.
Care is taken to keep the commit bisectables by
updating functions one by one, also easing review.

For rationale see previous series from Daniel:
https://lore.kernel.org/qemu-devel/20211028155457.967291-1-berra...@redhat.com/


This looks OK to me but I think there are patches in the ppc queue
that will conflict. I would wait for Nick to send a PR first and
then rebase.

Thanks,

C.





Regards,

Phil.

Philippe Mathieu-Daudé (26):
   hw/ppc: Avoid using Monitor in pnv_phb3_msi_pic_print_info()
   hw/ppc: Avoid using Monitor in icp_pic_print_info()
   hw/ppc: Avoid using Monitor in xive_tctx_pic_print_info()
   hw/ppc: Avoid using Monitor in ics_pic_print_info()
   hw/ppc: Avoid using Monitor in PnvChipClass::intc_print_info()
   hw/ppc: Avoid using Monitor in xive_end_queue_pic_print_info()
   hw/ppc: Avoid using Monitor in spapr_xive_end_pic_print_info()
   hw/ppc: Avoid using Monitor in spapr_xive_pic_print_info()
   hw/ppc: Avoid using Monitor in xive_source_pic_print_info()
   hw/ppc: Avoid using Monitor in pnv_phb4_pic_print_info()
   hw/ppc: Avoid using Monitor in xive_eas_pic_print_info()
   hw/ppc: Avoid using Monitor in xive_end_pic_print_info()
   hw/ppc: Avoid using Monitor in xive_end_eas_pic_print_info()
   hw/ppc: Avoid using Monitor in xive_nvt_pic_print_info()
   hw/ppc: Avoid using Monitor in pnv_xive_pic_print_info()
   hw/ppc: Avoid using Monitor in pnv_psi_pic_print_info()
   hw/ppc: Avoid using Monitor in xive2_eas_pic_print_info()
   hw/ppc: Avoid using Monitor in xive2_end_eas_pic_print_info()
   hw/ppc: Avoid using Monitor in xive2_end_queue_pic_print_info()
   hw/ppc: Avoid using Monitor in xive2_end_pic_print_info()
   hw/ppc: Avoid using Monitor in xive2_nvp_pic_print_info()
   hw/ppc: Avoid using Monitor in pnv_xive2_pic_print_info()
   hw/ppc: Avoid using Monitor in
 SpaprInterruptControllerClass::print_info()
   hw/ppc: Avoid using Monitor in spapr_irq_print_info()
   hw/ppc: Avoid using Monitor in pnv_chip_power9_pic_print_info_child()
   hw/ppc: Avoid using Monitor in pic_print_info()

  include/hw/pci-host/pnv_phb3.h |   2 +-
  include/hw/pci-host/pnv_phb4.h |   2 +-
  include/hw/ppc/pnv_chip.h  |   4 +-
  include/hw/ppc/pnv_psi.h   |   2 +-
  include/hw/ppc/pnv_xive.h  |   4 +-
  include/hw/ppc/spapr_irq.h |   4 +-
  include/hw/ppc/xics.h  |   4 +-
  include/hw/ppc/xive.h  |   4 +-
  include/hw/ppc/xive2_regs.h|   8 +--
  include/hw/ppc/xive_regs.h |   8 +--
  hw/intc/pnv_xive.c |  38 ++--
  hw/intc/pnv_xive2.c|  48 +++
  hw/intc/spapr_xive.c   |  41 ++---
  hw/intc/xics.c |  25 
  hw/intc/xics_spapr.c   |   7 +--
  hw/intc/xive.c | 108 -
  hw/intc/xive2.c|  87 +-
  hw/pci-host/pnv_phb3_msi.c |  21 +++
  hw/pci-host/pnv_phb4.c |  17 +++---
  hw/ppc/pnv.c   |  52 
  hw/ppc/pnv_psi.c   |   9 ++-
  hw/ppc/spapr.c |  11 +++-
  hw/ppc/spapr_irq.c |   4 +-
  23 files changed, 256 insertions(+), 254 deletions(-)






Re: [PATCH v4 00/15] vfio: VFIO migration support with vIOMMU

2024-06-06 Thread Cédric Le Goater

Hello Joao,

On 6/22/23 23:48, Joao Martins wrote:

Hey,

This series introduces support for vIOMMU with VFIO device migration,
particurlarly related to how we do the dirty page tracking.

Today vIOMMUs serve two purposes: 1) enable interrupt remaping 2)
provide dma translation services for guests to provide some form of
guest kernel managed DMA e.g. for nested virt based usage; (1) is specially
required for big VMs with VFs with more than 255 vcpus. We tackle both
and remove the migration blocker when vIOMMU is present provided the
conditions are met. I have both use-cases here in one series, but I am happy
to tackle them in separate series.

As I found out we don't necessarily need to expose the whole vIOMMU
functionality in order to just support interrupt remapping. x86 IOMMUs
on Windows Server 2018[2] and Linux >=5.10, with qemu 7.1+ (or really
Linux guests with commit c40c10 and since qemu commit 8646d9c773d8)
can instantiate a IOMMU just for interrupt remapping without needing to
be advertised/support DMA translation. AMD IOMMU in theory can provide
the same, but Linux doesn't quite support the IR-only part there yet,
only intel-iommu.

The series is organized as following:

Patches 1-5: Today we can't gather vIOMMU details before the guest
establishes their first DMA mapping via the vIOMMU. So these first four
patches add a way for vIOMMUs to be asked of their properties at start
of day. I choose the least churn possible way for now (as opposed to a
treewide conversion) and allow easy conversion a posteriori. As
suggested by Peter Xu[7], I have ressurected Yi's patches[5][6] which
allows us to fetch PCI backing vIOMMU attributes, without necessarily
tieing the caller (VFIO or anyone else) to an IOMMU MR like I
was doing in v3.

Patches 6-8: Handle configs with vIOMMU interrupt remapping but without
DMA translation allowed. Today the 'dma-translation' attribute is
x86-iommu only, but the way this series is structured nothing stops from
other vIOMMUs supporting it too as long as they use
pci_setup_iommu_ops() and the necessary IOMMU MR get_attr attributes
are handled. The blocker is thus relaxed when vIOMMUs are able to toggle
the toggle/report DMA_TRANSLATION attribute. With the patches up to this set,
we've then tackled item (1) of the second paragraph.

Patches 9-15: Simplified a lot from v2 (patch 9) to only track the complete
IOVA address space, leveraging the logic we use to compose the dirty ranges.
The blocker is once again relaxed for vIOMMUs that advertise their IOVA
addressing limits. This tackles item (2). So far I mainly use it with
intel-iommu, although I have a small set of patches for virtio-iommu per
Alex's suggestion in v2.

Comments, suggestions welcome. Thanks for the review!



I spent sometime refreshing your series on upstream QEMU (See [1]) and
gave migration a try with CX-7 VF. LGTM. It doesn't seem we are far
from acceptance in QEMU 9.1. Are we ?

First, I will resend these with the changes I made :

  vfio/common: Extract vIOMMU code from vfio_sync_dirty_bitmap()
  vfio/common: Move dirty tracking ranges update to helper()

I guess the PCIIOMMUOps::get_iommu_attr needs a close review. Is
IOMMU_ATTR_DMA_TRANSLATION a must have ?

The rest is mostly VFIO internals for dirty tracking.

Thanks,

C.

[1] https://github.com/legoater/qemu/commits/vfio-9.1




Regards,
Joao

Changes since v3[8]:
* Pick up Yi's patches[5][6], and rework the first four patches.
   These are a bit better splitted, and make the new iommu_ops *optional*
   as opposed to a treewide conversion. Rather than returning an IOMMU MR
   and let VFIO operate on it to fetch attributes, we instead let the
   underlying IOMMU driver fetch the desired IOMMU MR and ask for the
   desired IOMMU attribute. Callers only care about PCI Device backing
   vIOMMU attributes regardless of its topology/association. (Peter Xu)
   These patches are a bit better splitted compared to original ones,
   and I've kept all the same authorship and note the changes from
   original where applicable.
* Because of the rework of the first four patches, switch to
   individual attributes in the VFIOSpace that track dma_translation
   and the max_iova. All are expected to be unused when zero to retain
   the defaults of today in common code.
* Improve the migration blocker message of the last patch to be
   more obvious that vIOMMU migration blocker is added when no vIOMMU
   address space limits are advertised. (Patch 15)
* Cast to uintptr_t in IOMMUAttr data in intel-iommu (Philippe).
* Switch to MAKE_64BIT_MASK() instead of plain left shift (Philippe).
* Change diffstat of patches with scripts/git.orderfile (Philippe).

Changes since v2[3]:
* New patches 1-9 to be able to handle vIOMMUs without DMA translation, and
introduce ways to know various IOMMU model attributes via the IOMMU MR. This
is partly meant to address a comment in previous versions where we can't
access the IOMMU MR prior to the DMA mapping happening. Before 

Re: [PATCH] MAINTAINERS: Add reviewers for ASPEED BMCs

2024-06-05 Thread Cédric Le Goater

On 6/5/24 08:03, Jamin Lin wrote:

Add ASPEED members "Steven Lee", "Troy Lee" and "Jamin Lin"
to be reviewers of ASPEED BMCs.

Signed-off-by: Jamin Lin 
Signed-off-by: Troy Lee 
Signed-off-by: Steven Lee 



Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  MAINTAINERS | 3 +++
  1 file changed, 3 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 951556224a..0f63bcdc7d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1158,6 +1158,9 @@ F: docs/system/arm/emcraft-sf2.rst
  ASPEED BMCs
  M: Cédric Le Goater 
  M: Peter Maydell 
+R: Steven Lee 
+R: Troy Lee 
+R: Jamin Lin 
  R: Andrew Jeffery 
  R: Joel Stanley 
  L: qemu-...@nongnu.org





Re: [PATCH] MAINTAINERS: Add maintainers for ASPEED BMCs

2024-06-04 Thread Cédric Le Goater

On 6/5/24 05:44, Jamin Lin wrote:

Add ASPEED members "Steven Lee", "Troy Lee" and "Jamin Lin"
to be maintainers of ASPEED BMCs.


Let's start with Reviewers. please resend.

https://qemu.readthedocs.io/en/v9.0.0/devel/maintainers.html

Thanks,

C.




Signed-off-by: Jamin Lin 
Signed-off-by: Troy Lee 
Signed-off-by: Steven Lee 
---
  MAINTAINERS | 3 +++
  1 file changed, 3 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 951556224a..39651be467 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1158,6 +1158,9 @@ F: docs/system/arm/emcraft-sf2.rst
  ASPEED BMCs
  M: Cédric Le Goater 
  M: Peter Maydell 
+M: Steven Lee 
+M: Troy Lee 
+M: Jamin Lin 
  R: Andrew Jeffery 
  R: Joel Stanley 
  L: qemu-...@nongnu.org





Re: [PATCH 24/32] hw/sd: Subtract bootarea size from blk

2024-06-04 Thread Cédric Le Goater

On 6/3/24 14:31, Philippe Mathieu-Daudé wrote:

On 3/7/23 15:25, Cédric Le Goater wrote:

From: Joel Stanley 

The userdata size is derived from the file the user passes on the
command line, but we must take into account the boot areas.

Signed-off-by: Joel Stanley 
Signed-off-by: Cédric Le Goater 
---
  hw/sd/sd.c | 5 +
  1 file changed, 5 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 6da17a8d0972..1df7c7ac9dae 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -674,6 +674,7 @@ static unsigned sd_boot_capacity_bytes(SDState *sd)
  static void sd_reset(DeviceState *dev)
  {
  SDState *sd = SD_CARD(dev);
+    SDCardClass *sc = SD_CARD_GET_CLASS(sd);
  uint64_t size;
  uint64_t sect;
@@ -685,6 +686,10 @@ static void sd_reset(DeviceState *dev)
  }
  size = sect << 9;
+    if (sc->bootpart_offset) {
+    size -= sd_boot_capacity_bytes(sd) * 2;


IMO this patch and sd_boot_capacity_bytes() definition
from previous patch should be squashed in patch 22 where
you add emmc_cmd_SEND_EXT_CSD.


OK. I will check.

Have you looked at the other patches ?

Thanks,

C.





+    }
+
  sect = sd_addr_to_wpnum(size) + 1;
  sd->state = sd_idle_state;







Re: [PATCH 17/32] hw/sd: Add emmc_cmd_SEND_RELATIVE_ADDR() handler

2024-06-04 Thread Cédric Le Goater

On 6/3/24 14:26, Philippe Mathieu-Daudé wrote:

On 3/7/23 15:24, Cédric Le Goater wrote:

Signed-off-by: Cédric Le Goater 
---
  hw/sd/sd.c | 20 
  1 file changed, 20 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index dd60a16f8c0a..5ff132139ea9 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1053,6 +1053,25 @@ static sd_rsp_type_t sd_cmd_ALL_SEND_CID(SDState *sd, 
SDRequest req)
  return sd_r2_i;
  }
+static void sd_emmc_set_rca(SDState *sd, uint16_t value)
+{
+    sd->rca = value;
+}
+
+static sd_rsp_type_t emmc_cmd_SEND_RELATIVE_ADDR(SDState *sd, SDRequest req)


"emmc_cmd_SET_RELATIVE_ADDR".


Fixed.


Thanks,

C.




Reviewed-by: Philippe Mathieu-Daudé 


+{
+    switch (sd->state) {
+    case sd_identification_state:
+    case sd_standby_state:
+    sd->state = sd_standby_state;
+    sd_emmc_set_rca(sd, req.arg >> 16);
+    return sd_r1;
+
+    default:
+    return sd_invalid_state_for_cmd(sd, req);
+    }
+}
+
  static sd_rsp_type_t sd_cmd_SEND_RELATIVE_ADDR(SDState *sd, SDRequest req)
  {
  switch (sd->state) {
@@ -2194,6 +2213,7 @@ static const SDProto sd_proto_emmc = {
  [0] = sd_cmd_GO_IDLE_STATE,
  [1] = emmc_cmd_SEND_OP_CMD,
  [2] = emmc_cmd_ALL_SEND_CID,
+    [3] = emmc_cmd_SEND_RELATIVE_ADDR,
  [5] = sd_cmd_illegal,
  [19]    = sd_cmd_SEND_TUNING_BLOCK,
  [23]    = sd_cmd_SET_BLOCK_COUNT,







Re: [PATCH v5 00/17] Add AST2700 support

2024-06-04 Thread Cédric Le Goater

On 6/4/24 07:44, Jamin Lin wrote:

Changes from v1:
The patch series supports WDT, SDMC, SMC, SCU, SLI and INTC for AST2700 SoC.

Changes from v2:
- replace is_aarch64 with is_bus64bit for sdmc patch review.
- fix incorrect dram size for AST2700

Changes from v3:
- Add AST2700 Evaluation board in ASPEED document
- Add avocado test cases for AST2700 Evaluation board
- Fix reviewers review issues and add reviewers suggestions
- Implement INTC model GICINT 128 to GICINT136 for AST2700

Changes from v4:
- support 64 bits dma dram address associated with review issues
- support dma start length and 1 byte length unit associated with review issues
- refactor intc model to fix serial console stuck issue and associated with 
review issues

Changes from v5:
- sdmc: incrementing the version of vmstate to 2.
- smc: support different memory region ops for SMC flash region
introduce a new "const MemoryRegionOps *" attribute in AspeedSMCClass 
and
use it in aspeed_smc_flash_realize function.
- intc: fix associated with review issues
- dram size detect: change to use address space API and simplify with write
 transaction on the DRAM memory region of the SoC.
- ast27x0_soc: update aspeed_soc_ast2700_gic function associated with review 
issues
and rename to aspeed_soc_ast2700_gic_realize


v5 looks good to me.

Do you plan to send a MAINTAINERS file ?

Thanks,

C.






Test Version:
qemu commit:
https://github.com/qemu/qemu/commit/74abb45dac6979e7ff76172b7f0a24e869405184
applied patch:
https://patchew.org/QEMU/20240527124315.35356-1-...@redhat.com/

Test steps:
1. Download the latest openbmc image for AST2700 from AspeedTech-BMC/openbmc
repository, https://github.com/AspeedTech-BMC/openbmc/releases/tag/v09.01
link: 
https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.01/ast2700-default-obmc.tar.gz
2. untar ast2700-default-obmc.tar.gz
```
tar -xf ast2700-default-obmc.tar.gz
```
3. Run and the contents of scripts as following
IMGDIR=ast2700-default
UBOOT_SIZE=$(stat --format=%s -L ${IMGDIR}/u-boot-nodtb.bin)
UBOOT_DTB_ADDR=$((0x4 + ${UBOOT_SIZE}))

qemu-system-aarch64 -M ast2700-evb -nographic\
  -device loader,addr=0x4,file=${IMGDIR}/u-boot-nodtb.bin,force-raw=on\
  -device loader,addr=${UBOOT_DTB_ADDR},file=${IMGDIR}/u-boot.dtb,force-raw=on\
  -device loader,addr=0x43000,file=${IMGDIR}/bl31.bin,force-raw=on\
  -device loader,addr=0x43008,file=${IMGDIR}/optee/tee-raw.bin,force-raw=on\
  -device loader,addr=0x43000,cpu-num=0\
  -device loader,addr=0x43000,cpu-num=1\
  -device loader,addr=0x43000,cpu-num=2\
  -device loader,addr=0x43000,cpu-num=3\
  -smp 4\
  -drive file=${IMGDIR}/image-bmc,format=raw,if=mtd\
  -serial mon:stdio\
  -snapshot

Jamin Lin (17):
   aspeed/wdt: Add AST2700 support
   aspeed/sli: Add AST2700 support
   aspeed/sdmc: remove redundant macros
   aspeed/sdmc: fix coding style
   aspeed/sdmc: Add AST2700 support
   aspeed/smc: correct device description
   aspeed/smc: support dma start length and 1 byte length unit
   aspeed/smc: support 64 bits dma dram address
   aspeed/smc: support different memory region ops for SMC flash region
   aspeed/smc: Add AST2700 support
   aspeed/scu: Add AST2700 support
   aspeed/intc: Add AST2700 support
   aspeed/soc: Add AST2700 support
   aspeed: Add an AST2700 eval board
   aspeed/soc: fix incorrect dram size for AST2700
   test/avocado/machine_aspeed.py: Add AST2700 test case
   docs:aspeed: Add AST2700 Evaluation board

  docs/system/arm/aspeed.rst   |  39 +-
  hw/arm/aspeed.c  |  32 ++
  hw/arm/aspeed_ast27x0.c  | 648 +++
  hw/arm/meson.build   |   1 +
  hw/intc/aspeed_intc.c| 360 +
  hw/intc/meson.build  |   1 +
  hw/intc/trace-events |  13 +
  hw/misc/aspeed_scu.c | 306 ++-
  hw/misc/aspeed_sdmc.c| 220 +--
  hw/misc/aspeed_sli.c | 177 +
  hw/misc/meson.build  |   3 +-
  hw/misc/trace-events |  11 +
  hw/ssi/aspeed_smc.c  | 346 -
  hw/ssi/trace-events  |   2 +-
  hw/watchdog/wdt_aspeed.c |  24 ++
  include/hw/arm/aspeed_soc.h  |  30 +-
  include/hw/intc/aspeed_intc.h|  44 +++
  include/hw/misc/aspeed_scu.h |  47 ++-
  include/hw/misc/aspeed_sdmc.h|   5 +-
  include/hw/misc/aspeed_sli.h |  27 ++
  include/hw/ssi/aspeed_smc.h  |   2 +
  include/hw/watchdog/wdt_aspeed.h |   3 +-
  tests/avocado/machine_aspeed.py  |  62 +++
  23 files changed, 2345 insertions(+), 58 deletions(-)
  create mode 100644 hw/arm/aspeed_ast27x0.c
  create mode 100644 hw/intc/aspeed_intc.c
  create mode 100644 hw/misc/aspeed_sli.c
  create mode 100644 include/hw/intc/aspeed_intc.h
  create mode 100644 include/hw/misc/aspeed_sli.h






Re: [PATCH v5 12/17] aspeed/intc: Add AST2700 support

2024-06-04 Thread Cédric Le Goater

On 6/4/24 07:44, Jamin Lin wrote:

AST2700 interrupt controller(INTC) provides hardware interrupt interfaces
to interrupt of processors PSP, SSP and TSP. In INTC, each interrupt of
INT 128 to INT136 combines 32 interrupts.

Introduce a new aspeed_intc class with instance_init and realize handlers.

So far, this model only supports GICINT128 to GICINT136.
It creates 9 GICINT or-gates to connect 32 interrupts sources
from GICINT128 to GICINT136 as IRQ GPIO-OUTPUT pins.
Then, this model registers IRQ handler with its IRQ GPIO-INPUT pins which
connect to GICINT or-gates. And creates 9 GICINT IRQ GPIO-OUTPUT pins which
connect to GIC device with GIC IRQ 128 to 136.

If one interrupt source from GICINT128 to GICINT136
set irq, the OR-GATE irq callback function is called and set irq to INTC by
OR-GATE GPIO-OUTPUT pins. Then, the INTC irq callback function is called and
set irq to GIC by its GICINT IRQ GPIO-OUTPUT pins. Finally, the GIC irq
callback function is called and set irq to CPUs and
CPUs execute Interrupt Service Routine (ISR).

Block diagram of GICINT132:

 GICINT132
   ETH1+---+
+>+0 3|
   ETH2|  4|
+>+1 5|
   ETH3|  6|
+>+219|  INTC  
GIC
   UART0   | 20|+--+
+>+721||  |
+--+
   UART1   | 22||orgate0 +> 
output_pin0+--->+GIC128|
+>+823||  ||
  |
   UART2   | 24||orgate1 +> 
output_pin1+--->+GIC129|
+>+925||  ||
  |
   UART3   | 26||orgate2 +> 
output_pin2+--->+GIC130|
+->10   27||  ||
  |
   UART5   | 28||orgate3 +> 
output_pin3+--->+GIC131|
+>+11   29||  ||
  |
   UART6   |   +--->+orgate4 +> 
output_pin4+--->+GIC132|
+>+12   30||  ||
  |
   UART7   | 31||orgate5 +> 
output_pin5+--->+GIC133|
+>+13 ||  ||
  |
   UART8   |  OR[0:31] ||orgate6 +> 
output_pin6+--->+GIC134|
-->14 ||  ||
  |
   UART9   |   ||orgate7 +> 
output_pin7+--->+GIC135|
->+15 ||  ||
  |
   UART10  |   ||orgate8 +> 
output_pin8+--->+GIC136|
->+16 ||  |
+--+
   UART11  |   |+--+
+>+17 |
   UART12  |   |
+->18 |
   |   |
   |   |
   |   |
   +---+

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 



Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  hw/intc/aspeed_intc.c | 360 ++
  hw/intc/meson.build   |   1 +
  hw/intc/trace-events  |  13 ++
  include/hw/intc/aspeed_intc.h |  44 +
  4 files changed, 418 insertions(+)
  create mode 100644 hw/intc/aspeed_intc.c
  create mode 100644 include/hw/intc/aspeed_intc.h

diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c
new file mode 100644
index 00..e232361791
--- /dev/null
+++ b/hw/intc/aspeed_intc.c
@@ -0,0 +1,360 @@
+/*
+ * ASPEED INTC Controller
+ *
+ * Copyright (C) 2024 ASPEED Technology Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "hw/intc/aspeed_intc.h"
+#include "hw/irq.h"
+#include "qemu/log.h"
+#include "trace.h"
+#include "hw/registerfields.h"
+#include "qapi/error.h"
+
+/* INTC Registers */
+REG32(GICINT128_EN, 0x1000)
+REG32(GICINT128_STATUS, 0x1004)
+REG32(GICINT129_EN, 0x1100)
+REG32(GICINT129_STATUS, 0x1104)
+REG32(GICINT130_EN, 0x1200)
+REG32(GICINT130_STATUS, 0x1204)
+REG32(GICINT131_EN, 0x1300)
+REG32(GICINT131_STATUS, 0x1304)
+REG32(GICINT132_EN, 0x1400)
+REG32(GICINT132_STATUS, 0x1404)
+REG32(GICINT133_EN, 0x1500)
+REG32(GICINT133_STATUS, 0x1504)
+REG32(GICINT134_EN, 0x1600)
+REG32(GICI

Re: [PATCH v5 13/17] aspeed/soc: Add AST2700 support

2024-06-04 Thread Cédric Le Goater

On 6/4/24 07:44, Jamin Lin wrote:

Initial definitions for a simple machine using an AST2700 SOC (Cortex-a35 CPU).

AST2700 SOC and its interrupt controller are too complex to handle
in the common Aspeed SoC framework. We introduce a new ast2700
class with instance_init and realize handlers.

AST2700 is a 64 bits quad core cpus and support 8 watchdog.
Update maximum ASPEED_CPUS_NUM to 4 and ASPEED_WDTS_NUM to 8.
In addition, update AspeedSocState to support scuio, sli, sliio and intc.

Add TYPE_ASPEED27X0_SOC machine type.

The SDMC controller is unlocked at SPL stage.
At present, only supports to emulate booting
start from u-boot stage. Set SDMC controller
unlocked by default.

In INTC, each interrupt of INT 128 to INT 136 combines 32 interrupts.
It connect GICINT IRQ GPIO-OUTPUT pins to GIC device with irq 128 to 136.
And, if a device irq is 128 to 136, its irq GPIO-OUTPUT pin is connected to
GICINT or-gates instead of GIC device.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 



Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  hw/arm/aspeed_ast27x0.c | 563 
  hw/arm/meson.build  |   1 +
  include/hw/arm/aspeed_soc.h |  28 +-
  3 files changed, 590 insertions(+), 2 deletions(-)
  create mode 100644 hw/arm/aspeed_ast27x0.c

diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c
new file mode 100644
index 00..29e75072c4
--- /dev/null
+++ b/hw/arm/aspeed_ast27x0.c
@@ -0,0 +1,563 @@
+/*
+ * ASPEED SoC 27x0 family
+ *
+ * Copyright (C) 2024 ASPEED Technology Inc.
+ *
+ * This code is licensed under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ *
+ * Implementation extracted from the AST2600 and adapted for AST27x0.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/misc/unimp.h"
+#include "hw/arm/aspeed_soc.h"
+#include "qemu/module.h"
+#include "qemu/error-report.h"
+#include "hw/i2c/aspeed_i2c.h"
+#include "net/net.h"
+#include "sysemu/sysemu.h"
+#include "hw/intc/arm_gicv3.h"
+#include "qapi/qmp/qlist.h"
+
+static const hwaddr aspeed_soc_ast2700_memmap[] = {
+[ASPEED_DEV_SPI_BOOT]  =  0x4,
+[ASPEED_DEV_SRAM]  =  0x1000,
+[ASPEED_DEV_SDMC]  =  0x12C0,
+[ASPEED_DEV_SCU]   =  0x12C02000,
+[ASPEED_DEV_SCUIO] =  0x14C02000,
+[ASPEED_DEV_UART0] =  0X14C33000,
+[ASPEED_DEV_UART1] =  0X14C33100,
+[ASPEED_DEV_UART2] =  0X14C33200,
+[ASPEED_DEV_UART3] =  0X14C33300,
+[ASPEED_DEV_UART4] =  0X12C1A000,
+[ASPEED_DEV_UART5] =  0X14C33400,
+[ASPEED_DEV_UART6] =  0X14C33500,
+[ASPEED_DEV_UART7] =  0X14C33600,
+[ASPEED_DEV_UART8] =  0X14C33700,
+[ASPEED_DEV_UART9] =  0X14C33800,
+[ASPEED_DEV_UART10]=  0X14C33900,
+[ASPEED_DEV_UART11]=  0X14C33A00,
+[ASPEED_DEV_UART12]=  0X14C33B00,
+[ASPEED_DEV_WDT]   =  0x14C37000,
+[ASPEED_DEV_VUART] =  0X14C3,
+[ASPEED_DEV_FMC]   =  0x1400,
+[ASPEED_DEV_SPI0]  =  0x1401,
+[ASPEED_DEV_SPI1]  =  0x1402,
+[ASPEED_DEV_SPI2]  =  0x1403,
+[ASPEED_DEV_SDRAM] =  0x4,
+[ASPEED_DEV_MII1]  =  0x1404,
+[ASPEED_DEV_MII2]  =  0x14040008,
+[ASPEED_DEV_MII3]  =  0x14040010,
+[ASPEED_DEV_ETH1]  =  0x1405,
+[ASPEED_DEV_ETH2]  =  0x1406,
+[ASPEED_DEV_ETH3]  =  0x1407,
+[ASPEED_DEV_EMMC]  =  0x1209,
+[ASPEED_DEV_INTC]  =  0x1210,
+[ASPEED_DEV_SLI]   =  0x12C17000,
+[ASPEED_DEV_SLIIO] =  0x14C1E000,
+[ASPEED_GIC_DIST]  =  0x1220,
+[ASPEED_GIC_REDIST]=  0x1228,
+};
+
+#define AST2700_MAX_IRQ 288
+
+/* Shared Peripheral Interrupt values below are offset by -32 from datasheet */
+static const int aspeed_soc_ast2700_irqmap[] = {
+[ASPEED_DEV_UART0] = 132,
+[ASPEED_DEV_UART1] = 132,
+[ASPEED_DEV_UART2] = 132,
+[ASPEED_DEV_UART3] = 132,
+[ASPEED_DEV_UART4] = 8,
+[ASPEED_DEV_UART5] = 132,
+[ASPEED_DEV_UART6] = 132,
+[ASPEED_DEV_UART7] = 132,
+[ASPEED_DEV_UART8] = 132,
+[ASPEED_DEV_UART9] = 132,
+[ASPEED_DEV_UART10]= 132,
+[ASPEED_DEV_UART11]= 132,
+[ASPEED_DEV_UART12]= 132,
+[ASPEED_DEV_FMC]   = 131,
+[ASPEED_DEV_SDMC]  = 0,
+[ASPEED_DEV_SCU]   = 12,
+[ASPEED_DEV_ADC]   = 130,
+[ASPEED_DEV_XDMA]  = 5,
+[ASPEED_DEV_EMMC]  = 15,
+[ASPEED_DEV_GPIO]  = 11,
+[ASPEED_DEV_GPIO_1_8V] = 130,
+[ASPEED_DEV_RTC]   = 13,
+[ASPEED_DEV_TIMER1]= 16,
+[ASPEED_DEV_TIMER2]= 17,
+[ASPEED_DEV_TIMER3]= 18,
+[ASPEED_DEV_TIMER4]= 19,
+[ASPEED_DEV_TIMER5]= 20,
+[ASPEED_DEV_TIMER6]= 21,
+[ASPEED_DEV_TIMER7]  

Re: [PATCH v5 15/17] aspeed/soc: fix incorrect dram size for AST2700

2024-06-04 Thread Cédric Le Goater

On 6/4/24 07:44, Jamin Lin wrote:

AST2700 dram size calculation is not back compatible AST2600.
According to the DDR capacity hardware behavior,
if users write the data to the address which is beyond the ram size,
it would write the data to the "address % ram_size".
For example:
a. sdram base address "0x4 "
b. sdram size 1 GiB
The available address range is from "0x4 " to "0x4 3FFF".
If users write 0x12345678 to address "0x5 ",
the value of DRAM address 0 (base address 0x4 ) will be 0x12345678.

Add aspeed_soc_ast2700_dram_init to calculate the dram size and add
memory I/O whose address range is from "max_ram_size - ram_size" to max_ram_size
and its read/write handler to emulate DDR capacity hardware behavior.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 



Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  hw/arm/aspeed_ast27x0.c | 87 -
  include/hw/arm/aspeed_soc.h |  2 +
  2 files changed, 88 insertions(+), 1 deletion(-)

diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c
index 29e75072c4..b6876b4862 100644
--- a/hw/arm/aspeed_ast27x0.c
+++ b/hw/arm/aspeed_ast27x0.c
@@ -20,6 +20,7 @@
  #include "sysemu/sysemu.h"
  #include "hw/intc/arm_gicv3.h"
  #include "qapi/qmp/qlist.h"
+#include "qemu/log.h"
  
  static const hwaddr aspeed_soc_ast2700_memmap[] = {

  [ASPEED_DEV_SPI_BOOT]  =  0x4,
@@ -191,6 +192,90 @@ static qemu_irq aspeed_soc_ast2700_get_irq(AspeedSoCState 
*s, int dev)
  return qdev_get_gpio_in(DEVICE(>gic), sc->irqmap[dev]);
  }
  
+static uint64_t aspeed_ram_capacity_read(void *opaque, hwaddr addr,

+unsigned int size)
+{
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: DRAM read out of ram size, addr:0x%" PRIx64 "\n",
+   __func__, addr);
+return 0;
+}
+
+static void aspeed_ram_capacity_write(void *opaque, hwaddr addr, uint64_t data,
+unsigned int size)
+{
+AspeedSoCState *s = ASPEED_SOC(opaque);
+ram_addr_t ram_size;
+MemTxResult result;
+
+ram_size = object_property_get_uint(OBJECT(>sdmc), "ram-size",
+_abort);
+
+/*
+ * Emulate ddr capacity hardware behavior.
+ * If writes the data to the address which is beyond the ram size,
+ * it would write the data to the "address % ram_size".
+ */
+result = address_space_write(>dram_as, addr % ram_size,
+ MEMTXATTRS_UNSPECIFIED, , 4);
+if (result != MEMTX_OK) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: DRAM write failed, addr:0x%" HWADDR_PRIx
+  ", data :0x%" PRIx64  "\n",
+  __func__, addr % ram_size, data);
+}
+}
+
+static const MemoryRegionOps aspeed_ram_capacity_ops = {
+.read = aspeed_ram_capacity_read,
+.write = aspeed_ram_capacity_write,
+.endianness = DEVICE_LITTLE_ENDIAN,
+.valid = {
+.min_access_size = 1,
+.max_access_size = 8,
+},
+};
+
+/*
+ * SDMC should be realized first to get correct RAM size and max size
+ * values
+ */
+static bool aspeed_soc_ast2700_dram_init(DeviceState *dev, Error **errp)
+{
+ram_addr_t ram_size, max_ram_size;
+Aspeed27x0SoCState *a = ASPEED27X0_SOC(dev);
+AspeedSoCState *s = ASPEED_SOC(dev);
+AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
+
+ram_size = object_property_get_uint(OBJECT(>sdmc), "ram-size",
+_abort);
+max_ram_size = object_property_get_uint(OBJECT(>sdmc), "max-ram-size",
+_abort);
+
+memory_region_init(>dram_container, OBJECT(s), "ram-container",
+   ram_size);
+memory_region_add_subregion(>dram_container, 0, s->dram_mr);
+address_space_init(>dram_as, s->dram_mr, "dram");
+
+/*
+ * Add a memory region beyond the RAM region to emulate
+ * ddr capacity hardware behavior.
+ */
+if (ram_size < max_ram_size) {
+memory_region_init_io(>dram_empty, OBJECT(s),
+  _ram_capacity_ops, s,
+  "ram-empty", max_ram_size - ram_size);
+
+memory_region_add_subregion(s->memory,
+sc->memmap[ASPEED_DEV_SDRAM] + ram_size,
+>dram_empty);
+}
+
+memory_region_add_subregion(s->memory,
+  sc->memmap[ASPEED_DEV_SDRAM], >dram_container);
+return true;
+}
+
  static void aspeed_soc_ast2700_init(Object *obj)
  {
  Aspeed27x0SoCState *a = ASPEED27X0_SOC(obj);

Re: [PATCH v5 10/17] aspeed/smc: Add AST2700 support

2024-06-04 Thread Cédric Le Goater

On 6/4/24 07:44, Jamin Lin wrote:

AST2700 fmc/spi controller's address decoding unit is 64KB
and only bits [31:16] are used for decoding. Introduce seg_to_reg
and reg_to_seg handlers for ast2700 fmc/spi controller.
In addition, adds ast2700 fmc, spi0, spi1, and spi2 class init handler.

AST2700 is a 64 bits quad core CPUs(Cortex-a35). Introduce a new
"aspeed_2700_smc_flash_ops" and set its valid "max_access_size"
8 for 64 bits data format access.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 



Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  hw/ssi/aspeed_smc.c | 234 +++-
  1 file changed, 233 insertions(+), 1 deletion(-)

diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index 129d06690d..49205ab76d 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -185,7 +185,7 @@
   *   0: 4 bytes
   *   0x1FC: 32M bytes
   *
- * DMA length is from 1 byte to 32MB (AST2600, AST10x0)
+ * DMA length is from 1 byte to 32MB (AST2600, AST10x0 and AST2700)
   *   0: 1 byte
   *   0x1FF: 32M bytes
   */
@@ -1938,6 +1938,234 @@ static const TypeInfo aspeed_1030_spi2_info = {
  .class_init = aspeed_1030_spi2_class_init,
  };
  
+/*

+ * The FMC Segment Registers of the AST2700 have a 64KB unit.
+ * Only bits [31:16] are used for decoding.
+ */
+#define AST2700_SEG_ADDR_MASK 0x
+
+static uint32_t aspeed_2700_smc_segment_to_reg(const AspeedSMCState *s,
+   const AspeedSegments *seg)
+{
+uint32_t reg = 0;
+
+/* Disabled segments have a nil register */
+if (!seg->size) {
+return 0;
+}
+
+reg |= (seg->addr & AST2700_SEG_ADDR_MASK) >> 16; /* start offset */
+reg |= (seg->addr + seg->size - 1) & AST2700_SEG_ADDR_MASK; /* end offset 
*/
+return reg;
+}
+
+static void aspeed_2700_smc_reg_to_segment(const AspeedSMCState *s,
+   uint32_t reg, AspeedSegments *seg)
+{
+uint32_t start_offset = (reg << 16) & AST2700_SEG_ADDR_MASK;
+uint32_t end_offset = reg & AST2700_SEG_ADDR_MASK;
+AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
+
+if (reg) {
+seg->addr = asc->flash_window_base + start_offset;
+seg->size = end_offset + (64 * KiB) - start_offset;
+} else {
+seg->addr = asc->flash_window_base;
+seg->size = 0;
+}
+}
+
+static const uint32_t aspeed_2700_fmc_resets[ASPEED_SMC_R_MAX] = {
+[R_CONF] = (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE0 |
+CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE1),
+[R_CE_CTRL] = 0xaa00,
+[R_CTRL0] = 0x406b0641,
+[R_CTRL1] = 0x0400,
+[R_CTRL2] = 0x0400,
+[R_CTRL3] = 0x0400,
+[R_SEG_ADDR0] = 0x0800,
+[R_SEG_ADDR1] = 0x1800,
+[R_SEG_ADDR2] = 0x,
+[R_SEG_ADDR3] = 0x,
+[R_DUMMY_DATA] = 0x0001,
+[R_DMA_DRAM_ADDR_HIGH] = 0x,
+[R_TIMINGS] = 0x007b,
+};
+
+static const MemoryRegionOps aspeed_2700_smc_flash_ops = {
+.read = aspeed_smc_flash_read,
+.write = aspeed_smc_flash_write,
+.endianness = DEVICE_LITTLE_ENDIAN,
+.valid = {
+.min_access_size = 1,
+.max_access_size = 8,
+},
+};
+
+static const AspeedSegments aspeed_2700_fmc_segments[] = {
+{ 0x0, 128 * MiB }, /* start address is readonly */
+{ 128 * MiB, 128 * MiB }, /* default is disabled but needed for -kernel */
+{ 256 * MiB, 128 * MiB }, /* default is disabled but needed for -kernel */
+{ 0x0, 0 }, /* disabled */
+};
+
+static void aspeed_2700_fmc_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
+
+dc->desc   = "Aspeed 2700 FMC Controller";
+asc->r_conf= R_CONF;
+asc->r_ce_ctrl = R_CE_CTRL;
+asc->r_ctrl0   = R_CTRL0;
+asc->r_timings = R_TIMINGS;
+asc->nregs_timings = 3;
+asc->conf_enable_w0= CONF_ENABLE_W0;
+asc->cs_num_max= 3;
+asc->segments  = aspeed_2700_fmc_segments;
+asc->segment_addr_mask = 0x;
+asc->resets= aspeed_2700_fmc_resets;
+asc->flash_window_base = 0x1;
+asc->flash_window_size = 1 * GiB;
+asc->features  = ASPEED_SMC_FEATURE_DMA |
+ ASPEED_SMC_FEATURE_DMA_DRAM_ADDR_HIGH;
+asc->dma_flash_mask= 0x2FFC;
+asc->dma_dram_mask = 0xFFFC;
+asc->dma_start_length  = 1;
+asc->nregs = ASPEED_SMC_R_MAX;
+asc->segment_to_reg= aspeed_2700_smc_segment_to_reg;
+asc->reg_to_segment= aspeed_2700_smc_reg_to_segment;
+asc->dma_ctrl  = aspeed_2600_smc_dma_ctrl;
+asc->reg_ops   = _2700_smc_flash_ops;
+}
+
+static const TypeInfo aspeed_2

Re: [PATCH v5 09/17] aspeed/smc: support different memory region ops for SMC flash region

2024-06-04 Thread Cédric Le Goater

On 6/4/24 07:44, Jamin Lin wrote:

It set "aspeed_smc_flash_ops" struct which containing
read and write callbacks to be used when I/O is performed
on the SMC flash region. And it set the valid max_access_size 4
by default for all ASPEED SMC models.

However, the valid max_access_size 4 only support 32 bits CPUs.
To support all ASPEED SMC model, introduce a new
"const MemoryRegionOps *" attribute in AspeedSMCClass and
use it in aspeed_smc_flash_realize function.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 


Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  hw/ssi/aspeed_smc.c | 14 +-
  include/hw/ssi/aspeed_smc.h |  1 +
  2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index df0c63469c..129d06690d 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -1316,7 +1316,7 @@ static void aspeed_smc_flash_realize(DeviceState *dev, 
Error **errp)
   * Use the default segment value to size the memory region. This
   * can be changed by FW at runtime.
   */
-memory_region_init_io(>mmio, OBJECT(s), _smc_flash_ops,
+memory_region_init_io(>mmio, OBJECT(s), s->asc->reg_ops,
s, name, s->asc->segments[s->cs].size);
  sysbus_init_mmio(SYS_BUS_DEVICE(dev), >mmio);
  }
@@ -1391,6 +1391,7 @@ static void aspeed_2400_smc_class_init(ObjectClass 
*klass, void *data)
  asc->segment_to_reg= aspeed_smc_segment_to_reg;
  asc->reg_to_segment= aspeed_smc_reg_to_segment;
  asc->dma_ctrl  = aspeed_smc_dma_ctrl;
+asc->reg_ops   = _smc_flash_ops;
  }
  
  static const TypeInfo aspeed_2400_smc_info = {

@@ -1441,6 +1442,7 @@ static void aspeed_2400_fmc_class_init(ObjectClass 
*klass, void *data)
  asc->segment_to_reg= aspeed_smc_segment_to_reg;
  asc->reg_to_segment= aspeed_smc_reg_to_segment;
  asc->dma_ctrl  = aspeed_smc_dma_ctrl;
+asc->reg_ops   = _smc_flash_ops;
  }
  
  static const TypeInfo aspeed_2400_fmc_info = {

@@ -1480,6 +1482,7 @@ static void aspeed_2400_spi1_class_init(ObjectClass 
*klass, void *data)
  asc->reg_to_segment= aspeed_smc_reg_to_segment;
  asc->dma_ctrl  = aspeed_smc_dma_ctrl;
  asc->addr_width= aspeed_2400_spi1_addr_width;
+asc->reg_ops   = _smc_flash_ops;
  }
  
  static const TypeInfo aspeed_2400_spi1_info = {

@@ -1525,6 +1528,7 @@ static void aspeed_2500_fmc_class_init(ObjectClass 
*klass, void *data)
  asc->segment_to_reg= aspeed_smc_segment_to_reg;
  asc->reg_to_segment= aspeed_smc_reg_to_segment;
  asc->dma_ctrl  = aspeed_smc_dma_ctrl;
+asc->reg_ops   = _smc_flash_ops;
  }
  
  static const TypeInfo aspeed_2500_fmc_info = {

@@ -1560,6 +1564,7 @@ static void aspeed_2500_spi1_class_init(ObjectClass 
*klass, void *data)
  asc->segment_to_reg= aspeed_smc_segment_to_reg;
  asc->reg_to_segment= aspeed_smc_reg_to_segment;
  asc->dma_ctrl  = aspeed_smc_dma_ctrl;
+asc->reg_ops   = _smc_flash_ops;
  }
  
  static const TypeInfo aspeed_2500_spi1_info = {

@@ -1595,6 +1600,7 @@ static void aspeed_2500_spi2_class_init(ObjectClass 
*klass, void *data)
  asc->segment_to_reg= aspeed_smc_segment_to_reg;
  asc->reg_to_segment= aspeed_smc_reg_to_segment;
  asc->dma_ctrl  = aspeed_smc_dma_ctrl;
+asc->reg_ops   = _smc_flash_ops;
  }
  
  static const TypeInfo aspeed_2500_spi2_info = {

@@ -1682,6 +1688,7 @@ static void aspeed_2600_fmc_class_init(ObjectClass 
*klass, void *data)
  asc->segment_to_reg= aspeed_2600_smc_segment_to_reg;
  asc->reg_to_segment= aspeed_2600_smc_reg_to_segment;
  asc->dma_ctrl  = aspeed_2600_smc_dma_ctrl;
+asc->reg_ops   = _smc_flash_ops;
  }
  
  static const TypeInfo aspeed_2600_fmc_info = {

@@ -1721,6 +1728,7 @@ static void aspeed_2600_spi1_class_init(ObjectClass 
*klass, void *data)
  asc->segment_to_reg= aspeed_2600_smc_segment_to_reg;
  asc->reg_to_segment= aspeed_2600_smc_reg_to_segment;
  asc->dma_ctrl  = aspeed_2600_smc_dma_ctrl;
+asc->reg_ops   = _smc_flash_ops;
  }
  
  static const TypeInfo aspeed_2600_spi1_info = {

@@ -1761,6 +1769,7 @@ static void aspeed_2600_spi2_class_init(ObjectClass 
*klass, void *data)
  asc->segment_to_reg= aspeed_2600_smc_segment_to_reg;
  asc->reg_to_segment= aspeed_2600_smc_reg_to_segment;
  asc->dma_ctrl  = aspeed_2600_smc_dma_ctrl;
+asc->reg_ops   = _smc_flash_ops;
  }
  
  static const TypeInfo aspeed_2600_spi2_info = {

@@ -1843,6 +1852,7 @@ static void aspeed_1030_fmc_class_init(ObjectClass 
*klass, void *data)
  asc->segment_to_reg= aspeed_1030_smc_segment_to_reg;
  asc->reg_to_segme

Re: [PATCH v5 05/17] aspeed/sdmc: Add AST2700 support

2024-06-04 Thread Cédric Le Goater

On 6/4/24 07:44, Jamin Lin wrote:

The SDRAM memory controller(DRAMC) controls the access to external
DDR4 and DDR5 SDRAM and power up to DDR4 and DDR5 PHY.

The DRAM memory controller of AST2700 is not backward compatible
to previous chips such AST2600, AST2500 and AST2400.

Max memory is now 8GiB on the AST2700. Introduce new
aspeed_2700_sdmc and class with read/write operation and
reset handlers.

Define DRAMC necessary protected registers and
unprotected registers for AST2700 and increase
the register set to 0x1000.

Add unlocked property to change controller protected status.

Incrementing the version of vmstate to 2.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 


Reviewed-by: Cédric Le Goater 


Thanks,

C.




---
  hw/misc/aspeed_sdmc.c | 194 +-
  include/hw/misc/aspeed_sdmc.h |   5 +-
  2 files changed, 195 insertions(+), 4 deletions(-)

diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
index 873d67c592..93e2e29ead 100644
--- a/hw/misc/aspeed_sdmc.c
+++ b/hw/misc/aspeed_sdmc.c
@@ -27,6 +27,7 @@
  #define   PROT_SOFTLOCKED0x00
  
  #define   PROT_KEY_UNLOCK 0xFC600309

+#define   PROT_2700_KEY_UNLOCK  0x1688A8A8
  #define   PROT_KEY_HARDLOCK   0xDEADDEAD /* AST2600 */
  
  /* Configuration Register */

@@ -54,6 +55,46 @@
  #define R_DRAM_TIME   (0x8c / 4)
  #define R_ECC_ERR_INJECT  (0xb4 / 4)
  
+/* AST2700 Register */

+#define R_2700_PROT (0x00 / 4)
+#define R_INT_STATUS(0x04 / 4)
+#define R_INT_CLEAR (0x08 / 4)
+#define R_INT_MASK  (0x0c / 4)
+#define R_MAIN_CONF (0x10 / 4)
+#define R_MAIN_CONTROL  (0x14 / 4)
+#define R_MAIN_STATUS   (0x18 / 4)
+#define R_ERR_STATUS(0x1c / 4)
+#define R_ECC_FAIL_STATUS   (0x78 / 4)
+#define R_ECC_FAIL_ADDR (0x7c / 4)
+#define R_ECC_TESTING_CONTROL   (0x80 / 4)
+#define R_PROT_REGION_LOCK_STATUS   (0x94 / 4)
+#define R_TEST_FAIL_ADDR(0xd4 / 4)
+#define R_TEST_FAIL_D0  (0xd8 / 4)
+#define R_TEST_FAIL_D1  (0xdc / 4)
+#define R_TEST_FAIL_D2  (0xe0 / 4)
+#define R_TEST_FAIL_D3  (0xe4 / 4)
+#define R_DBG_STATUS(0xf4 / 4)
+#define R_PHY_INTERFACE_STATUS  (0xf8 / 4)
+#define R_GRAPHIC_MEM_BASE_ADDR (0x10c / 4)
+#define R_PORT0_INTERFACE_MONITOR0  (0x240 / 4)
+#define R_PORT0_INTERFACE_MONITOR1  (0x244 / 4)
+#define R_PORT0_INTERFACE_MONITOR2  (0x248 / 4)
+#define R_PORT1_INTERFACE_MONITOR0  (0x2c0 / 4)
+#define R_PORT1_INTERFACE_MONITOR1  (0x2c4 / 4)
+#define R_PORT1_INTERFACE_MONITOR2  (0x2c8 / 4)
+#define R_PORT2_INTERFACE_MONITOR0  (0x340 / 4)
+#define R_PORT2_INTERFACE_MONITOR1  (0x344 / 4)
+#define R_PORT2_INTERFACE_MONITOR2  (0x348 / 4)
+#define R_PORT3_INTERFACE_MONITOR0  (0x3c0 / 4)
+#define R_PORT3_INTERFACE_MONITOR1  (0x3c4 / 4)
+#define R_PORT3_INTERFACE_MONITOR2  (0x3c8 / 4)
+#define R_PORT4_INTERFACE_MONITOR0  (0x440 / 4)
+#define R_PORT4_INTERFACE_MONITOR1  (0x444 / 4)
+#define R_PORT4_INTERFACE_MONITOR2  (0x448 / 4)
+#define R_PORT5_INTERFACE_MONITOR0  (0x4c0 / 4)
+#define R_PORT5_INTERFACE_MONITOR1  (0x4c4 / 4)
+#define R_PORT5_INTERFACE_MONITOR2  (0x4c8 / 4)
+
  /*
   * Configuration register Ox4 (for Aspeed AST2400 SOC)
   *
@@ -101,6 +142,19 @@
   ASPEED_SDMC_AST2500_RESERVED | ASPEED_SDMC_VGA_COMPAT |\
   ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB))
  
+/*

+ * Main Configuration register Ox10 (for Aspeed AST2700 SOC and higher)
+ *
+ */
+#define ASPEED_SDMC_AST2700_RESERVED0x2082 /* 31:16, 13, 7, 1 */
+#define ASPEED_SDMC_AST2700_DATA_SCRAMBLE   (1 << 8)
+#define ASPEED_SDMC_AST2700_ECC_ENABLE  (1 << 6)
+#define ASPEED_SDMC_AST2700_PAGE_MATCHING_ENABLE(1 << 5)
+#define ASPEED_SDMC_AST2700_DRAM_SIZE(x)((x & 0x7) << 2)
+
+#define ASPEED_SDMC_AST2700_READONLY_MASK   \
+ (ASPEED_SDMC_AST2700_RESERVED)
+
  static uint64_t aspeed_sdmc_read(void *opaque, hwaddr addr, unsigned size)
  {
  AspeedSDMCState *s = ASPEED_SDMC(opaque);
@@ -216,7 +270,7 @@ static void aspeed_sdmc_realize(DeviceState *dev, Error 
**errp)
  AspeedSDMCState *s = ASPEED_SDMC(dev);
  AspeedSDMCClass *asc = ASPEED_SDMC_GET_CLASS(s);
  
-assert(asc->max_ram_size < 4 * GiB); /* 32-bit address bus */

+assert(asc->max_ram_size < 4 * GiB || asc->is_bus64bit);
  s->max_ram_size = asc->max_ram_size;
  
  memory_region_init_io(>iomem, OBJECT(s), _sdmc_ops, s,

@@ -226,8 +280,8 @@ static void aspeed_sdmc_realize(DeviceState *dev, Error 
**errp)
  
  static const VMStateDescription vmstate_aspeed_sdmc = {

  .name = "aspeed.sdmc",
-.version_id = 1,
-.minimum_version_id = 1,
+.version_id = 2,
+.minimum_version_id = 2,
  .fields = (const VMStateField[]) {
  VMSTATE_UINT32_ARRAY(regs, AspeedSDMCState, ASPEED_S

Re: [PATCH v6 18/19] intel_iommu: Implement [set|unset]_iommu_device() callbacks

2024-06-03 Thread Cédric Le Goater

On 6/3/24 13:02, Duan, Zhenzhong wrote:




-Original Message-
From: CLEMENT MATHIEU--DRIF 
Subject: Re: [PATCH v6 18/19] intel_iommu: Implement
[set|unset]_iommu_device() callbacks


On 03/06/2024 08:10, Zhenzhong Duan wrote:

Caution: External email. Do not open attachments or click links, unless this

email comes from a known sender and you know the content is safe.



From: Yi Liu 

Implement [set|unset]_iommu_device() callbacks in Intel vIOMMU.
In set call, a new structure VTDHostIOMMUDevice which holds
a reference to HostIOMMUDevice is stored in hash table
indexed by PCI BDF.

Signed-off-by: Yi Liu 
Signed-off-by: Yi Sun 
Signed-off-by: Zhenzhong Duan 
---
   hw/i386/intel_iommu_internal.h |  9 
   include/hw/i386/intel_iommu.h  |  2 +
   hw/i386/intel_iommu.c  | 76

++

   3 files changed, 87 insertions(+)

diff --git a/hw/i386/intel_iommu_internal.h

b/hw/i386/intel_iommu_internal.h

index f8cf99bddf..b800d62ca0 100644
--- a/hw/i386/intel_iommu_internal.h
+++ b/hw/i386/intel_iommu_internal.h
@@ -28,6 +28,7 @@
   #ifndef HW_I386_INTEL_IOMMU_INTERNAL_H
   #define HW_I386_INTEL_IOMMU_INTERNAL_H
   #include "hw/i386/intel_iommu.h"
+#include "sysemu/host_iommu_device.h"

   /*
* Intel IOMMU register specification
@@ -537,4 +538,12 @@ typedef struct VTDRootEntry VTDRootEntry;
   #define VTD_SL_IGN_COM  0xbff0ULL
   #define VTD_SL_TM   (1ULL << 62)

+
+typedef struct VTDHostIOMMUDevice {
+IntelIOMMUState *iommu_state;
+PCIBus *bus;
+uint8_t devfn;
+HostIOMMUDevice *dev;
+QLIST_ENTRY(VTDHostIOMMUDevice) next;
+} VTDHostIOMMUDevice;
   #endif
diff --git a/include/hw/i386/intel_iommu.h

b/include/hw/i386/intel_iommu.h

index 7d694b0813..2bbde41e45 100644
--- a/include/hw/i386/intel_iommu.h
+++ b/include/hw/i386/intel_iommu.h
@@ -293,6 +293,8 @@ struct IntelIOMMUState {
   /* list of registered notifiers */
   QLIST_HEAD(, VTDAddressSpace) vtd_as_with_notifiers;

+GHashTable *vtd_host_iommu_dev; /* VTDHostIOMMUDevice

*/

+
   /* interrupt remapping */
   bool intr_enabled;  /* Whether guest enabled IR */
   dma_addr_t intr_root;   /* Interrupt remapping table pointer */
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 519063c8f8..747c988bc4 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -237,6 +237,13 @@ static gboolean vtd_as_equal(gconstpointer v1,

gconstpointer v2)

  (key1->pasid == key2->pasid);
   }

+static gboolean vtd_as_idev_equal(gconstpointer v1, gconstpointer v2)
+{
+const struct vtd_as_key *key1 = v1;
+const struct vtd_as_key *key2 = v2;
+
+return (key1->bus == key2->bus) && (key1->devfn == key2->devfn);
+}
   /*
* Note that we use pointer to PCIBus as the key, so hashing/shifting
* based on the pointer value is intended. Note that we deal with
@@ -3812,6 +3819,70 @@ VTDAddressSpace

*vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus,

   return vtd_dev_as;
   }

+static bool vtd_dev_set_iommu_device(PCIBus *bus, void *opaque, int

devfn,

+ HostIOMMUDevice *hiod, Error **errp)
+{
+IntelIOMMUState *s = opaque;
+VTDHostIOMMUDevice *vtd_hdev;
+struct vtd_as_key key = {
+.bus = bus,
+.devfn = devfn,
+};
+struct vtd_as_key *new_key;
+
+assert(hiod);
+
+vtd_iommu_lock(s);
+
+vtd_hdev = g_hash_table_lookup(s->vtd_host_iommu_dev, );
+
+if (vtd_hdev) {
+error_setg(errp, "IOMMUFD device already exist");
+vtd_iommu_unlock(s);
+return false;
+}
+
+vtd_hdev = g_malloc0(sizeof(VTDHostIOMMUDevice));
+vtd_hdev->bus = bus;
+vtd_hdev->devfn = (uint8_t)devfn;
+vtd_hdev->iommu_state = s;
+vtd_hdev->dev = hiod;
+
+new_key = g_malloc(sizeof(*new_key));
+new_key->bus = bus;
+new_key->devfn = devfn;
+
+object_ref(hiod);
+g_hash_table_insert(s->vtd_host_iommu_dev, new_key, vtd_hdev);
+
+vtd_iommu_unlock(s);
+
+return true;
+}
+
+static void vtd_dev_unset_iommu_device(PCIBus *bus, void *opaque, int

devfn)

+{
+IntelIOMMUState *s = opaque;
+VTDHostIOMMUDevice *vtd_hdev;
+struct vtd_as_key key = {
+.bus = bus,
+.devfn = devfn,
+};
+
+vtd_iommu_lock(s);
+
+vtd_hdev = g_hash_table_lookup(s->vtd_host_iommu_dev, );
+if (!vtd_hdev) {
+vtd_iommu_unlock(s);
+return;
+}
+
+g_hash_table_remove(s->vtd_host_iommu_dev, );
+object_unref(vtd_hdev->dev);

Not sure but isn't that a potential use after free?


Good catch! Will fix. Should be:

object_unref(vtd_hdev->dev);
g_hash_table_remove(s->vtd_host_iommu_dev, );


you could also implement a custom destroy hash function.


Thanks,

C.




Thanks
Zhenzhong


+
+vtd_iommu_unlock(s);
+}
+
   /* Unmap the whole range in the notifier's scope. */
   static void vtd_address_space_unmap(VTDAddressSpace *as,


Re: [PATCH v6 05/19] backends/host_iommu_device: Introduce HostIOMMUDeviceCaps

2024-06-03 Thread Cédric Le Goater

On 6/3/24 08:10, Zhenzhong Duan wrote:

HostIOMMUDeviceCaps's elements map to the host IOMMU's capabilities.
Different platform IOMMU can support different elements.

Currently only two elements, type and aw_bits, type hints the host
platform IOMMU type, i.e., INTEL vtd, ARM smmu, etc; aw_bits hints
host IOMMU address width.

Introduce .get_cap() handler to check if HOST_IOMMU_DEVICE_CAP_XXX
is supported.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 
---
  include/sysemu/host_iommu_device.h | 37 ++
  1 file changed, 37 insertions(+)

diff --git a/include/sysemu/host_iommu_device.h 
b/include/sysemu/host_iommu_device.h
index 2b58a94d62..d47d1034b1 100644
--- a/include/sysemu/host_iommu_device.h
+++ b/include/sysemu/host_iommu_device.h
@@ -15,11 +15,25 @@
  #include "qom/object.h"
  #include "qapi/error.h"
  
+/**

+ * struct HostIOMMUDeviceCaps - Define host IOMMU device capabilities.
+ *
+ * @type: host platform IOMMU type.
+ *
+ * @aw_bits: host IOMMU address width. 0xff if no limitation.


Could we introduce a define for the special value 0xff ? This would answer
Eric's question.


Thanks,

C.




+ */
+typedef struct HostIOMMUDeviceCaps {
+uint32_t type;
+uint8_t aw_bits;
+} HostIOMMUDeviceCaps;
+
  #define TYPE_HOST_IOMMU_DEVICE "host-iommu-device"
  OBJECT_DECLARE_TYPE(HostIOMMUDevice, HostIOMMUDeviceClass, HOST_IOMMU_DEVICE)
  
  struct HostIOMMUDevice {

  Object parent_obj;
+
+HostIOMMUDeviceCaps caps;
  };
  
  /**

@@ -47,5 +61,28 @@ struct HostIOMMUDeviceClass {
   * Returns: true on success, false on failure.
   */
  bool (*realize)(HostIOMMUDevice *hiod, void *opaque, Error **errp);
+/**
+ * @get_cap: check if a host IOMMU device capability is supported.
+ *
+ * Optional callback, if not implemented, hint not supporting query
+ * of @cap.
+ *
+ * @hiod: pointer to a host IOMMU device instance.
+ *
+ * @cap: capability to check.
+ *
+ * @errp: pass an Error out when fails to query capability.
+ *
+ * Returns: <0 on failure, 0 if a @cap is unsupported, or else
+ * 1 or some positive value for some special @cap,
+ * i.e., HOST_IOMMU_DEVICE_CAP_AW_BITS.
+ */
+int (*get_cap)(HostIOMMUDevice *hiod, int cap, Error **errp);
  };
+
+/*
+ * Host IOMMU device capability list.
+ */
+#define HOST_IOMMU_DEVICE_CAP_IOMMU_TYPE0
+#define HOST_IOMMU_DEVICE_CAP_AW_BITS   1
  #endif





Re: [PATCH v6 11/19] backends/iommufd: Implement HostIOMMUDeviceClass::get_cap() handler

2024-06-03 Thread Cédric Le Goater

On 6/3/24 13:32, Eric Auger wrote:



On 6/3/24 08:10, Zhenzhong Duan wrote:

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 
---
  backends/iommufd.c | 23 +++
  1 file changed, 23 insertions(+)

diff --git a/backends/iommufd.c b/backends/iommufd.c
index c7e969d6f7..f2f7a762a0 100644
--- a/backends/iommufd.c
+++ b/backends/iommufd.c
@@ -230,6 +230,28 @@ bool iommufd_backend_get_device_info(IOMMUFDBackend *be, 
uint32_t devid,
  return true;
  }
  
+static int hiod_iommufd_get_cap(HostIOMMUDevice *hiod, int cap, Error **errp)

+{
+HostIOMMUDeviceCaps *caps = >caps;
+
+switch (cap) {
+case HOST_IOMMU_DEVICE_CAP_IOMMU_TYPE:
+return caps->type;
+case HOST_IOMMU_DEVICE_CAP_AW_BITS:
+return caps->aw_bits;
+default:
+error_setg(errp, "Not support get cap %x", cap);

can't you add details about the faulting HostIOMMUDevice by tracing the
devid for instance?


yes.


I would rephrase the error message into No support for capability 0x%x


I was going to propose "Unsupported capability ..."


Thanks,

C.





Eric

+return -EINVAL;
+}
+}
+
+static void hiod_iommufd_class_init(ObjectClass *oc, void *data)
+{
+HostIOMMUDeviceClass *hioc = HOST_IOMMU_DEVICE_CLASS(oc);
+
+hioc->get_cap = hiod_iommufd_get_cap;
+};
+
  static const TypeInfo types[] = {
  {
  .name = TYPE_IOMMUFD_BACKEND,
@@ -246,6 +268,7 @@ static const TypeInfo types[] = {
  }, {
  .name = TYPE_HOST_IOMMU_DEVICE_IOMMUFD,
  .parent = TYPE_HOST_IOMMU_DEVICE,
+.class_init = hiod_iommufd_class_init,
  .abstract = true,
  }
  };







Re: [PATCH v6 01/19] backends: Introduce HostIOMMUDevice abstract

2024-06-03 Thread Cédric Le Goater

On 6/3/24 08:10, Zhenzhong Duan wrote:

Introduce HostIOMMUDevice as an abstraction of host IOMMU device.

Introduce .realize() to initialize HostIOMMUDevice further after
instance init.

Introduce a macro CONFIG_HOST_IOMMU_DEVICE to define the usage
for VFIO, and VDPA in the future.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 
---
  MAINTAINERS|  2 ++
  include/sysemu/host_iommu_device.h | 51 ++
  backends/host_iommu_device.c   | 30 ++
  backends/Kconfig   |  5 +++
  backends/meson.build   |  1 +
  5 files changed, 89 insertions(+)
  create mode 100644 include/sysemu/host_iommu_device.h
  create mode 100644 backends/host_iommu_device.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 448dc951c5..1cf2b25beb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2196,6 +2196,8 @@ M: Zhenzhong Duan 
  S: Supported
  F: backends/iommufd.c
  F: include/sysemu/iommufd.h
+F: backends/host_iommu_device.c
+F: include/sysemu/host_iommu_device.h
  F: include/qemu/chardev_open.h
  F: util/chardev_open.c
  F: docs/devel/vfio-iommufd.rst
diff --git a/include/sysemu/host_iommu_device.h 
b/include/sysemu/host_iommu_device.h
new file mode 100644
index 00..2b58a94d62
--- /dev/null
+++ b/include/sysemu/host_iommu_device.h
@@ -0,0 +1,51 @@
+/*
+ * Host IOMMU device abstract declaration
+ *
+ * Copyright (C) 2024 Intel Corporation.
+ *
+ * Authors: Zhenzhong Duan 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#ifndef HOST_IOMMU_DEVICE_H
+#define HOST_IOMMU_DEVICE_H
+
+#include "qom/object.h"
+#include "qapi/error.h"
+
+#define TYPE_HOST_IOMMU_DEVICE "host-iommu-device"
+OBJECT_DECLARE_TYPE(HostIOMMUDevice, HostIOMMUDeviceClass, HOST_IOMMU_DEVICE)
+
+struct HostIOMMUDevice {
+Object parent_obj;
+};
+
+/**
+ * struct HostIOMMUDeviceClass - The base class for all host IOMMU devices.
+ *
+ * Different type of host devices (e.g., VFIO or VDPA device) or devices
+ * with different backend (e.g., VFIO legacy container or IOMMUFD backend)
+ * can have different sub-classes.
+ */
+struct HostIOMMUDeviceClass {
+ObjectClass parent_class;
+
+/**
+ * @realize: initialize host IOMMU device instance further.
+ *
+ * Mandatory callback.
+ *
+ * @hiod: pointer to a host IOMMU device instance.
+ *
+ * @opaque: pointer to agent device of this host IOMMU device,
+ *  i.e., for VFIO, pointer to VFIODevice
+ *
+ * @errp: pass an Error out when realize fails.
+ *
+ * Returns: true on success, false on failure.
+ */
+bool (*realize)(HostIOMMUDevice *hiod, void *opaque, Error **errp);
+};
+#endif
diff --git a/backends/host_iommu_device.c b/backends/host_iommu_device.c
new file mode 100644
index 00..41f2fdce20
--- /dev/null
+++ b/backends/host_iommu_device.c
@@ -0,0 +1,30 @@
+/*
+ * Host IOMMU device abstract
+ *
+ * Copyright (C) 2024 Intel Corporation.
+ *
+ * Authors: Zhenzhong Duan 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "sysemu/host_iommu_device.h"
+
+OBJECT_DEFINE_ABSTRACT_TYPE(HostIOMMUDevice,
+host_iommu_device,
+HOST_IOMMU_DEVICE,
+OBJECT)
+
+static void host_iommu_device_class_init(ObjectClass *oc, void *data)
+{
+}
+
+static void host_iommu_device_init(Object *obj)
+{
+}
+
+static void host_iommu_device_finalize(Object *obj)
+{
+}
diff --git a/backends/Kconfig b/backends/Kconfig
index 2cb23f62fa..34ab29e994 100644
--- a/backends/Kconfig
+++ b/backends/Kconfig
@@ -3,3 +3,8 @@ source tpm/Kconfig
  config IOMMUFD
  bool
  depends on VFIO
+
+config HOST_IOMMU_DEVICE
+bool
+default y
+depends on VFIO


And you can drop HOST_IOMMU_DEVICE config


diff --git a/backends/meson.build b/backends/meson.build
index 8b2b111497..2e975d641e 100644
--- a/backends/meson.build
+++ b/backends/meson.build
@@ -25,6 +25,7 @@ if have_vhost_user
  endif
  system_ss.add(when: 'CONFIG_VIRTIO_CRYPTO', if_true: 
files('cryptodev-vhost.c'))
  system_ss.add(when: 'CONFIG_IOMMUFD', if_true: files('iommufd.c'))
+system_ss.add(when: 'CONFIG_HOST_IOMMU_DEVICE', if_true: 
files('host_iommu_device.c'))


and I would move host_iommu_device.c build under host_os == 'linux'

Thanks,

C.



  if have_vhost_user_crypto
system_ss.add(when: 'CONFIG_VIRTIO_CRYPTO', if_true: 
files('cryptodev-vhost-user.c'))
  endif





Re: [SPAM] Re: [PATCH v4 09/16] aspeed/smc: Add AST2700 support

2024-06-03 Thread Cédric Le Goater

Thanks for your suggestion. How about these changes?

1. aspeed_smc.h
struct AspeedSMCClass {
 const MemoryRegionOps *reg_ops;
}

2. aspeed_smc.c
a. create new memory region opts for ast2700
static const MemoryRegionOps aspeed_2700_smc_flash_ops = {
 .read = aspeed_smc_flash_read,
 .write = aspeed_smc_flash_write,
 .endianness = DEVICE_LITTLE_ENDIAN,
 .valid = {
 .min_access_size = 1,
 .max_access_size = 8,
 },
};

b. set memory region opts in all model class init
static void aspeed_2400_smc_class_init(ObjectClass *klass, void *data){
 asc->reg_ops   = _smc_flash_ops;
}
static void aspeed_2400_fmc_class_init (ObjectClass *klass, void *data){
 asc->reg_ops   = _smc_flash_ops;
}
static void aspeed_2400_spi1_class_init (ObjectClass *klass, void *data){
 asc->reg_ops   = _smc_flash_ops;
}
static void aspeed_2500_fmc_class_init (ObjectClass *klass, void *data){
 asc->reg_ops   = _smc_flash_ops;
}
static void aspeed_2500_spi1_class_init (ObjectClass *klass, void *data){
 asc->reg_ops   = _smc_flash_ops;
}
static void aspeed_2500_spi2_class_init (ObjectClass *klass, void *data){
 asc->reg_ops   = _smc_flash_ops;
}
static void aspeed_2600_fmc_class_init (ObjectClass *klass, void *data){
 asc->reg_ops   = _smc_flash_ops;
}
static void aspeed_2600_spi1_class_init (ObjectClass *klass, void *data){
 asc->reg_ops   = _smc_flash_ops;
}
static void aspeed_2600_spi2_class_init (ObjectClass *klass, void *data){
 asc->reg_ops   = _smc_flash_ops;
}
static void aspeed_1030_fmc_class_init (ObjectClass *klass, void *data){
 asc->reg_ops   = _smc_flash_ops;
}
static void aspeed_1030_spi1_class_init (ObjectClass *klass, void *data){
 asc->reg_ops   = _smc_flash_ops;
}
static void aspeed_1030_spi2_class_init (ObjectClass *klass, void *data){
 asc->reg_ops   = _smc_flash_ops;
}
static void aspeed_2700_fmc_class_init(ObjectClass *klass, void *data)
{
   asc->reg_ops   = _2700_smc_flash_ops;
}
static void aspeed_2700_spi0_class_init (ObjectClass *klass, void *data)
{
   asc->reg_ops   = _2700_smc_flash_ops;
}
static void aspeed_2700_spi1_class_init (ObjectClass *klass, void *data)
{
   asc->reg_ops   = _2700_smc_flash_ops;
}
static void aspeed_2700_spi2_class_init (ObjectClass *klass, void *data)
{
   asc->reg_ops   = _2700_smc_flash_ops;
}

c. update realize to use memory region opts from class reg_opts
static void aspeed_smc_flash_realize(DeviceState *dev, Error **errp) {
 memory_region_init_io(>mmio, OBJECT(s), s->asc->reg_ops,
   s, name, s->asc->segments[s->cs].size);
}


LGTM,


Thanks,

C.



Re: [SPAM] Re: [PATCH v4 09/16] aspeed/smc: Add AST2700 support

2024-06-03 Thread Cédric Le Goater

On 6/3/24 11:49, Jamin Lin wrote:

Hi Cedric,


From: Cédric Le Goater 
Subject: Re: [SPAM] Re: [PATCH v4 09/16] aspeed/smc: Add AST2700 support


@@ -670,7 +670,7 @@ static const MemoryRegionOps

aspeed_smc_flash_ops

= {
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid = {
    .min_access_size = 1,
-    .max_access_size = 4,
+    .max_access_size = 8,


Is this a bugfix? If so, please use a separate patch. Otherwise
please mention why it is OK to widen access for AST2600 & AST10x0.



According the design of SPI drivers, it uses this "memcpy_fromio" KERNEL API

for SPI calibration.



https://github.com/AspeedTech-BMC/linux/blob/1062a07420f9aed4ed7dc9deb

3429b8e7828f5cf/drivers/spi/spi-aspeed-smc.c#L1832
AST2700 is a 64 bits quad core cpus(Cortex-a35), so kernel API use 64 bits for

data access.

https://github.com/AspeedTech-BMC/linux/blob/aspeed-master-v6.6/arch/a
rm64/kernel/io.c#L25 I simply set the max_access_size to 8 for AST2700
support.
AST2500, AST2600 and AST10x0 are all 32bits CPUS, that was why this

max_access_size 8 did not impact these models.

https://github.com/AspeedTech-BMC/linux/blob/aspeed-master-v6.6/arch/a
rm/kernel/io.c#L45


Yes. I think we are safe on that side.


If you have any suggestion about this patch modification, please let me know.
I am going to re-send v5 patch for AST2700 support.


Please move this change in its own commit explaining the reason and add a
TODO comment in the code.

The aspeed_smc_flash_ops MemoryRegionOps should be copied in _realize()
to set a different width for the AST2700 SoC. You could do that too.

Thanks,

C.

I will do the following changes. Could you give me any suggestion?

1. add asc->max_access_size = 8 in aspeed_2700_fmc_class_init, 
aspeed_2700_spi0_class_init, aspeed_2700_spi1_class_init and 
aspeed_2700_spi2_class_init
2. Update aspeed_smc_flash_realize as below
static void aspeed_smc_flash_realize(DeviceState *dev, Error **errp)
{
--
s->asc = ASPEED_SMC_GET_CLASS(s->controller)
if (s->asc->max_access_size ==8) --> check max_access_size
   aspeed_smc_flash_ops.valid.max_access_size = s->asc->max_access --> 
update max_access_size


You can not because aspeed_smc_flash_ops is a static const shared
by all models

Best option is to introduce a new 'const MemoryRegionOps*' attribute
in AspeedSMCClass and use it in aspeed_smc_flash_realize().


Thanks,

C.





Re: [SPAM] Re: [PATCH v4 09/16] aspeed/smc: Add AST2700 support

2024-06-03 Thread Cédric Le Goater

@@ -670,7 +670,7 @@ static const MemoryRegionOps

aspeed_smc_flash_ops

= {
   .endianness = DEVICE_LITTLE_ENDIAN,
   .valid = {
   .min_access_size = 1,
-    .max_access_size = 4,
+    .max_access_size = 8,


Is this a bugfix? If so, please use a separate patch. Otherwise please
mention why it is OK to widen access for AST2600 & AST10x0.



According the design of SPI drivers, it uses this "memcpy_fromio" KERNEL API 
for SPI calibration.
https://github.com/AspeedTech-BMC/linux/blob/1062a07420f9aed4ed7dc9deb3429b8e7828f5cf/drivers/spi/spi-aspeed-smc.c#L1832
AST2700 is a 64 bits quad core cpus(Cortex-a35), so kernel API use 64 bits for 
data access.
https://github.com/AspeedTech-BMC/linux/blob/aspeed-master-v6.6/arch/arm64/kernel/io.c#L25
I simply set the max_access_size to 8 for AST2700 support.
AST2500, AST2600 and AST10x0 are all 32bits CPUS, that was why this 
max_access_size 8 did not impact these models.
https://github.com/AspeedTech-BMC/linux/blob/aspeed-master-v6.6/arch/arm/kernel/io.c#L45


Yes. I think we are safe on that side.


If you have any suggestion about this patch modification, please let me know.
I am going to re-send v5 patch for AST2700 support.


Please move this change in its own commit explaining the reason and
add a TODO comment in the code.
 
The aspeed_smc_flash_ops MemoryRegionOps should be copied in _realize()

to set a different width for the AST2700 SoC. You could do that too.

Thanks,

C.




Re: [PATCH v4 11/16] aspeed/intc: Add AST2700 support

2024-06-03 Thread Cédric Le Goater

+static void aspeed_2700_intc_class_init(ObjectClass *klass, void
+*data) {
+DeviceClass *dc = DEVICE_CLASS(klass);
+AspeedINTCClass *aic = ASPEED_INTC_CLASS(klass);
+
+dc->desc = "ASPEED 2700 INTC Controller";
+aic->num_lines = 32;
+aic->num_ints = 9;


Use ASPEED_INTC_NR_INTS ?


I am considering to support INTC model for future BMC SOCs.
For example, if the num_ints has been changed to "18" in the future BMC Socs, 
users only need to update ASPEED_INTC_NR_INTS and
Create a aspeed__intc_class_init to set its "aic->num_ints 18".
That was why I set aic->num_ints 9 in aspeed_2700_intc_class_init.


OK. This is minor.


Thanks,

C.






Re: [PATCH v4 12/16] aspeed/soc: Add AST2700 support

2024-05-31 Thread Cédric Le Goater



Hello Jamin,

I refer to versal_create_apu_gic function, 
https://github.com/qemu/qemu/blob/master/hw/arm/xlnx-versal.c#L67
and updated aspeed_soc_ast2700_gic as following.
If you have any concerned about the new changes, please let me know.
Thanks-Jamin

static bool aspeed_soc_ast2700_gic(DeviceState *dev, Error **errp)


Please rename to aspeed_soc_ast2700_gic_realize()


{
 Aspeed27x0SoCState *a = ASPEED27X0_SOC(dev);
 AspeedSoCState *s = ASPEED_SOC(dev);
 AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
 SysBusDevice *gicbusdev;
 DeviceState *gicdev;
 QList *redist_region_count;
 int i;

 object_initialize_child(OBJECT(a), "ast2700-gic", >gic,
 gicv3_class_name());


and object_initialize_child() can be called in aspeed_soc_ast2700_init().


 gicbusdev = SYS_BUS_DEVICE(>gic);
 gicdev = DEVICE(>gic);
 qdev_prop_set_uint32(gicdev, "revision", 3);
 qdev_prop_set_uint32(gicdev, "num-cpu", sc->num_cpus);
 qdev_prop_set_uint32(gicdev, "num-irq", AST2700_MAX_IRQ);

 redist_region_count = qlist_new();
 qlist_append_int(redist_region_count, sc->num_cpus);
 qdev_prop_set_array(gicdev, "redist-region-count", redist_region_count);

 if (!sysbus_realize(gicbusdev, errp)) {
 return false;
 }
 sysbus_mmio_map(gicbusdev, 0, sc->memmap[ASPEED_GIC_DIST]);
 sysbus_mmio_map(gicbusdev, 1, sc->memmap[ASPEED_GIC_REDIST]);

 for (i = 0; i < sc->num_cpus; i++) {
 DeviceState *cpudev = DEVICE(qemu_get_cpu(i));


Could we avoid qemu_get_cpu() and use the cpu array of the SoC instead ?


 int NUM_IRQS = 256, ARCH_GIC_MAINT_IRQ = 9, VIRTUAL_PMU_IRQ = 7;
 int ppibase = NUM_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS;

 const int timer_irq[] = {
 [GTIMER_PHYS] = 14,
 [GTIMER_VIRT] = 11,
 [GTIMER_HYP]  = 10,
 [GTIMER_SEC]  = 13,
 };
 int j;

 for (j = 0; j < ARRAY_SIZE(timer_irq); j++) {
 qdev_connect_gpio_out(cpudev, j,
 qdev_get_gpio_in(gicdev, ppibase + timer_irq[j]));
 }

 qemu_irq irq = qdev_get_gpio_in(gicdev,
 ppibase + ARCH_GIC_MAINT_IRQ);
 qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt",
 0, irq);
 qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
 qdev_get_gpio_in(gicdev, ppibase + VIRTUAL_PMU_IRQ));

 sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, 
ARM_CPU_IRQ));
 sysbus_connect_irq(gicbusdev, i + sc->num_cpus,
qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
 sysbus_connect_irq(gicbusdev, i + 2 * sc->num_cpus,
qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ));
 sysbus_connect_irq(gicbusdev, i + 3 * sc->num_cpus,
qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
 }

 return true;
}

struct Aspeed27x0SoCState {
 AspeedSoCState parent;

 ARMCPU cpu[ASPEED_CPUS_NUM];
 AspeedINTCState intc;
 GICv3State gic;
};

#define TYPE_ASPEED27X0_SOC "aspeed27x0-soc"
OBJECT_DECLARE_SIMPLE_TYPE(Aspeed27x0SoCState, ASPEED27X0_SOC)


Thanks,

C.






Re: [PATCH v4 14/16] aspeed/soc: fix incorrect dram size for AST2700

2024-05-30 Thread Cédric Le Goater

On 5/30/24 09:42, Jamin Lin wrote:

Hi Cedric,

From: Cédric Le Goater >
Hello Jamin

On 5/27/24 10:02, Jamin Lin wrote:

AST2700 dram size calculation is not back compatible AST2600.
According to the DDR capacity hardware behavior, if users write the
data to address which is beyond the ram size, it would write the data
to address 0.
For example:
a. sdram base address "0x4 "
b. sdram size is 1 GiB
The available address range is from "0x4 " to "0x4 4000".
If users write 0xdeadbeef to address "0x6 ", the value of DRAM
address 0 (base address 0x4 ) should be 0xdeadbeef.

Add aspeed_soc_ast2700_dram_init to calculate the dram size and add
memory I/O whose address range is from max_ram_size - ram_size to
max_ram_size and its read/write handler to emulate DDR capacity hardware

behavior.


Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
---
   hw/arm/aspeed_ast27x0.c | 94

-

   include/hw/arm/aspeed_soc.h |  1 +
   2 files changed, 94 insertions(+), 1 deletion(-)

diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c index
a3a03fc1ca..19380087fa 100644
--- a/hw/arm/aspeed_ast27x0.c
+++ b/hw/arm/aspeed_ast27x0.c
@@ -20,6 +20,7 @@
   #include "sysemu/sysemu.h"
   #include "hw/intc/arm_gicv3.h"
   #include "qapi/qmp/qlist.h"
+#include "qemu/log.h"

   static const hwaddr aspeed_soc_ast2700_memmap[] = {
   [ASPEED_DEV_SPI_BOOT]  =  0x4, @@ -191,6 +192,97

@@

static qemu_irq aspeed_soc_ast2700_get_irq(AspeedSoCState *s, int dev)
   return qdev_get_gpio_in(a->intc.gic, sc->irqmap[dev]);
   }

+static uint64_t aspeed_ram_capacity_read(void *opaque, hwaddr addr,
+unsigned

int

+size) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: read @%" PRIx64 " out of ram size\n",
+   __func__, addr);
+return 0;
+}
+
+static void aspeed_ram_capacity_write(void *opaque, hwaddr addr,

uint64_t data,

+unsigned int size)

{

+AspeedSoCState *s = ASPEED_SOC(opaque);
+uint32_t test_pattern = 0xdeadbeef;
+bool invalid_pattern = true;
+uint32_t *ram_ptr;
+int sz;
+
+ram_ptr = memory_region_get_ram_ptr(s->dram_mr);
+
+   /*
+* Emulate ddr capacity hardware behavior.
+* If writes the test_pattern to address which is beyond the ram size,
+* it would write the test_pattern to address 0.
+*/
+for (sz = 4; sz > 0 ; sz--) {
+test_pattern = (test_pattern << 4) + sz;
+if (data == test_pattern) {
+ram_ptr[0] = test_pattern;
+invalid_pattern = false;
+break;
+}
+}
+
+if (invalid_pattern) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: write invalid pattern @%" PRIx64
+  " to addr @%" HWADDR_PRIx "]\n",
+  __func__, data, addr);
+}
+}



I would simplify with write transaction on the DRAM memory region of the
SoC.

For that, initialize a 'dram_as' on top of 'dram_mr' in
aspeed_soc_ast2700_dram_init():

 address_space_init(>dram_as, s->dram_mr, "dram");

Then, in aspeed_ram_capacity_write(), add :

address_space_write(>dram_as, addr % ram_size,
MEMTXATTRS_UNSPECIFIED,
   , size);

and check returned error.

It should be enough to detect the RAM size from FW.


Thanks,

C.


Thanks for your suggestion and review.
I changed to use address space APIs to write DRAM memory region(s->dram_mr).
I have a question about aspeed_ram_capacity_write function implementation.
Could you tell me which solution you prefer? Do you want to use solution 1?


I prefer solution 1 because no assumption is made on what software does.
It simply implements the wraparound HW does on RAM accesses.

Thanks,

C.




Thanks-Jamin

Solution 1:
static void aspeed_ram_capacity_write(void *opaque, hwaddr addr, uint64_t data,
 unsigned int size)
{
 AspeedSoCState *s = ASPEED_SOC(opaque);
 ram_addr_t ram_size;
 MemTxResult result;

 ram_size = object_property_get_uint(OBJECT(>sdmc), "ram-size",
 _abort);

 /*
  * Emulate ddr capacity hardware behavior.
  * If writes the data to the address which is beyond the ram size,
  * it would write the data to the "address % ram_size".
  */
 result = address_space_write(>dram_as, addr % ram_size,
  MEMTXATTRS_UNSPECIFIED, , 4);
 if (result != MEMTX_OK) {
 qemu_log_mask(LOG_GUEST_ERROR,
   "%s: DRAM write failed, addr:0x%" HWADDR_PRIx
   ", data :0x%" PRIx64  "\n&quo

Re: [RFC PATCH 08/10] ppc/pnv: Invert the design for big-core machine modelling

2024-05-30 Thread Cédric Le Goater




@@ -157,6 +157,14 @@ static int pnv_dt_core(PnvChip *chip, PnvCore *pc, void 
*fdt)
   
   pnv_cc->processor_id(chip, pc->hwid, 0, , );
   
+/* Only one DT node per (big) core */

+if (tir != 0) {
+g_assert(pc->big_core);
+g_assert(tir == 1);
+g_assert(pc->hwid & 1);
+return -1;


return is -1 but it's not an error. right ?


Not an error just a "no CPU node to insert".

It's a bit ugly. Could return bool for yes/no and take a *offset
maybe?


or we could pass the pa_features array  ?



+if (machine->smp.threads > 8) {
+error_report("Cannot support more than 8 threads/core "
+ "on a powernv9/10  machine");
+exit(1);
+}
+if (machine->smp.threads % 2 == 1) {


is_power_of_2()


It does have that check later in pnv_init(), but I wanted
to be careful that we're dividing by 2 below I think it makes
it more obvious (and big-core can't have 1 thread per big core).


ok





@@ -1099,6 +1157,8 @@ static void pnv_power9_init(MachineState *machine)
   
   static void pnv_power10_init(MachineState *machine)

   {
+PnvMachineState *pnv = PNV_MACHINE(machine);
+pnv->big_core_tbst_quirk = true;
   pnv_power9_init(machine);
   }
   
@@ -1169,9 +1229,15 @@ static void pnv_processor_id_p9(PnvChip *chip,

   uint32_t core_id, uint32_t thread_id,
   uint32_t *pir, uint32_t *tir)
   {
-if (chip->nr_threads == 8) {
-*pir = (chip->chip_id << 8) | ((thread_id & 1) << 2) | (core_id << 3) |
-   (thread_id >> 1);
+PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine());


arg. We should avoid these qdev_get_machine() calls. Could big_core be a
chip property instead ?


We could, but per machine probably makes more sense. It's
funny there seems to be no good way to get machine from CPU.
Maybe we can just add a machine pointer in PnvChip?



It would be easier/cleaner to propagate the machine settings to
the chip unit and subunits. If I remember correctly, real HW has a
scan init sequence doing something similar.


I'l probably leave that for another series and try to convert
most things.


+static bool pnv_machine_get_hb(Object *obj, Error **errp)
+{
+PnvMachineState *pnv = PNV_MACHINE(obj);
+
+return !!pnv->fw_load_addr;
+}
+
+static void pnv_machine_set_hb(Object *obj, bool value, Error **errp)
+{
+PnvMachineState *pnv = PNV_MACHINE(obj);
+
+if (value) {
+pnv->fw_load_addr = 0x800;
+}
+}


we might want to get rid of the hostboot mode oneday. This was really
experimental stuff.


Okay sure, I don't use it. Although we may want to run the
open source hostboot part of the firmware on QEMU one day,
we can always add back some options for it.


It's not invasive either. Let's keep it. It use to work with a
trimdown Linux image.


Thanks,

C.




We do have a PowerVM mode too which tweaks a few things, but
that's no use for upstream.


diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index 059d372c8a..05195527a5 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c


This change should come in another patch preferably


Yeah this might have got into the wrong patch.

Thanks,
Nick





Re: [PATCH v4 02/11] ppc/pseries: Add Power11 cpu type

2024-05-30 Thread Cédric Le Goater

On 5/30/24 09:06, Harsh Prateek Bora wrote:



On 5/28/24 12:35, Aditya Gupta wrote:

Add sPAPR CPU Core definition for Power11

Cc: David Gibson  (reviewer:sPAPR (pseries))
Cc: Harsh Prateek Bora  (reviewer:sPAPR (pseries))
Cc: Cédric Le Goater 
Cc: Daniel Henrique Barboza 
Cc: Frédéric Barrat 
Cc: Mahesh J Salgaonkar 
Cc: Madhavan Srinivasan 
Cc: Nicholas Piggin 
Signed-off-by: Aditya Gupta 
---
  docs/system/ppc/pseries.rst | 6 +++---
  hw/ppc/spapr_cpu_core.c | 1 +
  2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/docs/system/ppc/pseries.rst b/docs/system/ppc/pseries.rst
index a876d897b6e4..3277564b34c2 100644
--- a/docs/system/ppc/pseries.rst
+++ b/docs/system/ppc/pseries.rst
@@ -15,9 +15,9 @@ Supported devices
  =
   * Multi processor support for many Power processors generations: POWER7,
-   POWER7+, POWER8, POWER8NVL, POWER9, and Power10. Support for POWER5+ exists,
-   but its state is unknown.
- * Interrupt Controller, XICS (POWER8) and XIVE (POWER9 and Power10)
+   POWER7+, POWER8, POWER8NVL, POWER9, Power10 and Power11. Support for POWER5+
+   exists, but its state is unknown.
+ * Interrupt Controller, XICS (POWER8) and XIVE (POWER9, Power10, Power11)


I think it would look more cleaner to rephrase as below:

  * Multi processor support for many Power processors generations:
    - POWER7, POWER7+
    - POWER8, POWER8NVL
    - POWER9
    - Power10
    - Power11.
    - Support for POWER5+ exists, but its state is unknown.



$ /usr/bin/qemu-system-ppc64 -version
QEMU emulator version 8.1.3 (qemu-8.1.3-5.fc39)
Copyright (c) 2003-2023 Fabrice Bellard and the QEMU Project developers

With the correct kernel/userspace, it runs :

# uname -a
Linux buildroot 6.6.3 #1 SMP Fri Jan  5 00:00:45 CET 2024 ppc64 GNU/Linux
# cat /proc/cpuinfo
processor   : 0
cpu : POWER5+ (gs)
clock   : 1000.00MHz
revision: 2.1 (pvr 003b 0201)

timebase: 51200
platform: pSeries
model   : IBM pSeries (emulated by qemu)
machine : CHRP IBM pSeries (emulated by qemu)
MMU : Hash


Thanks,

C.





  * Interrupt Controller
     - XICS (POWER8)
     - XIVE (Supported by below:)
     - POWER9
     - Power10
     - Power11

So, that every next platform just need to add one line for itself.

With that,
Reviewed-by: Harsh Prateek Bora 

Thanks
Harsh

   * vPHB PCIe Host bridge.
   * vscsi and vnet devices, compatible with the same devices available on a
 PowerVM hypervisor with VIOS managing LPARs.
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index e7c9edd033c8..62416b7e0a7e 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -401,6 +401,7 @@ static const TypeInfo spapr_cpu_core_type_infos[] = {
  DEFINE_SPAPR_CPU_CORE_TYPE("power9_v2.0"),
  DEFINE_SPAPR_CPU_CORE_TYPE("power9_v2.2"),
  DEFINE_SPAPR_CPU_CORE_TYPE("power10_v2.0"),
+    DEFINE_SPAPR_CPU_CORE_TYPE("power11_v2.0"),
  #ifdef CONFIG_KVM
  DEFINE_SPAPR_CPU_CORE_TYPE("host"),
  #endif





Re: [PATCH v4 11/11] ppc/pnv: Update skiboot.lid to support Power11

2024-05-30 Thread Cédric Le Goater

On 5/30/24 08:41, Aditya Gupta wrote:

Hello Cedric,

On Tue, May 28, 2024 at 09:15:29AM GMT, Cédric Le Goater wrote:

On 5/28/24 09:05, Aditya Gupta wrote:

Skiboot/OPAL patches are in discussion upstream [1], with corresponding
commits in github repository [2].

Update skiboot.lid, with binary built from 'upstream_power11' branch
of skiboot repository with Power11 enablement patches [2].

---
This patch can be skipped for now, if need to wait for patches to be
merged in open-power/skiboot. Have updated the skiboot.lid to aid in
testing this patch series.


When is the merge in skiboot planned ? QEMU 9.1 freeze is in ~2 months.


I have asked, will let you know when I get the expected time.


The typical flow would to be merge a new skiboot.lid with Power11 first,
than this series.


Thanks,

C.


 




[1]:https://lists.ozlabs.org/pipermail/skiboot/2024-April/018963.html
[2]:https://github.com/maheshsal/skiboot.

Cc: Cédric Le Goater
Cc: Joel Stanley
Cc: Mahesh J Salgaonkar
Cc: Madhavan Srinivasan
Cc: Nicholas Piggin
Signed-off-by: Aditya Gupta
---
   pc-bios/skiboot.lid | Bin 2527328 -> 2527328 bytes


Please don't resend. This is big !


Oh okay. Sure.

Thanks,
Aditya Gupta



Thanks,

C.









Re: [RFC PATCH 05/10] ppc/pnv: Extend chip_pir class method to TIR as well

2024-05-30 Thread Cédric Le Goater

On 5/30/24 08:38, Nicholas Piggin wrote:

On Wed May 29, 2024 at 4:30 PM AEST, Cédric Le Goater wrote:

On 5/29/24 02:24, Nicholas Piggin wrote:

On Tue May 28, 2024 at 6:32 PM AEST, Harsh Prateek Bora wrote:



On 5/26/24 17:56, Nicholas Piggin wrote:

The chip_pir chip class method allows the platform to set the PIR
processor identification register. Extend this to a more general
ID function which also allows the TIR to be set. This is in
preparation for "big core", which is a more complicated topology
of cores and threads.

Signed-off-by: Nicholas Piggin 
---
include/hw/ppc/pnv_chip.h |  3 +-
hw/ppc/pnv.c  | 61 ---
hw/ppc/pnv_core.c | 10 ---
3 files changed, 45 insertions(+), 29 deletions(-)

diff --git a/include/hw/ppc/pnv_chip.h b/include/hw/ppc/pnv_chip.h
index 8589f3291e..679723926a 100644
--- a/include/hw/ppc/pnv_chip.h
+++ b/include/hw/ppc/pnv_chip.h
@@ -147,7 +147,8 @@ struct PnvChipClass {

DeviceRealize parent_realize;

-uint32_t (*chip_pir)(PnvChip *chip, uint32_t core_id, uint32_t thread_id);

+void (*processor_id)(PnvChip *chip, uint32_t core_id, uint32_t thread_id,
+ uint32_t *pir, uint32_t *tir);


Should it be named get_chip_core_thread_regs() ?


Yeah, the name isn't great. It is getting the regs, but the regs are the
"pervasive id" used as well... but maybe that's not too relevant here.
What about we drop chip_ since we have the chip and no other methods use
such prefix, then call it get_thread_pir_tir()?


processor relates to chip and so, processor_id() is not great indeed.
get_pir_tir() would be enough I think.

What would be good though, since pnv is growing, is to start adding
documentation to these common helpers.


Okay we'll use that name.

You mean just a comment them in the header? Might as well do that for
new ones at least.


Yes. All class handlers should have a minimal description.

Thanks,

C.




Re: [PATCH v7 1/9] vfio: Add Error** argument to .set_dirty_page_tracking() handler

2024-05-29 Thread Cédric Le Goater

On 5/29/24 08:26, Markus Armbruster wrote:

I had a look at this before I realized it's already in.  I'm sending
this out not to demand any change, but only to point out an issue to be
avoided in future work.

Cédric Le Goater  writes:


We will use the Error object to improve error reporting in the
.log_global*() handlers of VFIO. Add documentation while at it.

Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Avihai Horon 
Reviewed-by: Eric Auger 
Signed-off-by: Cédric Le Goater 
---
  include/hw/vfio/vfio-container-base.h | 18 --
  hw/vfio/common.c  |  4 ++--
  hw/vfio/container-base.c  |  4 ++--
  hw/vfio/container.c   |  6 +++---
  4 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/include/hw/vfio/vfio-container-base.h 
b/include/hw/vfio/vfio-container-base.h
index 
3582d5f97a37877b2adfc0d0b06996c82403f8b7..326ceea52a2030eec9dad289a9845866c4a8c090
 100644
--- a/include/hw/vfio/vfio-container-base.h
+++ b/include/hw/vfio/vfio-container-base.h
@@ -82,7 +82,7 @@ int vfio_container_add_section_window(VFIOContainerBase 
*bcontainer,
  void vfio_container_del_section_window(VFIOContainerBase *bcontainer,
 MemoryRegionSection *section);
  int vfio_container_set_dirty_page_tracking(VFIOContainerBase *bcontainer,
-   bool start);
+   bool start, Error **errp);
  int vfio_container_query_dirty_bitmap(const VFIOContainerBase *bcontainer,
VFIOBitmap *vbmap,
hwaddr iova, hwaddr size);
@@ -121,9 +121,23 @@ struct VFIOIOMMUClass {
  int (*attach_device)(const char *name, VFIODevice *vbasedev,
   AddressSpace *as, Error **errp);
  void (*detach_device)(VFIODevice *vbasedev);
+
  /* migration feature */
+
+/**
+ * @set_dirty_page_tracking
+ *
+ * Start or stop dirty pages tracking on VFIO container
+ *
+ * @bcontainer: #VFIOContainerBase on which to de/activate dirty
+ *  page tracking
+ * @start: indicates whether to start or stop dirty pages tracking
+ * @errp: pointer to Error*, to store an error if it happens.
+ *
+ * Returns zero to indicate success and negative for error
+ */
  int (*set_dirty_page_tracking)(const VFIOContainerBase *bcontainer,
-   bool start);
+   bool start, Error **errp);


Note for later: this is always called via
vfio_container_set_dirty_page_tracking().


  int (*query_dirty_bitmap)(const VFIOContainerBase *bcontainer,
VFIOBitmap *vbmap,
hwaddr iova, hwaddr size);
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 
8f9cbdc0264044ce587877a7d19d14b28527291b..485e53916491f1164d29e739fb7106c0c77df737
 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -1076,7 +1076,7 @@ static bool vfio_listener_log_global_start(MemoryListener 
*listener,
  if (vfio_devices_all_device_dirty_tracking(bcontainer)) {
  ret = vfio_devices_dma_logging_start(bcontainer);
  } else {
-ret = vfio_container_set_dirty_page_tracking(bcontainer, true);
+ret = vfio_container_set_dirty_page_tracking(bcontainer, true, NULL);
  }
  
  if (ret) {

@@ -1096,7 +1096,7 @@ static void vfio_listener_log_global_stop(MemoryListener 
*listener)
  if (vfio_devices_all_device_dirty_tracking(bcontainer)) {
  vfio_devices_dma_logging_stop(bcontainer);
  } else {
-ret = vfio_container_set_dirty_page_tracking(bcontainer, false);
+ret = vfio_container_set_dirty_page_tracking(bcontainer, false, NULL);
  }
  
  if (ret) {


Note for later: all callers pass NULL to ignore the new Error.


diff --git a/hw/vfio/container-base.c b/hw/vfio/container-base.c
index 
913ae49077c4f09b7b27517c1231cfbe4befb7fb..7c0764121d24b02b6c4e66e368d7dff78a6d65aa
 100644
--- a/hw/vfio/container-base.c
+++ b/hw/vfio/container-base.c
@@ -53,14 +53,14 @@ void vfio_container_del_section_window(VFIOContainerBase 
*bcontainer,
  }
  
  int vfio_container_set_dirty_page_tracking(VFIOContainerBase *bcontainer,

-   bool start)
+   bool start, Error **errp)
  {
  if (!bcontainer->dirty_pages_supported) {
  return 0;
  }
  
  g_assert(bcontainer->ops->set_dirty_page_tracking);

-return bcontainer->ops->set_dirty_page_tracking(bcontainer, start);
+return bcontainer->ops->set_dirty_page_tracking(bcontainer, start, errp);
  }
  
  int vfio_container_query_dirty_bitmap(const VFIOContainerBase *bcontainer,

diff --git a/hw/vfio/container.c b/hw/vfio/container.c
index 
77bdec276ec49cb9cd767c0de42ec801b4421572..c35221fbe7dc5453050f97cd186fc958e24f28f7
 100644
--- 

Re: [PATCH v4 14/16] aspeed/soc: fix incorrect dram size for AST2700

2024-05-29 Thread Cédric Le Goater

Hello Jamin

On 5/27/24 10:02, Jamin Lin wrote:

AST2700 dram size calculation is not back compatible AST2600.
According to the DDR capacity hardware behavior,
if users write the data to address which is beyond the ram size,
it would write the data to address 0.
For example:
a. sdram base address "0x4 "
b. sdram size is 1 GiB
The available address range is from "0x4 " to "0x4 4000".
If users write 0xdeadbeef to address "0x6 ",
the value of DRAM address 0 (base address 0x4 ) should be 0xdeadbeef.

Add aspeed_soc_ast2700_dram_init to calculate the dram size and add
memory I/O whose address range is from max_ram_size - ram_size to max_ram_size
and its read/write handler to emulate DDR capacity hardware behavior.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
---
  hw/arm/aspeed_ast27x0.c | 94 -
  include/hw/arm/aspeed_soc.h |  1 +
  2 files changed, 94 insertions(+), 1 deletion(-)

diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c
index a3a03fc1ca..19380087fa 100644
--- a/hw/arm/aspeed_ast27x0.c
+++ b/hw/arm/aspeed_ast27x0.c
@@ -20,6 +20,7 @@
  #include "sysemu/sysemu.h"
  #include "hw/intc/arm_gicv3.h"
  #include "qapi/qmp/qlist.h"
+#include "qemu/log.h"
  
  static const hwaddr aspeed_soc_ast2700_memmap[] = {

  [ASPEED_DEV_SPI_BOOT]  =  0x4,
@@ -191,6 +192,97 @@ static qemu_irq aspeed_soc_ast2700_get_irq(AspeedSoCState 
*s, int dev)
  return qdev_get_gpio_in(a->intc.gic, sc->irqmap[dev]);
  }
  
+static uint64_t aspeed_ram_capacity_read(void *opaque, hwaddr addr,

+unsigned int size)
+{
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: read @%" PRIx64 " out of ram size\n",
+   __func__, addr);
+return 0;
+}
+
+static void aspeed_ram_capacity_write(void *opaque, hwaddr addr, uint64_t data,
+unsigned int size)
+{
+AspeedSoCState *s = ASPEED_SOC(opaque);
+uint32_t test_pattern = 0xdeadbeef;
+bool invalid_pattern = true;
+uint32_t *ram_ptr;
+int sz;
+
+ram_ptr = memory_region_get_ram_ptr(s->dram_mr);
+
+   /*
+* Emulate ddr capacity hardware behavior.
+* If writes the test_pattern to address which is beyond the ram size,
+* it would write the test_pattern to address 0.
+*/
+for (sz = 4; sz > 0 ; sz--) {
+test_pattern = (test_pattern << 4) + sz;
+if (data == test_pattern) {
+ram_ptr[0] = test_pattern;
+invalid_pattern = false;
+break;
+}
+}
+
+if (invalid_pattern) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: write invalid pattern @%" PRIx64
+  " to addr @%" HWADDR_PRIx "]\n",
+  __func__, data, addr);
+}
+}



I would simplify with write transaction on the DRAM memory region
of the SoC.

For that, initialize a 'dram_as' on top of 'dram_mr' in
aspeed_soc_ast2700_dram_init():

   address_space_init(>dram_as, s->dram_mr, "dram");

Then, in aspeed_ram_capacity_write(), add :

  address_space_write(>dram_as, addr % ram_size, MEMTXATTRS_UNSPECIFIED,
 , size);

and check returned error.

It should be enough to detect the RAM size from FW.


Thanks,

C.






+static const MemoryRegionOps aspeed_ram_capacity_ops = {
+.read = aspeed_ram_capacity_read,
+.write = aspeed_ram_capacity_write,
+.endianness = DEVICE_LITTLE_ENDIAN,
+.valid = {
+.min_access_size = 1,
+.max_access_size = 8,
+},
+};
+
+/*
+ * SDMC should be realized first to get correct RAM size and max size
+ * values
+ */
+static bool aspeed_soc_ast2700_dram_init(DeviceState *dev, Error **errp)
+{
+ram_addr_t ram_size, max_ram_size;
+Aspeed27x0SoCState *a = ASPEED27X0_SOC(dev);
+AspeedSoCState *s = ASPEED_SOC(dev);
+AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
+
+ram_size = object_property_get_uint(OBJECT(>sdmc), "ram-size",
+_abort);
+max_ram_size = object_property_get_uint(OBJECT(>sdmc), "max-ram-size",
+_abort);
+
+memory_region_init(>dram_container, OBJECT(s), "ram-container",
+   ram_size);
+memory_region_add_subregion(>dram_container, 0, s->dram_mr);
+
+/*
+ * Add a memory region beyond the RAM region to emulate
+ * ddr capacity hardware behavior.
+ */
+if (ram_size < max_ram_size) {
+memory_region_init_io(>dram_empty, OBJECT(s),
+  _ram_capacity_ops, s,
+  "ram-empty", max_ram_size - ram_size);
+
+memory_region_add_subregion(s->memory,
+sc->memmap[ASPEED_DEV_SDRAM] + ram_size,
+>dram_empty);
+}
+
+memory_region_add_subregion(s->memory,
+  

Re: [RFC PATCH 10/10] ppc/pnv: Add an LPAR per core machine option

2024-05-29 Thread Cédric Le Goater

On 5/26/24 14:26, Nicholas Piggin wrote:

Recent POWER CPUs can operate in "LPAR per core" or "LPAR per thread"
modes. In per-core mode, some SPRs and IPI doorbells are shared between
threads in a core. In per-thread mode, supervisor and user state is
not shared between threads.

OpenPOWER systems use LPAR per thread mode as it is required for KVM.
Enterprise systems use LPAR per core mode, as they partition the
machine by core.

Implement a lpar-per-core machine option for powernv machines. This
is supported on POWER9 and POWER10.

Signed-off-by: Nicholas Piggin 


LGTM,


Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  include/hw/ppc/pnv.h  |  1 +
  include/hw/ppc/pnv_core.h |  1 +
  hw/ppc/pnv.c  | 29 +
  hw/ppc/pnv_core.c |  8 
  target/ppc/cpu_init.c |  3 ++-
  5 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index bec603f1a8..8f75c715d8 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -103,6 +103,7 @@ struct PnvMachineState {
  
  bool big_core;

  bool big_core_tbst_quirk;
+bool lpar_per_core;
  };
  
  PnvChip *pnv_get_chip(PnvMachineState *pnv, uint32_t chip_id);

diff --git a/include/hw/ppc/pnv_core.h b/include/hw/ppc/pnv_core.h
index 9599da15ea..e41b6347ea 100644
--- a/include/hw/ppc/pnv_core.h
+++ b/include/hw/ppc/pnv_core.h
@@ -57,6 +57,7 @@ struct PnvCore {
  /*< public >*/
  PowerPCCPU **threads;
  bool big_core;
+bool lpar_per_core;
  uint32_t pir;
  uint32_t hwid;
  uint64_t hrmor;
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 765142965f..0d830ad731 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1108,12 +1108,17 @@ static void pnv_init(MachineState *machine)
  
  static void pnv_power8_init(MachineState *machine)

  {
+PnvMachineState *pnv = PNV_MACHINE(machine);
+
  if (machine->smp.threads > 8) {
  error_report("Cannot support more than 8 threads/core "
   "on a powernv POWER8 machine");
  exit(1);
  }
  
+/* POWER8 is always lpar-per-core. */

+pnv->lpar_per_core = true;
+
  pnv_init(machine);
  }
  
@@ -2541,6 +2546,18 @@ static void pnv_machine_set_big_core(Object *obj, bool value, Error **errp)

  pnv->big_core = value;
  }
  
+static bool pnv_machine_get_1lpar(Object *obj, Error **errp)

+{
+PnvMachineState *pnv = PNV_MACHINE(obj);
+return pnv->lpar_per_core;
+}
+
+static void pnv_machine_set_1lpar(Object *obj, bool value, Error **errp)
+{
+PnvMachineState *pnv = PNV_MACHINE(obj);
+pnv->lpar_per_core = value;
+}
+
  static bool pnv_machine_get_hb(Object *obj, Error **errp)
  {
  PnvMachineState *pnv = PNV_MACHINE(obj);
@@ -2614,6 +2631,12 @@ static void pnv_machine_power9_class_init(ObjectClass 
*oc, void *data)
 pnv_machine_set_big_core);
  object_class_property_set_description(oc, "big-core",
"Use big-core (aka fused-core) mode");
+
+object_class_property_add_bool(oc, "lpar-per-core",
+   pnv_machine_get_1lpar,
+   pnv_machine_set_1lpar);
+object_class_property_set_description(oc, "lpar-per-core",
+  "Use 1 LPAR per core mode");
  }
  
  static void pnv_machine_p10_common_class_init(ObjectClass *oc, void *data)

@@ -2660,6 +2683,12 @@ static void pnv_machine_power10_class_init(ObjectClass 
*oc, void *data)
 pnv_machine_set_big_core);
  object_class_property_set_description(oc, "big-core",
"Use big-core (aka fused-core) mode");
+
+object_class_property_add_bool(oc, "lpar-per-core",
+   pnv_machine_get_1lpar,
+   pnv_machine_set_1lpar);
+object_class_property_set_description(oc, "lpar-per-core",
+  "Use 1 LPAR per core mode");
  }
  
  static void pnv_machine_p10_rainier_class_init(ObjectClass *oc, void *data)

diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c
index 835c35d90b..e510909db1 100644
--- a/hw/ppc/pnv_core.c
+++ b/hw/ppc/pnv_core.c
@@ -207,6 +207,9 @@ static uint64_t pnv_core_power10_xscom_read(void *opaque, 
hwaddr addr,
  val |= PPC_BIT(56 + i);
  }
  }
+if (pc->lpar_per_core) {
+val |= PPC_BIT(62);
+}
  break;
  case PNV10_XSCOM_EC_CORE_THREAD_INFO:
  break;
@@ -322,6 +325,11 @@ static void pnv_core_cpu_realize(PnvCore *pc, PowerPCCPU 
*cpu, Error **errp,
  env->core_index = core_hwid;
  }
  
+if (pnv->lpar_per_core) {

+pc->lpar_per_core = true;
+cp

Re: [RFC PATCH 09/10] ppc/pnv: Implement POWER10 PC xscom registers for direct controls

2024-05-29 Thread Cédric Le Goater

On 5/26/24 14:26, Nicholas Piggin wrote:

The PC unit in the processor core contains xscom registers that provide
low level status and control of the CPU.

This implements "direct controls" sufficient for OPAL (skiboot) firmware
use, which is to stop threads and send them non-maskable IPIs in the
form of SRESET interrupts.

POWER10 is sufficiently different (particularly QME and special wakeup)
from POWER9 that it is not trivial to implement by reusing the code.

Signed-off-by: Nicholas Piggin 
---
  include/hw/core/cpu.h |  8 
  include/hw/ppc/pnv.h  |  2 +
  include/hw/ppc/pnv_core.h |  3 ++
  hw/ppc/pnv.c  |  7 +++-
  hw/ppc/pnv_core.c | 88 ---
  system/cpus.c | 10 +
  6 files changed, 112 insertions(+), 6 deletions(-)

diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index bb398e8237..52a8fc65cb 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -974,6 +974,14 @@ void cpu_reset_interrupt(CPUState *cpu, int mask);
   */
  void cpu_exit(CPUState *cpu);
  
+/**

+ * cpu_pause:
+ * @cpu: The CPU to pause.
+ *
+ * Resumes CPU, i.e. puts CPU into stopped state.
+ */
+void cpu_pause(CPUState *cpu);
+
  /**
   * cpu_resume:
   * @cpu: The CPU to resume.
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 93ecb062b4..bec603f1a8 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -111,6 +111,8 @@ PnvChip *pnv_chip_add_phb(PnvChip *chip, PnvPHB *phb);
  #define PNV_FDT_ADDR  0x0100
  #define PNV_TIMEBASE_FREQ 51200ULL
  
+void pnv_cpu_do_nmi(CPUState *cs);

+
  /*
   * BMC helpers
   */
diff --git a/include/hw/ppc/pnv_core.h b/include/hw/ppc/pnv_core.h
index 39f8f33e6c..9599da15ea 100644
--- a/include/hw/ppc/pnv_core.h
+++ b/include/hw/ppc/pnv_core.h
@@ -109,6 +109,9 @@ OBJECT_DECLARE_TYPE(PnvQuad, PnvQuadClass, PNV_QUAD)
  struct PnvQuad {
  DeviceState parent_obj;
  
+bool special_wakeup_done;

+bool special_wakeup[4];
+
  uint32_t quad_id;
  MemoryRegion xscom_regs;
  MemoryRegion xscom_qme_regs;
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 5364c55bbb..765142965f 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -2700,12 +2700,17 @@ static void pnv_cpu_do_nmi_on_cpu(CPUState *cs, 
run_on_cpu_data arg)
  }
  }
  
+void pnv_cpu_do_nmi(CPUState *cs)

+{
+async_run_on_cpu(cs, pnv_cpu_do_nmi_on_cpu, RUN_ON_CPU_NULL);
+}
+
  static void pnv_nmi(NMIState *n, int cpu_index, Error **errp)
  {
  CPUState *cs;
  
  CPU_FOREACH(cs) {

-async_run_on_cpu(cs, pnv_cpu_do_nmi_on_cpu, RUN_ON_CPU_NULL);
+pnv_cpu_do_nmi(cs);
  }
  }


What about ?

https://lore.kernel.org/qemu-devel/20240424093048.180966-1-...@redhat.com/


Thanks,

C.




diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c
index 10417d92ae..835c35d90b 100644
--- a/hw/ppc/pnv_core.c
+++ b/hw/ppc/pnv_core.c
@@ -184,16 +184,40 @@ static const MemoryRegionOps pnv_core_power9_xscom_ops = {
   */
  
  #define PNV10_XSCOM_EC_CORE_THREAD_STATE0x412

+#define PNV10_XSCOM_EC_CORE_THREAD_INFO 0x413
+#define PNV10_XSCOM_EC_CORE_DIRECT_CONTROLS 0x449
+#define PNV10_XSCOM_EC_CORE_RAS_STATUS  0x454
  
  static uint64_t pnv_core_power10_xscom_read(void *opaque, hwaddr addr,

 unsigned int width)
  {
+PnvCore *pc = PNV_CORE(opaque);
+int nr_threads = CPU_CORE(pc)->nr_threads;
+int i;
  uint32_t offset = addr >> 3;
  uint64_t val = 0;
  
  switch (offset) {

  case PNV10_XSCOM_EC_CORE_THREAD_STATE:
-val = 0;
+for (i = 0; i < nr_threads; i++) {
+PowerPCCPU *cpu = pc->threads[i];
+CPUState *cs = CPU(cpu);
+
+if (cs->halted) {
+val |= PPC_BIT(56 + i);
+}
+}
+break;
+case PNV10_XSCOM_EC_CORE_THREAD_INFO:
+break;
+case PNV10_XSCOM_EC_CORE_RAS_STATUS:
+for (i = 0; i < nr_threads; i++) {
+PowerPCCPU *cpu = pc->threads[i];
+CPUState *cs = CPU(cpu);
+if (cs->stopped) {
+val |= PPC_BIT(0 + 8*i) | PPC_BIT(1 + 8*i);
+}
+}
  break;
  default:
  qemu_log_mask(LOG_UNIMP, "%s: unimp read 0x%08x\n", __func__,
@@ -206,9 +230,45 @@ static uint64_t pnv_core_power10_xscom_read(void *opaque, 
hwaddr addr,
  static void pnv_core_power10_xscom_write(void *opaque, hwaddr addr,
   uint64_t val, unsigned int width)
  {
+PnvCore *pc = PNV_CORE(opaque);
+int nr_threads = CPU_CORE(pc)->nr_threads;
+int i;
  uint32_t offset = addr >> 3;
  
  switch (offset) {

+case PNV10_XSCOM_EC_CORE_DIRECT_CONTROLS:
+for (i = 0; i < nr_threads; i++) {
+PowerPCCPU *cpu = pc->threads[i];
+CPUState *cs = CPU(cpu);
+
+if (val & PPC_BIT(7 + 8*i)) { /* stop */
+val &= ~PPC_BIT(7 + 8*i);
+

Re: [RFC PATCH 08/10] ppc/pnv: Invert the design for big-core machine modelling

2024-05-29 Thread Cédric Le Goater

On 5/26/24 14:26, Nicholas Piggin wrote:

POWER9 and POWER10 machines come in two variants, "big-core" and
"small-core".

Big core machines are SMT8 from the software point of view, but in the
low level platform topology ("xscom registers and pervasive
addressing"), these look more like a pair of small cores ganged
together.

Presently, the way this is modelled is to create an SMT8 PnvCore and
add special cases to xscom and pervasive for big-core mode. This is
becoming too complicated to manage as more of the machine is modelled.
The better approach looks like the inverse, which is creating 2xPnvCore
ganging them together to look like an SMT8 core in TCG. The TCG SMT code
is quite simple to do that, and then the xscom and pervasive modelling
does not need to differentiate big and small core modes for the most
part.

device-tree building does need a special case to only build one
CPU node for each big-core because that's what the firmware expects.
And so does a special case workaround in the ChipTOD model.

A big-core machine option is added for powernv9 and 10 machines.


That's another patch.

It is difficult to follow all the changes. I think this patch
needs further splitting.


Signed-off-by: Nicholas Piggin 
---
  include/hw/ppc/pnv.h |   3 +
  include/hw/ppc/pnv_core.h|   8 ++
  target/ppc/cpu.h |   4 +-
  hw/ppc/pnv.c | 183 ---
  hw/ppc/pnv_core.c|  20 +++-
  hw/ppc/spapr_cpu_core.c  |   6 +-
  target/ppc/misc_helper.c |   6 +-
  target/ppc/timebase_helper.c |   9 ++
  8 files changed, 197 insertions(+), 42 deletions(-)

diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 476b136146..93ecb062b4 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -100,6 +100,9 @@ struct PnvMachineState {
  PnvPnor  *pnor;
  
  hwaddr   fw_load_addr;

+
+bool big_core;
+bool big_core_tbst_quirk;


I think the quirk should be introduced in its own patch.


  };
  
  PnvChip *pnv_get_chip(PnvMachineState *pnv, uint32_t chip_id);

diff --git a/include/hw/ppc/pnv_core.h b/include/hw/ppc/pnv_core.h
index 21297262c1..39f8f33e6c 100644
--- a/include/hw/ppc/pnv_core.h
+++ b/include/hw/ppc/pnv_core.h
@@ -27,6 +27,13 @@
  
  /* ChipTOD and TimeBase State Machine */

  struct pnv_tod_tbst {
+/*
+ * POWER10 DD2.0 - big core TFMR drives the state machine on the even
+ * small core. Skiboot has a workaround that targets the even small core
+ * for CHIPTOD_TO_TB ops.
+ */
+bool big_core_quirk;
+
  int tb_ready_for_tod; /* core TB ready to receive TOD from chiptod */
  int tod_sent_to_tb;   /* chiptod sent TOD to the core TB */
  
@@ -49,6 +56,7 @@ struct PnvCore {
  
  /*< public >*/

  PowerPCCPU **threads;
+bool big_core;
  uint32_t pir;
  uint32_t hwid;
  uint64_t hrmor;
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 8fd6ade471..de15e38af8 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1248,6 +1248,7 @@ struct CPUArchState {
  int access_type;
  
  /* For SMT processors */

+int has_smt_siblings;
  int core_index;
  
  #if !defined(CONFIG_USER_ONLY)

@@ -1276,7 +1277,6 @@ struct CPUArchState {
  uint32_t tlb_need_flush; /* Delayed flush needed */
  #define TLB_NEED_LOCAL_FLUSH   0x1
  #define TLB_NEED_GLOBAL_FLUSH  0x2
-
  #endif
  
  /* Other registers */

@@ -1407,7 +1407,7 @@ struct CPUArchState {
  };
  
  #define PPC_CPU_HAS_CORE_SIBLINGS(cs)   \

-(cs->nr_threads > 1)
+(POWERPC_CPU(cs)->env.has_smt_siblings)
  
  #define PPC_CPU_HAS_LPAR_SIBLINGS(cs)   \

  ((POWERPC_CPU(cs)->env.flags & POWERPC_FLAG_SMT_1LPAR) &&   \
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 7d062ec16c..5364c55bbb 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -142,7 +142,7 @@ static int pnv_dt_core(PnvChip *chip, PnvCore *pc, void 
*fdt)
  CPUPPCState *env = >env;
  PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
  PnvChipClass *pnv_cc = PNV_CHIP_GET_CLASS(chip);
-g_autofree uint32_t *servers_prop = g_new(uint32_t, smt_threads);
+uint32_t *servers_prop;
  int i;
  uint32_t pir, tir;
  uint32_t segs[] = {cpu_to_be32(28), cpu_to_be32(40),
@@ -157,6 +157,14 @@ static int pnv_dt_core(PnvChip *chip, PnvCore *pc, void 
*fdt)
  
  pnv_cc->processor_id(chip, pc->hwid, 0, , );
  
+/* Only one DT node per (big) core */

+if (tir != 0) {
+g_assert(pc->big_core);
+g_assert(tir == 1);
+g_assert(pc->hwid & 1);
+return -1;


return is -1 but it's not an error. right ?


+}
+
  nodename = g_strdup_printf("%s@%x", dc->fw_name, pir);
  offset = fdt_add_subnode(fdt, cpus_offset, nodename);
  _FDT(offset);
@@ -236,12 +244,28 @@ static int pnv_dt_core(PnvChip *chip, PnvCore *pc, void 
*fdt)
  }
  
  /* Build interrupt servers properties */

-for (i = 0; i < 

Re: [RFC PATCH 07/10] target/ppc: Add helpers to check for SMT sibling threads

2024-05-29 Thread Cédric Le Goater

On 5/26/24 14:26, Nicholas Piggin wrote:

Add helpers for TCG code to determine if there are SMT siblings
sharing per-core and per-lpar registers. This simplifies the
callers and makes SMT register topology simpler to modify with
later changes.

Signed-off-by: Nicholas Piggin 
---
  target/ppc/cpu.h |  7 +++
  target/ppc/cpu_init.c|  2 +-
  target/ppc/excp_helper.c | 16 +++-
  target/ppc/misc_helper.c | 27 ++-
  target/ppc/timebase_helper.c | 20 +++-
  5 files changed, 28 insertions(+), 44 deletions(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 9a89083932..8fd6ade471 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1406,6 +1406,13 @@ struct CPUArchState {
  uint64_t pmu_base_time;
  };
  
+#define PPC_CPU_HAS_CORE_SIBLINGS(cs)   \

+(cs->nr_threads > 1)


   (cs)->nr_threads


+
+#define PPC_CPU_HAS_LPAR_SIBLINGS(cs)   \
+((POWERPC_CPU(cs)->env.flags & POWERPC_FLAG_SMT_1LPAR) &&   \
+ PPC_CPU_HAS_CORE_SIBLINGS(cs))
+


I tend to prefer static inline when things get complex.

The rest looks good.

Thanks,

C.




  #define _CORE_ID(cs)\
  (POWERPC_CPU(cs)->env.core_index)
  
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c

index ae483e20c4..e71ee008ed 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -6975,7 +6975,7 @@ static void ppc_cpu_realize(DeviceState *dev, Error 
**errp)
  
  pcc->parent_realize(dev, errp);
  
-if (env_cpu(env)->nr_threads > 1) {

+if (PPC_CPU_HAS_CORE_SIBLINGS(cs)) {
  env->flags |= POWERPC_FLAG_SMT;
  }
  
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c

index 0cd542675f..fd45da0f2b 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -3029,7 +3029,7 @@ void helper_book3s_msgsnd(CPUPPCState *env, target_ulong 
rb)
  brdcast = true;
  }
  
-if (cs->nr_threads == 1 || !brdcast) {

+if (!PPC_CPU_HAS_CORE_SIBLINGS(cs) || !brdcast) {
  ppc_set_irq(cpu, PPC_INTERRUPT_HDOORBELL, 1);
  return;
  }
@@ -3067,21 +3067,19 @@ void helper_book3s_msgsndp(CPUPPCState *env, 
target_ulong rb)
  CPUState *cs = env_cpu(env);
  PowerPCCPU *cpu = env_archcpu(env);
  CPUState *ccs;
-uint32_t nr_threads = cs->nr_threads;
  int ttir = rb & PPC_BITMASK(57, 63);
  
  helper_hfscr_facility_check(env, HFSCR_MSGP, "msgsndp", HFSCR_IC_MSGP);
  
-if (!(env->flags & POWERPC_FLAG_SMT_1LPAR)) {

-nr_threads = 1; /* msgsndp behaves as 1-thread in LPAR-per-thread 
mode*/
-}
-
-if (!dbell_type_server(rb) || ttir >= nr_threads) {
+if (!dbell_type_server(rb)) {
  return;
  }
  
-if (nr_threads == 1) {

-ppc_set_irq(cpu, PPC_INTERRUPT_DOORBELL, 1);
+/* msgsndp behaves as 1-thread in LPAR-per-thread mode*/
+if (!PPC_CPU_HAS_LPAR_SIBLINGS(cs)) {
+if (ttir == 0) {
+ppc_set_irq(cpu, PPC_INTERRUPT_DOORBELL, 1);
+}
  return;
  }
  
diff --git a/target/ppc/misc_helper.c b/target/ppc/misc_helper.c

index 46ba3a5584..598c956cdd 100644
--- a/target/ppc/misc_helper.c
+++ b/target/ppc/misc_helper.c
@@ -49,9 +49,8 @@ void helper_spr_core_write_generic(CPUPPCState *env, uint32_t 
sprn,
  {
  CPUState *cs = env_cpu(env);
  CPUState *ccs;
-uint32_t nr_threads = cs->nr_threads;
  
-if (nr_threads == 1) {

+if (!PPC_CPU_HAS_CORE_SIBLINGS(cs)) {
  env->spr[sprn] = val;
  return;
  }
@@ -196,7 +195,7 @@ void helper_store_ptcr(CPUPPCState *env, target_ulong val)
  return;
  }
  
-if (cs->nr_threads == 1 || !(env->flags & POWERPC_FLAG_SMT_1LPAR)) {

+if (!PPC_CPU_HAS_LPAR_SIBLINGS(cs)) {
  env->spr[SPR_PTCR] = val;
  tlb_flush(cs);
  } else {
@@ -243,16 +242,12 @@ target_ulong helper_load_dpdes(CPUPPCState *env)
  {
  CPUState *cs = env_cpu(env);
  CPUState *ccs;
-uint32_t nr_threads = cs->nr_threads;
  target_ulong dpdes = 0;
  
  helper_hfscr_facility_check(env, HFSCR_MSGP, "load DPDES", HFSCR_IC_MSGP);
  
-if (!(env->flags & POWERPC_FLAG_SMT_1LPAR)) {

-nr_threads = 1; /* DPDES behaves as 1-thread in LPAR-per-thread mode */
-}
-
-if (nr_threads == 1) {
+/* DPDES behaves as 1-thread in LPAR-per-thread mode */
+if (!PPC_CPU_HAS_LPAR_SIBLINGS(cs)) {
  if (env->pending_interrupts & PPC_INTERRUPT_DOORBELL) {
  dpdes = 1;
  }
@@ -279,21 +274,11 @@ void helper_store_dpdes(CPUPPCState *env, target_ulong 
val)
  PowerPCCPU *cpu = env_archcpu(env);
  CPUState *cs = env_cpu(env);
  CPUState *ccs;
-uint32_t nr_threads = cs->nr_threads;
  
  helper_hfscr_facility_check(env, HFSCR_MSGP, "store DPDES", HFSCR_IC_MSGP);
  
-if (!(env->flags & POWERPC_FLAG_SMT_1LPAR)) {

-nr_threads = 

Re: [RFC PATCH 05/10] ppc/pnv: Extend chip_pir class method to TIR as well

2024-05-29 Thread Cédric Le Goater

On 5/29/24 02:24, Nicholas Piggin wrote:

On Tue May 28, 2024 at 6:32 PM AEST, Harsh Prateek Bora wrote:



On 5/26/24 17:56, Nicholas Piggin wrote:

The chip_pir chip class method allows the platform to set the PIR
processor identification register. Extend this to a more general
ID function which also allows the TIR to be set. This is in
preparation for "big core", which is a more complicated topology
of cores and threads.

Signed-off-by: Nicholas Piggin 
---
   include/hw/ppc/pnv_chip.h |  3 +-
   hw/ppc/pnv.c  | 61 ---
   hw/ppc/pnv_core.c | 10 ---
   3 files changed, 45 insertions(+), 29 deletions(-)

diff --git a/include/hw/ppc/pnv_chip.h b/include/hw/ppc/pnv_chip.h
index 8589f3291e..679723926a 100644
--- a/include/hw/ppc/pnv_chip.h
+++ b/include/hw/ppc/pnv_chip.h
@@ -147,7 +147,8 @@ struct PnvChipClass {
   
   DeviceRealize parent_realize;
   
-uint32_t (*chip_pir)(PnvChip *chip, uint32_t core_id, uint32_t thread_id);

+void (*processor_id)(PnvChip *chip, uint32_t core_id, uint32_t thread_id,
+ uint32_t *pir, uint32_t *tir);


Should it be named get_chip_core_thread_regs() ?


Yeah, the name isn't great. It is getting the regs, but the regs are the
"pervasive id" used as well... but maybe that's not too relevant here.
What about we drop chip_ since we have the chip and no other methods use
such prefix, then call it get_thread_pir_tir()?


processor relates to chip and so, processor_id() is not great indeed.
get_pir_tir() would be enough I think.

What would be good though, since pnv is growing, is to start adding
documentation to these common helpers.


Thanks,

C.




@@ -155,7 +155,7 @@ static int pnv_dt_core(PnvChip *chip, PnvCore *pc, void 
*fdt)
   char *nodename;
   int cpus_offset = get_cpus_node(fdt);
   
-pir = pnv_cc->chip_pir(chip, pc->hwid, 0);

+pnv_cc->processor_id(chip, pc->hwid, 0, , );


As a generic helper API and potentially expandable, it should allow
passing NULL for registers whose values are not really sought to avoid
having to create un-necessary local variables by the caller.


I'll do that.

Thanks,
Nick





Re: [PATCH v4 00/16] Add AST2700 support

2024-05-28 Thread Cédric Le Goater

On 5/28/24 12:02, Jamin Lin wrote:

Hi Cedric,


-Original Message-
From: Cédric Le Goater 
Sent: Tuesday, May 28, 2024 5:56 PM
To: Jamin Lin ; Peter Maydell
; Andrew Jeffery ;
Joel Stanley ; Alistair Francis ; Cleber
Rosa ; Philippe Mathieu-Daudé ;
Wainer dos Santos Moschetta ; Beraldo Leal
; open list:ASPEED BMCs ; open
list:All patches CC here 
Cc: Troy Lee ; Yunlin Tang

Subject: Re: [PATCH v4 00/16] Add AST2700 support

Jamin,

I think you should add your self as a Reviewer to the ASPEED BMCs machine in
the MAINTAINERS files. Would you agree ?


Agree.

Could you please add me, Troy and Steven in the MAINTAINERS files?
steven_...@aspeedtech.com
troy_...@aspeedtech.com
jamin_...@aspeedtech.com


You should send a patch updating the MAINTAINERS file with new names
and those promoted should reply that they agree, or not.

See https://qemu.readthedocs.io/en/v9.0.0/devel/maintainers.html for
more info and the git history of MAINTAINERS also.

Thanks,

C.





Re: [PATCH v4 00/16] Add AST2700 support

2024-05-28 Thread Cédric Le Goater

Jamin,

I think you should add your self as a Reviewer to the ASPEED BMCs
machine in the MAINTAINERS files. Would you agree ?

Thanks,

C.



On 5/27/24 10:02, Jamin Lin wrote:

Changes from v1:
The patch series supports WDT, SDMC, SMC, SCU, SLI and INTC for AST2700 SoC.

Changes from v2:
- replace is_aarch64 with is_bus64bit for sdmc patch review.
- fix incorrect dram size for AST2700

Changes from v3:
- Add AST2700 Evaluation board in ASPEED document
- Add avocado test cases for AST2700 Evaluation board
- Fix reviewers review issues and add reviewers suggestions
- Implement INTC model GICINT 128 to GICINT136 for AST2700

Changes from v4:
- support 64 bits dma dram address associated with review issues
- support dma start length and 1 byte length unit associated with review issues
- refactor intc model to fix serial console stuck issue and associated with 
review issues

Test Version:
https://github.com/qemu/qemu/commit/0c2a3807483b4ebe360cfa475dbfc9dfd2f6d16d

Test steps:
1. Download the latest openbmc image for AST2700 from AspeedTech-BMC/openbmc
repository, https://github.com/AspeedTech-BMC/openbmc/releases/tag/v09.01
link: 
https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.01/ast2700-default-obmc.tar.gz
2. untar ast2700-default-obmc.tar.gz
```
tar -xf ast2700-default-obmc.tar.gz
```
3. Run and the contents of scripts as following
IMGDIR=ast2700-default
UBOOT_SIZE=$(stat --format=%s -L ${IMGDIR}/u-boot-nodtb.bin)
UBOOT_DTB_ADDR=$((0x4 + ${UBOOT_SIZE}))

qemu-system-aarch64 -M ast2700-evb -nographic\
  -device loader,addr=0x4,file=${IMGDIR}/u-boot-nodtb.bin,force-raw=on\
  -device loader,addr=${UBOOT_DTB_ADDR},file=${IMGDIR}/u-boot.dtb,force-raw=on\
  -device loader,addr=0x43000,file=${IMGDIR}/bl31.bin,force-raw=on\
  -device loader,addr=0x43008,file=${IMGDIR}/optee/tee-raw.bin,force-raw=on\
  -device loader,addr=0x43000,cpu-num=0\
  -device loader,addr=0x43000,cpu-num=1\
  -device loader,addr=0x43000,cpu-num=2\
  -device loader,addr=0x43000,cpu-num=3\
  -smp 4\
  -drive file=${IMGDIR}/image-bmc,format=raw,if=mtd\
  -serial mon:stdio\
  -snapshot

Jamin Lin (16):
   aspeed/wdt: Add AST2700 support
   aspeed/sli: Add AST2700 support
   aspeed/sdmc: remove redundant macros
   aspeed/sdmc: fix coding style
   aspeed/sdmc: Add AST2700 support
   aspeed/smc: correct device description
   aspeed/smc: support dma start length and 1 byte length unit
   aspeed/smc: support 64 bits dma dram address
   aspeed/smc: Add AST2700 support
   aspeed/scu: Add AST2700 support
   aspeed/intc: Add AST2700 support
   aspeed/soc: Add AST2700 support
   aspeed: Add an AST2700 eval board
   aspeed/soc: fix incorrect dram size for AST2700
   test/avocado/machine_aspeed.py: Add AST2700 test case
   docs:aspeed: Add AST2700 Evaluation board

  docs/system/arm/aspeed.rst   |  39 +-
  hw/arm/aspeed.c  |  32 ++
  hw/arm/aspeed_ast27x0.c  | 655 +++
  hw/arm/meson.build   |   1 +
  hw/intc/aspeed_intc.c| 355 +
  hw/intc/meson.build  |   1 +
  hw/intc/trace-events |   6 +
  hw/misc/aspeed_scu.c | 306 ++-
  hw/misc/aspeed_sdmc.c| 216 +-
  hw/misc/aspeed_sli.c | 177 +
  hw/misc/meson.build  |   3 +-
  hw/misc/trace-events |  11 +
  hw/ssi/aspeed_smc.c  | 321 ++-
  hw/ssi/trace-events  |   2 +-
  hw/watchdog/wdt_aspeed.c |  24 ++
  include/hw/arm/aspeed_soc.h  |  27 +-
  include/hw/intc/aspeed_intc.h|  46 +++
  include/hw/misc/aspeed_scu.h |  47 ++-
  include/hw/misc/aspeed_sdmc.h|   5 +-
  include/hw/misc/aspeed_sli.h |  27 ++
  include/hw/ssi/aspeed_smc.h  |   2 +
  include/hw/watchdog/wdt_aspeed.h |   3 +-
  tests/avocado/machine_aspeed.py  |  62 +++
  23 files changed, 2312 insertions(+), 56 deletions(-)
  create mode 100644 hw/arm/aspeed_ast27x0.c
  create mode 100644 hw/intc/aspeed_intc.c
  create mode 100644 hw/misc/aspeed_sli.c
  create mode 100644 include/hw/intc/aspeed_intc.h
  create mode 100644 include/hw/misc/aspeed_sli.h






Re: [PATCH v4 05/16] aspeed/sdmc: Add AST2700 support

2024-05-28 Thread Cédric Le Goater

[ ... ]


I don't think this is necessary to do so now. Possibly, increase the version
number in the vmstate when resending a v5.


If I understand your request, do you mean to change as following in this patch?

static const VMStateDescription vmstate_aspeed_sdmc = {
 .name = "aspeed.sdmc",
 .version_id = 1,  ---> Change 2
 .minimum_version_id = 1, ---> Change 2
};


yes.



Also, all Aspeed models should be addressed and that's beyond the scope of
this series.



And create a new patch series to update all vmstate version for all ASPEED 
models?


That would be to remove migration support for Aspeed machines. For later.
Let's address AST2700 first.

Thanks,

C.



Re: [PATCH v4 12/16] aspeed/soc: Add AST2700 support

2024-05-28 Thread Cédric Le Goater

On 5/27/24 10:02, Jamin Lin wrote:

Initial definitions for a simple machine using an AST2700 SOC (Cortex-a35 CPU).

AST2700 SOC and its interrupt controller are too complex to handle
in the common Aspeed SoC framework. We introduce a new ast2700
class with instance_init and realize handlers.

AST2700 is a 64 bits quad core cpus and support 8 watchdog.
Update maximum ASPEED_CPUS_NUM to 4 and ASPEED_WDTS_NUM to 8.
In addition, update AspeedSocState to support scuio, sli, sliio and intc.

Add TYPE_ASPEED27X0_SOC machine type.

The SDMC controller is unlocked at SPL stage.
At present, only supports to emulate booting
start from u-boot stage. Set SDMC controller
unlocked by default.

In INTC, each interrupt of INT 128 to INT 136 combines 32 interrupts.
It connect GICINT IRQ GPIO-OUTPUT pins to GIC device with irq 128 to 136.
And, if a device irq is 128 to 136, its irq GPIO-OUTPUT pin is connected to
GICINT or-gates instead of GIC device.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
---
  hw/arm/aspeed_ast27x0.c | 563 
  hw/arm/meson.build  |   1 +
  include/hw/arm/aspeed_soc.h |  26 +-
  3 files changed, 588 insertions(+), 2 deletions(-)
  create mode 100644 hw/arm/aspeed_ast27x0.c

diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c
new file mode 100644
index 00..a3a03fc1ca
--- /dev/null
+++ b/hw/arm/aspeed_ast27x0.c
@@ -0,0 +1,563 @@
+/*
+ * ASPEED SoC 27x0 family
+ *
+ * Copyright (C) 2024 ASPEED Technology Inc.
+ *
+ * This code is licensed under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ *
+ * Implementation extracted from the AST2600 and adapted for AST27x0.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/misc/unimp.h"
+#include "hw/arm/aspeed_soc.h"
+#include "qemu/module.h"
+#include "qemu/error-report.h"
+#include "hw/i2c/aspeed_i2c.h"
+#include "net/net.h"
+#include "sysemu/sysemu.h"
+#include "hw/intc/arm_gicv3.h"
+#include "qapi/qmp/qlist.h"
+
+static const hwaddr aspeed_soc_ast2700_memmap[] = {
+[ASPEED_DEV_SPI_BOOT]  =  0x4,
+[ASPEED_DEV_SRAM]  =  0x1000,
+[ASPEED_DEV_SDMC]  =  0x12C0,
+[ASPEED_DEV_SCU]   =  0x12C02000,
+[ASPEED_DEV_SCUIO] =  0x14C02000,
+[ASPEED_DEV_UART0] =  0X14C33000,
+[ASPEED_DEV_UART1] =  0X14C33100,
+[ASPEED_DEV_UART2] =  0X14C33200,
+[ASPEED_DEV_UART3] =  0X14C33300,
+[ASPEED_DEV_UART4] =  0X12C1A000,
+[ASPEED_DEV_UART5] =  0X14C33400,
+[ASPEED_DEV_UART6] =  0X14C33500,
+[ASPEED_DEV_UART7] =  0X14C33600,
+[ASPEED_DEV_UART8] =  0X14C33700,
+[ASPEED_DEV_UART9] =  0X14C33800,
+[ASPEED_DEV_UART10]=  0X14C33900,
+[ASPEED_DEV_UART11]=  0X14C33A00,
+[ASPEED_DEV_UART12]=  0X14C33B00,
+[ASPEED_DEV_WDT]   =  0x14C37000,
+[ASPEED_DEV_VUART] =  0X14C3,
+[ASPEED_DEV_FMC]   =  0x1400,
+[ASPEED_DEV_SPI0]  =  0x1401,
+[ASPEED_DEV_SPI1]  =  0x1402,
+[ASPEED_DEV_SPI2]  =  0x1403,
+[ASPEED_DEV_SDRAM] =  0x4,
+[ASPEED_DEV_MII1]  =  0x1404,
+[ASPEED_DEV_MII2]  =  0x14040008,
+[ASPEED_DEV_MII3]  =  0x14040010,
+[ASPEED_DEV_ETH1]  =  0x1405,
+[ASPEED_DEV_ETH2]  =  0x1406,
+[ASPEED_DEV_ETH3]  =  0x1407,
+[ASPEED_DEV_EMMC]  =  0x1209,
+[ASPEED_DEV_INTC]  =  0x1210,
+[ASPEED_DEV_SLI]   =  0x12C17000,
+[ASPEED_DEV_SLIIO] =  0x14C1E000,
+[ASPEED_GIC_DIST]  =  0x1220,
+[ASPEED_GIC_REDIST]=  0x1228,
+};
+
+#define AST2700_MAX_IRQ 288
+
+/* Shared Peripheral Interrupt values below are offset by -32 from datasheet */
+static const int aspeed_soc_ast2700_irqmap[] = {
+[ASPEED_DEV_UART0] = 132,
+[ASPEED_DEV_UART1] = 132,
+[ASPEED_DEV_UART2] = 132,
+[ASPEED_DEV_UART3] = 132,
+[ASPEED_DEV_UART4] = 8,
+[ASPEED_DEV_UART5] = 132,
+[ASPEED_DEV_UART6] = 132,
+[ASPEED_DEV_UART7] = 132,
+[ASPEED_DEV_UART8] = 132,
+[ASPEED_DEV_UART9] = 132,
+[ASPEED_DEV_UART10]= 132,
+[ASPEED_DEV_UART11]= 132,
+[ASPEED_DEV_UART12]= 132,
+[ASPEED_DEV_FMC]   = 131,
+[ASPEED_DEV_SDMC]  = 0,
+[ASPEED_DEV_SCU]   = 12,
+[ASPEED_DEV_ADC]   = 130,
+[ASPEED_DEV_XDMA]  = 5,
+[ASPEED_DEV_EMMC]  = 15,
+[ASPEED_DEV_GPIO]  = 11,
+[ASPEED_DEV_GPIO_1_8V] = 130,
+[ASPEED_DEV_RTC]   = 13,
+[ASPEED_DEV_TIMER1]= 16,
+[ASPEED_DEV_TIMER2]= 17,
+[ASPEED_DEV_TIMER3]= 18,
+[ASPEED_DEV_TIMER4]= 19,
+[ASPEED_DEV_TIMER5]= 20,
+[ASPEED_DEV_TIMER6]= 21,
+[ASPEED_DEV_TIMER7]= 22,
+[ASPEED_DEV_TIMER8]= 23,
+[ASPEED_DEV_WDT]   = 131,
+[ASPEED_DEV_PWM]   = 131,
+[ASPEED_DEV_LPC]   = 128,
+[ASPEED_DEV_IBT]

Re: [PATCH v4 11/16] aspeed/intc: Add AST2700 support

2024-05-28 Thread Cédric Le Goater

On 5/27/24 10:02, Jamin Lin wrote:

AST2700 interrupt controller(INTC) provides hardware interrupt interfaces
to interrupt of processors PSP, SSP and TSP. In INTC, each interrupt of
INT 128 to INT136 combines 32 interrupts.

Introduce a new aspeed_intc class with instance_init and realize handlers.

So far, this model only supports GICINT128 to GICINT136.
It creates 9 GICINT or-gates to connect 32 interrupts sources
from GICINT128 to GICINT136 as IRQ GPIO-OUTPUT pins.
Then, this model registers IRQ handler with its IRQ GPIO-INPUT pins which
connect to GICINT or-gates. And creates 9 GICINT IRQ GPIO-OUTPUT pins which
connect to GIC device with GIC IRQ 128 to 136.

If one interrupt source from GICINT128 to GICINT136
set irq, the OR-GATE irq callback function is called and set irq to INTC by
OR-GATE GPIO-OUTPUT pins. Then, the INTC irq callback function is called and
set irq to GIC by its GICINT IRQ GPIO-OUTPUT pins. Finally, the GIC irq
callback function is called and set irq to CPUs and
CPUs execute Interrupt Service Routine (ISR).

Block diagram of GICINT132:

 GICINT132
   ETH1+---+
+>+0 3|
   ETH2|  4|
+>+1 5|
   ETH3|  6|
+>+219|  INTC  
GIC
   UART0   | 20|+--+
+>+721||  |
+--+
   UART1   | 22||orgate0 +> 
output_pin0+--->+GIC128|
+>+823||  ||
  |
   UART2   | 24||orgate1 +> 
output_pin1+--->+GIC129|
+>+925||  ||
  |
   UART3   | 26||orgate2 +> 
output_pin2+--->+GIC130|
+->10   27||  ||
  |
   UART5   | 28||orgate3 +> 
output_pin3+--->+GIC131|
+>+11   29||  ||
  |
   UART6   |   +--->+orgate4 +> 
output_pin4+--->+GIC132|
+>+12   30||  ||
  |
   UART7   | 31||orgate5 +> 
output_pin5+--->+GIC133|
+>+13 ||  ||
  |
   UART8   |  OR[0:31] ||orgate6 +> 
output_pin6+--->+GIC134|
-->14 ||  ||
  |
   UART9   |   ||orgate7 +> 
output_pin7+--->+GIC135|
->+15 ||  ||
  |
   UART10  |   ||orgate8 +> 
output_pin8+--->+GIC136|
->+16 ||  |
+--+
   UART11  |   |+--+
+>+17 |
   UART12  |   |
+->18 |
   |   |
   |   |
   |   |
   +---+

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
---
  hw/intc/aspeed_intc.c | 355 ++
  hw/intc/meson.build   |   1 +
  hw/intc/trace-events  |   6 +
  include/hw/intc/aspeed_intc.h |  46 +
  4 files changed, 408 insertions(+)
  create mode 100644 hw/intc/aspeed_intc.c
  create mode 100644 include/hw/intc/aspeed_intc.h

diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c
new file mode 100644
index 00..cb6111d79c
--- /dev/null
+++ b/hw/intc/aspeed_intc.c
@@ -0,0 +1,355 @@
+/*
+ * ASPEED INTC Controller
+ *
+ * Copyright (C) 2024 ASPEED Technology Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "hw/intc/aspeed_intc.h"
+#include "hw/irq.h"
+#include "migration/vmstate.h"
+#include "qemu/bitops.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "hw/intc/arm_gicv3.h"
+#include "trace.h"
+#include "hw/registerfields.h"
+#include "qapi/error.h"
+#include "hw/qdev-properties.h"
+
+/* INTC Registers */
+REG32(GICINT128_EN, 0x1000)
+REG32(GICINT128_STATUS, 0x1004)
+REG32(GICINT129_EN, 0x1100)
+REG32(GICINT129_STATUS, 0x1104)
+REG32(GICINT130_EN, 0x1200)
+REG32(GICINT130_STATUS, 0x1204)
+REG32(GICINT131_EN, 0x1300)
+REG32(GICINT131_STATUS, 0x1304)
+REG32(GICINT132_EN, 0x1400)
+REG32(GICINT132_STATUS, 0x1404)
+REG32(GICINT133_EN, 0x1500)
+REG32(GICINT133_STATUS, 0x1504)
+REG32(GICINT134_EN, 0x1600)
+REG32(GICINT134_STATUS, 0x1604)
+REG32(GICINT135_EN, 0x1700)

Re: [PATCH v4 12/16] aspeed/soc: Add AST2700 support

2024-05-28 Thread Cédric Le Goater

On 5/27/24 10:02, Jamin Lin wrote:

Initial definitions for a simple machine using an AST2700 SOC (Cortex-a35 CPU).

AST2700 SOC and its interrupt controller are too complex to handle
in the common Aspeed SoC framework. We introduce a new ast2700
class with instance_init and realize handlers.

AST2700 is a 64 bits quad core cpus and support 8 watchdog.
Update maximum ASPEED_CPUS_NUM to 4 and ASPEED_WDTS_NUM to 8.
In addition, update AspeedSocState to support scuio, sli, sliio and intc.

Add TYPE_ASPEED27X0_SOC machine type.

The SDMC controller is unlocked at SPL stage.
At present, only supports to emulate booting
start from u-boot stage. Set SDMC controller
unlocked by default.

In INTC, each interrupt of INT 128 to INT 136 combines 32 interrupts.
It connect GICINT IRQ GPIO-OUTPUT pins to GIC device with irq 128 to 136.
And, if a device irq is 128 to 136, its irq GPIO-OUTPUT pin is connected to
GICINT or-gates instead of GIC device.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
---
  hw/arm/aspeed_ast27x0.c | 563 
  hw/arm/meson.build  |   1 +
  include/hw/arm/aspeed_soc.h |  26 +-
  3 files changed, 588 insertions(+), 2 deletions(-)
  create mode 100644 hw/arm/aspeed_ast27x0.c

diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c
new file mode 100644
index 00..a3a03fc1ca
--- /dev/null
+++ b/hw/arm/aspeed_ast27x0.c
@@ -0,0 +1,563 @@
+/*
+ * ASPEED SoC 27x0 family
+ *
+ * Copyright (C) 2024 ASPEED Technology Inc.
+ *
+ * This code is licensed under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ *
+ * Implementation extracted from the AST2600 and adapted for AST27x0.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/misc/unimp.h"
+#include "hw/arm/aspeed_soc.h"
+#include "qemu/module.h"
+#include "qemu/error-report.h"
+#include "hw/i2c/aspeed_i2c.h"
+#include "net/net.h"
+#include "sysemu/sysemu.h"
+#include "hw/intc/arm_gicv3.h"
+#include "qapi/qmp/qlist.h"
+
+static const hwaddr aspeed_soc_ast2700_memmap[] = {
+[ASPEED_DEV_SPI_BOOT]  =  0x4,
+[ASPEED_DEV_SRAM]  =  0x1000,
+[ASPEED_DEV_SDMC]  =  0x12C0,
+[ASPEED_DEV_SCU]   =  0x12C02000,
+[ASPEED_DEV_SCUIO] =  0x14C02000,
+[ASPEED_DEV_UART0] =  0X14C33000,
+[ASPEED_DEV_UART1] =  0X14C33100,
+[ASPEED_DEV_UART2] =  0X14C33200,
+[ASPEED_DEV_UART3] =  0X14C33300,
+[ASPEED_DEV_UART4] =  0X12C1A000,
+[ASPEED_DEV_UART5] =  0X14C33400,
+[ASPEED_DEV_UART6] =  0X14C33500,
+[ASPEED_DEV_UART7] =  0X14C33600,
+[ASPEED_DEV_UART8] =  0X14C33700,
+[ASPEED_DEV_UART9] =  0X14C33800,
+[ASPEED_DEV_UART10]=  0X14C33900,
+[ASPEED_DEV_UART11]=  0X14C33A00,
+[ASPEED_DEV_UART12]=  0X14C33B00,
+[ASPEED_DEV_WDT]   =  0x14C37000,
+[ASPEED_DEV_VUART] =  0X14C3,
+[ASPEED_DEV_FMC]   =  0x1400,
+[ASPEED_DEV_SPI0]  =  0x1401,
+[ASPEED_DEV_SPI1]  =  0x1402,
+[ASPEED_DEV_SPI2]  =  0x1403,
+[ASPEED_DEV_SDRAM] =  0x4,
+[ASPEED_DEV_MII1]  =  0x1404,
+[ASPEED_DEV_MII2]  =  0x14040008,
+[ASPEED_DEV_MII3]  =  0x14040010,
+[ASPEED_DEV_ETH1]  =  0x1405,
+[ASPEED_DEV_ETH2]  =  0x1406,
+[ASPEED_DEV_ETH3]  =  0x1407,
+[ASPEED_DEV_EMMC]  =  0x1209,
+[ASPEED_DEV_INTC]  =  0x1210,
+[ASPEED_DEV_SLI]   =  0x12C17000,
+[ASPEED_DEV_SLIIO] =  0x14C1E000,
+[ASPEED_GIC_DIST]  =  0x1220,
+[ASPEED_GIC_REDIST]=  0x1228,
+};
+
+#define AST2700_MAX_IRQ 288
+
+/* Shared Peripheral Interrupt values below are offset by -32 from datasheet */
+static const int aspeed_soc_ast2700_irqmap[] = {
+[ASPEED_DEV_UART0] = 132,
+[ASPEED_DEV_UART1] = 132,
+[ASPEED_DEV_UART2] = 132,
+[ASPEED_DEV_UART3] = 132,
+[ASPEED_DEV_UART4] = 8,
+[ASPEED_DEV_UART5] = 132,
+[ASPEED_DEV_UART6] = 132,
+[ASPEED_DEV_UART7] = 132,
+[ASPEED_DEV_UART8] = 132,
+[ASPEED_DEV_UART9] = 132,
+[ASPEED_DEV_UART10]= 132,
+[ASPEED_DEV_UART11]= 132,
+[ASPEED_DEV_UART12]= 132,
+[ASPEED_DEV_FMC]   = 131,
+[ASPEED_DEV_SDMC]  = 0,
+[ASPEED_DEV_SCU]   = 12,
+[ASPEED_DEV_ADC]   = 130,
+[ASPEED_DEV_XDMA]  = 5,
+[ASPEED_DEV_EMMC]  = 15,
+[ASPEED_DEV_GPIO]  = 11,
+[ASPEED_DEV_GPIO_1_8V] = 130,
+[ASPEED_DEV_RTC]   = 13,
+[ASPEED_DEV_TIMER1]= 16,
+[ASPEED_DEV_TIMER2]= 17,
+[ASPEED_DEV_TIMER3]= 18,
+[ASPEED_DEV_TIMER4]= 19,
+[ASPEED_DEV_TIMER5]= 20,
+[ASPEED_DEV_TIMER6]= 21,
+[ASPEED_DEV_TIMER7]= 22,
+[ASPEED_DEV_TIMER8]= 23,
+[ASPEED_DEV_WDT]   = 131,
+[ASPEED_DEV_PWM]   = 131,
+[ASPEED_DEV_LPC]   = 128,
+[ASPEED_DEV_IBT]

Re: [RFC PATCH 02/10] ppc/pnv: Move timebase state into PnvCore

2024-05-28 Thread Cédric Le Goater

On 5/28/24 08:28, Harsh Prateek Bora wrote:



On 5/26/24 17:56, Nicholas Piggin wrote:

The timebase state machine is per per-core state and can be driven
by any thread in the core. It is currently implemented as a hack
where the state is in a CPU structure and only thread 0's state is
accessed by the chiptod, which limits programming the timebase
side of the state machine to thread 0 of a core.

Move the state out into PnvCore and share it among all threads.

Signed-off-by: Nicholas Piggin 
---
  include/hw/ppc/pnv_core.h    | 17 
  target/ppc/cpu.h | 20 --
  hw/ppc/pnv_chiptod.c |  6 ++--
  target/ppc/timebase_helper.c | 53 
  4 files changed, 49 insertions(+), 47 deletions(-)

diff --git a/include/hw/ppc/pnv_core.h b/include/hw/ppc/pnv_core.h
index 30c1e5b1a3..f434c71547 100644
--- a/include/hw/ppc/pnv_core.h
+++ b/include/hw/ppc/pnv_core.h
@@ -25,6 +25,20 @@
  #include "hw/ppc/pnv.h"
  #include "qom/object.h"
+/* ChipTOD and TimeBase State Machine */
+struct pnv_tod_tbst {
+    int tb_ready_for_tod; /* core TB ready to receive TOD from chiptod */
+    int tod_sent_to_tb;   /* chiptod sent TOD to the core TB */
+
+    /*
+ * "Timers" for async TBST events are simulated by mfTFAC because TFAC
+ * is polled for such events. These are just used to ensure firmware
+ * performs the polling at least a few times.
+ */
+    int tb_state_timer;
+    int tb_sync_pulse_timer;
+};
+
  #define TYPE_PNV_CORE "powernv-cpu-core"
  OBJECT_DECLARE_TYPE(PnvCore, PnvCoreClass,
  PNV_CORE)
@@ -38,6 +52,9 @@ struct PnvCore {
  uint32_t pir;
  uint32_t hwid;
  uint64_t hrmor;
+
+    struct pnv_tod_tbst pnv_tod_tbst;
+


Now that it is part of struct PnvCore itself, we can drop pnv_ prefix
and just call the member variable as tod_tbst ?


yes and rename pnv_tod_tbst using CamelCase please.


Thanks,

C.







  PnvChip *chip;
  MemoryRegion xscom_regs;
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 2015e603d4..1e86658da6 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1196,21 +1196,6 @@ DEXCR_ASPECT(SRAPD, 4)
  DEXCR_ASPECT(NPHIE, 5)
  DEXCR_ASPECT(PHIE, 6)
-/*/
-/* PowerNV ChipTOD and TimeBase State Machine */
-struct pnv_tod_tbst {
-    int tb_ready_for_tod; /* core TB ready to receive TOD from chiptod */
-    int tod_sent_to_tb;   /* chiptod sent TOD to the core TB */
-
-    /*
- * "Timers" for async TBST events are simulated by mfTFAC because TFAC
- * is polled for such events. These are just used to ensure firmware
- * performs the polling at least a few times.
- */
-    int tb_state_timer;
-    int tb_sync_pulse_timer;
-};
-
  
/*/
  /* The whole PowerPC CPU context */
@@ -1292,11 +1277,6 @@ struct CPUArchState {
  #define TLB_NEED_LOCAL_FLUSH   0x1
  #define TLB_NEED_GLOBAL_FLUSH  0x2
-#if defined(TARGET_PPC64)
-    /* PowerNV chiptod / timebase facility state. */
-    /* Would be nice to put these into PnvCore */
-    struct pnv_tod_tbst pnv_tod_tbst;
-#endif
  #endif
  /* Other registers */
diff --git a/hw/ppc/pnv_chiptod.c b/hw/ppc/pnv_chiptod.c
index 3831a72101..3eaddd66f0 100644
--- a/hw/ppc/pnv_chiptod.c
+++ b/hw/ppc/pnv_chiptod.c
@@ -365,7 +365,7 @@ static void pnv_chiptod_xscom_write(void *opaque, hwaddr 
addr,
    " TOD_MOVE_TOD_TO_TB_REG with no slave target\n");
  } else {
  PowerPCCPU *cpu = chiptod->slave_pc_target->threads[0];
-    CPUPPCState *env = >env;
+    PnvCore *pc = pnv_cpu_state(cpu)->core;
  /*
   * Moving TOD to TB will set the TB of all threads in a
@@ -377,8 +377,8 @@ static void pnv_chiptod_xscom_write(void *opaque, hwaddr 
addr,
   * thread 0.
   */
-    if (env->pnv_tod_tbst.tb_ready_for_tod) {
-    env->pnv_tod_tbst.tod_sent_to_tb = 1;
+    if (pc->pnv_tod_tbst.tb_ready_for_tod) {
+    pc->pnv_tod_tbst.tod_sent_to_tb = 1;
  } else {
  qemu_log_mask(LOG_GUEST_ERROR, "pnv_chiptod: xscom write reg"
    " TOD_MOVE_TOD_TO_TB_REG with TB not ready to"
diff --git a/target/ppc/timebase_helper.c b/target/ppc/timebase_helper.c
index 39d397416e..788c498d63 100644
--- a/target/ppc/timebase_helper.c
+++ b/target/ppc/timebase_helper.c
@@ -19,6 +19,7 @@
  #include "qemu/osdep.h"
  #include "cpu.h"
  #include "hw/ppc/ppc.h"
+#include "hw/ppc/pnv_core.h"
  #include "exec/helper-proto.h"
  #include "exec/exec-all.h"
  #include "qemu/log.h"
@@ -298,8 +299,17 @@ static void write_tfmr(CPUPPCState *env, target_ulong val)
  }
  }
+static struct pnv_tod_tbst *cpu_get_tbst(PowerPCCPU *cpu)
+{
+    PnvCore *pc = pnv_cpu_state(cpu)->core;
+
+    return >pnv_tod_tbst;
+}
+
  static void 

Re: [RFC PATCH 04/10] ppc/pnv: specialise init for powernv8/9/10 machines

2024-05-28 Thread Cédric Le Goater

On 5/28/24 09:10, Harsh Prateek Bora wrote:

Hi Nick,

On 5/26/24 17:56, Nicholas Piggin wrote:

This will allow different settings and checks for different
machine types with later changes.

Signed-off-by: Nicholas Piggin 
---
  hw/ppc/pnv.c | 35 ++-
  1 file changed, 30 insertions(+), 5 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 6e3a5ccdec..a706de2e36 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -976,11 +976,6 @@ static void pnv_init(MachineState *machine)
  pnv->num_chips =
  machine->smp.max_cpus / (machine->smp.cores * machine->smp.threads);
-    if (machine->smp.threads > 8) {
-    error_report("Cannot support more than 8 threads/core "
- "on a powernv machine");
-    exit(1);
-    }
  if (!is_power_of_2(machine->smp.threads)) {
  error_report("Cannot support %d threads/core on a powernv"
   "machine because it must be a power of 2",
@@ -1076,6 +1071,33 @@ static void pnv_init(MachineState *machine)
  }
  }
+static void pnv_power8_init(MachineState *machine)
+{
+    if (machine->smp.threads > 8) {
+    error_report("Cannot support more than 8 threads/core "
+ "on a powernv POWER8 machine");


We could use mc->desc for machine name above, so that ..


+    exit(1);
+    }


with this patch, we can reuse p8 init for both p9 and p10 (and not just reuse 
p9 for p10 with hard coded string?).


Good idea. You could add a 'max_smt' attribute to PnvMachineClass to limit
POWER8 to one.


Thanks,

C.




With that,
Reviewed-by: Harsh Prateek Bora 


+
+    pnv_init(machine);
+}
+
+static void pnv_power9_init(MachineState *machine)
+{
+    if (machine->smp.threads > 8) {
+    error_report("Cannot support more than 8 threads/core "
+ "on a powernv9/10 machine");
+    exit(1);
+    }
+
+    pnv_init(machine);
+}
+
+static void pnv_power10_init(MachineState *machine)
+{
+    pnv_power9_init(machine);
+}
+
  /*
   *    0:21  Reserved - Read as zeros
   *   22:24  Chip ID
@@ -2423,6 +2445,7 @@ static void pnv_machine_power8_class_init(ObjectClass 
*oc, void *data)
  };
  mc->desc = "IBM PowerNV (Non-Virtualized) POWER8";
+    mc->init = pnv_power8_init;
  mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power8_v2.0");
  compat_props_add(mc->compat_props, phb_compat, G_N_ELEMENTS(phb_compat));
@@ -2449,6 +2472,7 @@ static void pnv_machine_power9_class_init(ObjectClass 
*oc, void *data)
  };
  mc->desc = "IBM PowerNV (Non-Virtualized) POWER9";
+    mc->init = pnv_power9_init;
  mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power9_v2.2");
  compat_props_add(mc->compat_props, phb_compat, G_N_ELEMENTS(phb_compat));
@@ -2473,6 +2497,7 @@ static void pnv_machine_p10_common_class_init(ObjectClass 
*oc, void *data)
  { TYPE_PNV_PHB_ROOT_PORT, "version", "5" },
  };
+    mc->init = pnv_power10_init;
  mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power10_v2.0");
  compat_props_add(mc->compat_props, phb_compat, G_N_ELEMENTS(phb_compat));





Re: [PATCH v4 05/11] ppc/pnv: Add a Power11 Pnv11Chip, and a Power11 Machine

2024-05-28 Thread Cédric Le Goater

Hello Aditya

On 5/28/24 09:05, Aditya Gupta wrote:

Power11 core is same as Power10, use the existing functionalities to
introduce a Power11 chip and machine, with Power10 chip as parent of
Power11 chip, thus going through similar class_init paths


This patch should come last, after all the POWER11 processor sub-unit
models (HOMER, OCC, LPC) are implemented. Also the POWER11 chip model
lacks an instance_init() handler initializing the chip children to the
correct POWER11 types.

AFAICT, power11-pnv-chip is still using power10 types.

More below,



Cc: Cédric Le Goater 
Cc: Frédéric Barrat 
Cc: Mahesh J Salgaonkar 
Cc: Madhavan Srinivasan 
Cc: Nicholas Piggin 
Signed-off-by: Aditya Gupta 
---
  docs/system/ppc/powernv.rst |   9 +--
  hw/ppc/pnv.c| 120 ++--
  hw/ppc/pnv_core.c   |  11 
  include/hw/ppc/pnv.h|   5 ++
  include/hw/ppc/pnv_chip.h   |   7 +++
  include/hw/ppc/pnv_core.h   |   1 +
  6 files changed, 145 insertions(+), 8 deletions(-)

diff --git a/docs/system/ppc/powernv.rst b/docs/system/ppc/powernv.rst
index 09f39658587d..65606aa767aa 100644
--- a/docs/system/ppc/powernv.rst
+++ b/docs/system/ppc/powernv.rst
@@ -1,5 +1,5 @@
-PowerNV family boards (``powernv8``, ``powernv9``, ``powernv10``)
-==
+PowerNV family boards (``powernv8``, ``powernv9``, ``powernv10``, 
``powernv11``)
+
  
  PowerNV (as Non-Virtualized) is the "bare metal" platform using the

  OPAL firmware. It runs Linux on IBM and OpenPOWER systems and it can
@@ -15,11 +15,12 @@ beyond the scope of what QEMU addresses today.
  Supported devices
  -
  
- * Multi processor support for POWER8, POWER8NVL and POWER9.

+ * Multi processor support for POWER8, POWER8NVL, POWER9, Power10 and Power11.
   * XSCOM, serial communication sideband bus to configure chiplets.
   * Simple LPC Controller.
   * Processor Service Interface (PSI) Controller.
- * Interrupt Controller, XICS (POWER8) and XIVE (POWER9) and XIVE2 (Power10).
+ * Interrupt Controller, XICS (POWER8) and XIVE (POWER9) and XIVE2 (Power10 &
+   Power11).
   * POWER8 PHB3 PCIe Host bridge and POWER9 PHB4 PCIe Host bridge.
   * Simple OCC is an on-chip micro-controller used for power management tasks.
   * iBT device to handle BMC communication, with the internal BMC simulator
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 6e3a5ccdec76..f8270f4b123b 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -456,6 +456,33 @@ static void pnv_chip_power10_dt_populate(PnvChip *chip, 
void *fdt)
  pnv_dt_lpc(chip, fdt, 0, PNV10_LPCM_BASE(chip), PNV10_LPCM_SIZE);
  }
  
+static void pnv_chip_power11_dt_populate(PnvChip *chip, void *fdt)

+{
+static const char compat[] = "ibm,power11-xscom\0ibm,xscom";
+int i;
+
+pnv_dt_xscom(chip, fdt, 0,
+ cpu_to_be64(PNV10_XSCOM_BASE(chip)),
+ cpu_to_be64(PNV10_XSCOM_SIZE),


I wonder if we should not duplicate the PNV10 macros in PNV11. It's minor.


+ compat, sizeof(compat));
+
+for (i = 0; i < chip->nr_cores; i++) {
+PnvCore *pnv_core = chip->cores[i];
+int offset;
+
+offset = pnv_dt_core(chip, pnv_core, fdt);
+
+_FDT((fdt_setprop(fdt, offset, "ibm,pa-features",
+   pa_features_31, sizeof(pa_features_31;
+}
+
+if (chip->ram_size) {
+pnv_dt_memory(fdt, chip->chip_id, chip->ram_start, chip->ram_size);
+}
+
+pnv_dt_lpc(chip, fdt, 0, PNV10_LPCM_BASE(chip), PNV10_LPCM_SIZE);


ditto


+}
+
  static void pnv_dt_rtc(ISADevice *d, void *fdt, int lpc_off)
  {
  uint32_t io_base = d->ioport_id;
@@ -1288,6 +1315,8 @@ static void pnv_chip_power10_intc_print_info(PnvChip 
*chip, PowerPCCPU *cpu,
  
  #define POWER10_CORE_MASK  (0xffull)
  
+#define POWER11_CORE_MASK  (0xffull)

+
  static void pnv_chip_power8_instance_init(Object *obj)
  {
  Pnv8Chip *chip8 = PNV8_CHIP(obj);
@@ -1831,7 +1860,8 @@ static void pnv_chip_power10_instance_init(Object *obj)
  }
  }
  
-static void pnv_chip_power10_quad_realize(Pnv10Chip *chip10, Error **errp)

+static void pnv_chip_power10_quad_realize(Pnv10Chip *chip10, Error **errp,


Rename in pnv_chip_power1x_quad_realize may be ? same below.


+const char *cpu_model)
  {
  PnvChip *chip = PNV_CHIP(chip10);
  int i;
@@ -1841,9 +1871,10 @@ static void pnv_chip_power10_quad_realize(Pnv10Chip 
*chip10, Error **errp)
  
  for (i = 0; i < chip10->nr_quads; i++) {

  PnvQuad *eq = >quads[i];
+g_autofree char *type_name = PNV_QUAD_TYPE_NAME_DYN(cpu_model);


and PNV_QUAD_TYPE_NAME_DYN becomes quite useless now.


Thanks,

C.



  
  pnv_chip_quad_realize_one(chip, eq, chip->cores[i

Re: [PATCH v4 11/11] ppc/pnv: Update skiboot.lid to support Power11

2024-05-28 Thread Cédric Le Goater

On 5/28/24 09:05, Aditya Gupta wrote:

Skiboot/OPAL patches are in discussion upstream [1], with corresponding
commits in github repository [2].

Update skiboot.lid, with binary built from 'upstream_power11' branch
of skiboot repository with Power11 enablement patches [2].

---
This patch can be skipped for now, if need to wait for patches to be
merged in open-power/skiboot. Have updated the skiboot.lid to aid in
testing this patch series.


When is the merge in skiboot planned ? QEMU 9.1 freeze is in ~2 months.

[1]:https://lists.ozlabs.org/pipermail/skiboot/2024-April/018963.html
[2]:https://github.com/maheshsal/skiboot.

Cc: Cédric Le Goater
Cc: Joel Stanley
Cc: Mahesh J Salgaonkar
Cc: Madhavan Srinivasan
Cc: Nicholas Piggin
Signed-off-by: Aditya Gupta
---
  pc-bios/skiboot.lid | Bin 2527328 -> 2527328 bytes


Please don't resend. This is big !

Thanks,

C.







Re: [SPAM] Re: [PATCH v4 09/16] aspeed/smc: Add AST2700 support

2024-05-28 Thread Cédric Le Goater

On 5/27/24 17:58, Philippe Mathieu-Daudé wrote:

Hi,

On 27/5/24 10:02, Jamin Lin wrote:

AST2700 fmc/spi controller's address decoding unit is 64KB
and only bits [31:16] are used for decoding. Introduce seg_to_reg
and reg_to_seg handlers for ast2700 fmc/spi controller.
In addition, adds ast2700 fmc, spi0, spi1, and spi2 class init handler.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Reviewed-by: Cédric Le Goater 
---
  hw/ssi/aspeed_smc.c | 222 +++-
  1 file changed, 220 insertions(+), 2 deletions(-)

diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index df0c63469c..b4006c8339 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -185,7 +185,7 @@
   *   0: 4 bytes
   *   0x1FC: 32M bytes
   *
- * DMA length is from 1 byte to 32MB (AST2600, AST10x0)
+ * DMA length is from 1 byte to 32MB (AST2600, AST10x0 and AST2700)
   *   0: 1 byte
   *   0x1FF: 32M bytes
   */
@@ -670,7 +670,7 @@ static const MemoryRegionOps aspeed_smc_flash_ops = {
  .endianness = DEVICE_LITTLE_ENDIAN,
  .valid = {
  .min_access_size = 1,
-    .max_access_size = 4,
+    .max_access_size = 8,


Is this a bugfix? If so, please use a separate patch. Otherwise
please mention why it is OK to widen access for AST2600 & AST10x0.


Ah I missed that. I wonder how we could set different access width
tough on the model ?

Should we allocate a MemoryRegionOps in the realize() handler and set
the width depending on the SoC ?


Thanks,

C.







Re: [SPAM] Re: [PATCH v4 08/16] aspeed/smc: support 64 bits dma dram address

2024-05-28 Thread Cédric Le Goater

On 5/27/24 18:06, Philippe Mathieu-Daudé wrote:

Hi Jamin,

On 27/5/24 10:02, Jamin Lin wrote:

AST2700 support the maximum dram size is 8GiB
and has a "DMA DRAM Side Address High Part(0x7C)"
register to support 64 bits dma dram address.
Add helper routines functions to compute the dma dram
address, new features and update trace-event
to support 64 bits dram address.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
---
  hw/ssi/aspeed_smc.c | 52 +++--
  hw/ssi/trace-events |  2 +-
  include/hw/ssi/aspeed_smc.h |  1 +
  3 files changed, 46 insertions(+), 9 deletions(-)




+static uint64_t aspeed_smc_dma_dram_addr(AspeedSMCState *s)
+{
+    return s->regs[R_DMA_DRAM_ADDR] |
+    ((uint64_t) s->regs[R_DMA_DRAM_ADDR_HIGH] << 32);
+}
+
  static uint32_t aspeed_smc_dma_len(AspeedSMCState *s)
  {
  AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
@@ -903,24 +921,34 @@ static void aspeed_smc_dma_checksum(AspeedSMCState *s)
  static void aspeed_smc_dma_rw(AspeedSMCState *s)
  {
+    AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
+    uint64_t dma_dram_offset;
+    uint64_t dma_dram_addr;
  MemTxResult result;
  uint32_t dma_len;
  uint32_t data;
  dma_len = aspeed_smc_dma_len(s);
+    dma_dram_addr = aspeed_smc_dma_dram_addr(s);
+
+    if (aspeed_smc_has_dma64(asc)) {
+    dma_dram_offset = dma_dram_addr - s->dram_base;
+    } else {
+    dma_dram_offset = dma_dram_addr;


Here s->dram_base is 0x0. Do we really need to check
aspeed_smc_has_dma64?


You are right, it could be done as your proposal below. However,
we should add a comment regarding some values :

R_DMA_DRAM_ADDR_HIGH and s->dram_base are only set on the AST2700
SoC and zero on other Aspeed SoCs.


+    }


Maybe simplify improving aspeed_smc_dma_dram_addr() as:

   static uint64_t aspeed_smc_dma_dram_addr(AspeedSMCState *s)
   {
   return (s->regs[R_DMA_DRAM_ADDR]
   | ((uint64_t) s->regs[R_DMA_DRAM_ADDR_HIGH] << 32))
   - s->dram_base;
   }

Then no need for dma_dram_offset, dma_dram_addr is enough.


we need both, dma_dram_offset for the transaction and dma_dram_addr
to update the R_DMA_DRAM_ADDR_HIGH reg. A bit cumbersome, I agree.

Thanks,

C.





  trace_aspeed_smc_dma_rw(s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE ?
  "write" : "read",
  s->regs[R_DMA_FLASH_ADDR],
-    s->regs[R_DMA_DRAM_ADDR],
+    dma_dram_offset,
  dma_len);
  while (dma_len) {
  if (s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE) {
-    data = address_space_ldl_le(>dram_as, s->regs[R_DMA_DRAM_ADDR],
+    data = address_space_ldl_le(>dram_as, dma_dram_offset,
  MEMTXATTRS_UNSPECIFIED, );
  if (result != MEMTX_OK) {
-    aspeed_smc_error("DRAM read failed @%08x",
- s->regs[R_DMA_DRAM_ADDR]);
+    aspeed_smc_error("DRAM read failed @%" PRIx64,
+ dma_dram_offset);
  return;
  }
@@ -940,11 +968,11 @@ static void aspeed_smc_dma_rw(AspeedSMCState *s)
  return;
  }
-    address_space_stl_le(>dram_as, s->regs[R_DMA_DRAM_ADDR],
+    address_space_stl_le(>dram_as, dma_dram_offset,
   data, MEMTXATTRS_UNSPECIFIED, );
  if (result != MEMTX_OK) {
-    aspeed_smc_error("DRAM write failed @%08x",
- s->regs[R_DMA_DRAM_ADDR]);
+    aspeed_smc_error("DRAM write failed @%" PRIx64,
+ dma_dram_offset);
  return;
  }
  }
@@ -953,8 +981,12 @@ static void aspeed_smc_dma_rw(AspeedSMCState *s)
   * When the DMA is on-going, the DMA registers are updated
   * with the current working addresses and length.
   */
+    dma_dram_offset += 4;
+    dma_dram_addr += 4;
+
+    s->regs[R_DMA_DRAM_ADDR_HIGH] = dma_dram_addr >> 32;
+    s->regs[R_DMA_DRAM_ADDR] = dma_dram_addr & 0x;
  s->regs[R_DMA_FLASH_ADDR] += 4;
-    s->regs[R_DMA_DRAM_ADDR] += 4;
  dma_len -= 4;
  s->regs[R_DMA_LEN] = dma_len;
  s->regs[R_DMA_CHECKSUM] += data;
@@ -1107,6 +1139,9 @@ static void aspeed_smc_write(void *opaque, hwaddr addr, 
uint64_t data,
  } else if (aspeed_smc_has_dma(asc) && addr == R_DMA_LEN &&
 aspeed_smc_dma_granted(s)) {
  s->regs[addr] = DMA_LENGTH(value);
+    } else if (aspeed_smc_has_dma(asc) && aspeed_smc_has_dma64(asc) &&
+   addr == R_DMA_DRAM_ADDR_HIGH) {
+    s->regs[addr] = DMA_DRAM_ADDR_HIGH(value);
  } else {
  qemu_log_mask(LOG_UNIMP, "%s: not implemented: 0x%" HWADDR_PRIx "\n",
    __func__, addr);
@@ -1239,6 +1274,7 @@ 

Re: [PATCH v4 08/16] aspeed/smc: support 64 bits dma dram address

2024-05-28 Thread Cédric Le Goater

On 5/28/24 03:34, Jamin Lin wrote:

Hi Cedric,


On 5/27/24 10:02, Jamin Lin wrote:

AST2700 support the maximum dram size is 8GiB and has a "DMA DRAM

Side

Address High Part(0x7C)"
register to support 64 bits dma dram address.
Add helper routines functions to compute the dma dram address, new
features and update trace-event to support 64 bits dram address.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 


I will move the addition of the "dram-base" property to another patch. See :

https://patchew.org/QEMU/20240527124315.35356-1-...@redhat.com/

(Please review)

Review done.
If I need to resend v5 patch series, I will remove "dram-base property" from 
this patch.


ok. Wait a bit before resending though. We are not done with v4 yet !

Thanks,

C.



Thanks for your help, Jamin





Else,

Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
   hw/ssi/aspeed_smc.c | 52

+++--

   hw/ssi/trace-events |  2 +-
   include/hw/ssi/aspeed_smc.h |  1 +
   3 files changed, 46 insertions(+), 9 deletions(-)

diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c index
ffb13a12e8..df0c63469c 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -132,6 +132,9 @@
   #define   FMC_WDT2_CTRL_BOOT_SOURCE  BIT(4) /* O: primary

1: alternate */

   #define   FMC_WDT2_CTRL_EN   BIT(0)

+/* DMA DRAM Side Address High Part (AST2700) */
+#define R_DMA_DRAM_ADDR_HIGH   (0x7c / 4)
+
   /* DMA Control/Status Register */
   #define R_DMA_CTRL(0x80 / 4)
   #define   DMA_CTRL_REQUEST  (1 << 31)
@@ -187,6 +190,7 @@
*   0x1FF: 32M bytes
*/
   #define DMA_DRAM_ADDR(asc, val)   ((val) & (asc)->dma_dram_mask)
+#define DMA_DRAM_ADDR_HIGH(val)   ((val) & 0xf)
   #define DMA_FLASH_ADDR(asc, val)  ((val) & (asc)->dma_flash_mask)
   #define DMA_LENGTH(val) ((val) & 0x01FF)

@@ -207,6 +211,7 @@ static const AspeedSegments

aspeed_2500_spi2_segments[];

   #define ASPEED_SMC_FEATURE_DMA   0x1
   #define ASPEED_SMC_FEATURE_DMA_GRANT 0x2
   #define ASPEED_SMC_FEATURE_WDT_CONTROL 0x4
+#define ASPEED_SMC_FEATURE_DMA_DRAM_ADDR_HIGH 0x08

   static inline bool aspeed_smc_has_dma(const AspeedSMCClass *asc)
   {
@@ -218,6 +223,11 @@ static inline bool

aspeed_smc_has_wdt_control(const AspeedSMCClass *asc)

   return !!(asc->features & ASPEED_SMC_FEATURE_WDT_CONTROL);
   }

+static inline bool aspeed_smc_has_dma64(const AspeedSMCClass *asc) {
+return !!(asc->features &

ASPEED_SMC_FEATURE_DMA_DRAM_ADDR_HIGH);

+}
+
   #define aspeed_smc_error(fmt, ...)

\

   qemu_log_mask(LOG_GUEST_ERROR, "%s: " fmt "\n", __func__, ##
__VA_ARGS__)

@@ -747,6 +757,8 @@ static uint64_t aspeed_smc_read(void *opaque,

hwaddr addr, unsigned int size)

   (aspeed_smc_has_dma(asc) && addr == R_DMA_CTRL) ||
   (aspeed_smc_has_dma(asc) && addr == R_DMA_FLASH_ADDR)

||

   (aspeed_smc_has_dma(asc) && addr == R_DMA_DRAM_ADDR)

||

+(aspeed_smc_has_dma(asc) && aspeed_smc_has_dma64(asc)

&&

+ addr == R_DMA_DRAM_ADDR_HIGH) ||
   (aspeed_smc_has_dma(asc) && addr == R_DMA_LEN) ||
   (aspeed_smc_has_dma(asc) && addr == R_DMA_CHECKSUM)

||

   (addr >= R_SEG_ADDR0 &&
@@ -847,6 +859,12 @@ static bool

aspeed_smc_inject_read_failure(AspeedSMCState *s)

   }
   }

+static uint64_t aspeed_smc_dma_dram_addr(AspeedSMCState *s) {
+return s->regs[R_DMA_DRAM_ADDR] |
+((uint64_t) s->regs[R_DMA_DRAM_ADDR_HIGH] << 32); }
+
   static uint32_t aspeed_smc_dma_len(AspeedSMCState *s)
   {
   AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s); @@ -903,24
+921,34 @@ static void aspeed_smc_dma_checksum(AspeedSMCState *s)

   static void aspeed_smc_dma_rw(AspeedSMCState *s)
   {
+AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
+uint64_t dma_dram_offset;
+uint64_t dma_dram_addr;
   MemTxResult result;
   uint32_t dma_len;
   uint32_t data;

   dma_len = aspeed_smc_dma_len(s);
+dma_dram_addr = aspeed_smc_dma_dram_addr(s);
+
+if (aspeed_smc_has_dma64(asc)) {
+dma_dram_offset = dma_dram_addr - s->dram_base;
+} else {
+dma_dram_offset = dma_dram_addr;
+}

   trace_aspeed_smc_dma_rw(s->regs[R_DMA_CTRL] &

DMA_CTRL_WRITE ?

   "write" : "read",
   s->regs[R_DMA_FLASH_ADDR],
-s->regs[R_DMA_DRAM_ADDR],
+dma_dram_offset,
   dma_len);
   while (dma_len) {
   if (s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE) {
-data = address_space_ldl_le(>dram_as,

s->regs[R_DMA_DRAM_ADDR],

+data = address_space_ldl_le(>dram_as,

dma_dram_offset,



MEMTXATTRS_UNSPECIFIED, );

 

Re: [PATCH v4 05/16] aspeed/sdmc: Add AST2700 support

2024-05-28 Thread Cédric Le Goater

On 5/28/24 03:26, Jamin Lin wrote:

Hi Philippe, Cedric


On 27/5/24 13:18, Cédric Le Goater wrote:

On 5/27/24 12:24, Philippe Mathieu-Daudé wrote:

Hi Jamin,

On 27/5/24 10:02, Jamin Lin wrote:

The SDRAM memory controller(DRAMC) controls the access to external
DDR4 and DDR5 SDRAM and power up to DDR4 and DDR5 PHY.

The DRAM memory controller of AST2700 is not backward compatible to
previous chips such AST2600, AST2500 and AST2400.

Max memory is now 8GiB on the AST2700. Introduce new
aspeed_2700_sdmc and class with read/write operation and reset
handlers.

Define DRAMC necessary protected registers and unprotected registers
for AST2700 and increase the register set to 0x1000.

Add unlocked property to change controller protected status.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Reviewed-by: Cédric Le Goater 
---
   hw/misc/aspeed_sdmc.c | 190
+-
   include/hw/misc/aspeed_sdmc.h |   5 +-
   2 files changed, 193 insertions(+), 2 deletions(-)




diff --git a/include/hw/misc/aspeed_sdmc.h
b/include/hw/misc/aspeed_sdmc.h index ec2d59a14f..61c979583a 100644
--- a/include/hw/misc/aspeed_sdmc.h
+++ b/include/hw/misc/aspeed_sdmc.h
@@ -17,6 +17,7 @@ OBJECT_DECLARE_TYPE(AspeedSDMCState,
AspeedSDMCClass, ASPEED_SDMC)
   #define TYPE_ASPEED_2400_SDMC TYPE_ASPEED_SDMC "-ast2400"
   #define TYPE_ASPEED_2500_SDMC TYPE_ASPEED_SDMC "-ast2500"
   #define TYPE_ASPEED_2600_SDMC TYPE_ASPEED_SDMC "-ast2600"
+#define TYPE_ASPEED_2700_SDMC TYPE_ASPEED_SDMC "-ast2700"
   /*
    * SDMC has 174 documented registers. In addition the u-boot
device tree @@ -29,7 +30,7 @@

OBJECT_DECLARE_TYPE(AspeedSDMCState,

AspeedSDMCClass, ASPEED_SDMC)
    * time, and the other is in the DDR-PHY IP which is used during
DDR-PHY
    * training.
    */
-#define ASPEED_SDMC_NR_REGS (0x500 >> 2)
+#define ASPEED_SDMC_NR_REGS (0x1000 >> 2)


This change breaks the migration stream.


Do you mean migration compat ? We never cared much about that for the
Aspeed machines.


So let's just remove the VMSTATE to reduce code burden?

Otherwise incrementing the vmstate.version is enough.

Regards,

Phil.

If you both okay, I will remove it.
Do I need to create a new patch or just update in this patch?


I don't think this is necessary to do so now. Possibly, increase the
version number in the vmstate when resending a v5.

Also, all Aspeed models should be addressed and that's beyond the scope
of this series.


Thanks,

C.





Re: [RFC PATCH 01/10] ppc/pnv: Add pointer from PnvCPUState to PnvCore

2024-05-27 Thread Cédric Le Goater

On 5/26/24 14:26, Nicholas Piggin wrote:

This helps move core state from CPU to core structures.

Signed-off-by: Nicholas Piggin 
---
  include/hw/ppc/pnv_core.h | 1 +
  hw/ppc/pnv_core.c | 3 +++
  2 files changed, 4 insertions(+)

diff --git a/include/hw/ppc/pnv_core.h b/include/hw/ppc/pnv_core.h
index c6d62fd145..30c1e5b1a3 100644
--- a/include/hw/ppc/pnv_core.h
+++ b/include/hw/ppc/pnv_core.h
@@ -54,6 +54,7 @@ struct PnvCoreClass {
  #define PNV_CORE_TYPE_NAME(cpu_model) cpu_model PNV_CORE_TYPE_SUFFIX
  
  typedef struct PnvCPUState {

+PnvCore *core;
  Object *intc;
  } PnvCPUState;
  
diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c

index f40ab721d6..7b0ea7812b 100644
--- a/hw/ppc/pnv_core.c
+++ b/hw/ppc/pnv_core.c
@@ -225,6 +225,7 @@ static const MemoryRegionOps pnv_core_power10_xscom_ops = {
  static void pnv_core_cpu_realize(PnvCore *pc, PowerPCCPU *cpu, Error **errp,
   int thread_index)
  {
+PnvCPUState *pnv_cpu = pnv_cpu_state(cpu);
  CPUPPCState *env = >env;
  int core_hwid;
  ppc_spr_t *pir = >spr_cb[SPR_PIR];
@@ -232,6 +233,8 @@ static void pnv_core_cpu_realize(PnvCore *pc, PowerPCCPU 
*cpu, Error **errp,
  Error *local_err = NULL;
  PnvChipClass *pcc = PNV_CHIP_GET_CLASS(pc->chip);
  
+pnv_cpu->core = pc;


I would do the assignment in pnv_core_realize() after cpu->machine_data is
allocated. it's minor.


Reviewed-by: Cédric Le Goater 

Thanks,

C.



  if (!qdev_realize(DEVICE(cpu), NULL, errp)) {
  return;
  }





Re: [PATCH v3 05/11] ppc/pnv: Add a Power11 Pnv11Chip, and a Power11 Machine

2024-05-27 Thread Cédric Le Goater

On 5/27/24 09:10, Aditya Gupta wrote:

Power11 core is same as Power10, use the existing functionalities to
introduce a Power11 chip and machine, with Power10 chip as parent of
Power11 chip, thus going through similar class_init paths

Cc: Cédric Le Goater 
Cc: Frédéric Barrat 
Cc: Mahesh J Salgaonkar 
Cc: Madhavan Srinivasan 
Cc: Nicholas Piggin 
Signed-off-by: Aditya Gupta 
---
  docs/system/ppc/powernv.rst |   9 +--
  hw/ppc/pnv.c| 119 ++--
  hw/ppc/pnv_core.c   |  11 
  include/hw/ppc/pnv.h|   5 ++
  include/hw/ppc/pnv_chip.h   |   7 +++
  include/hw/ppc/pnv_core.h   |   1 +
  6 files changed, 144 insertions(+), 8 deletions(-)

diff --git a/docs/system/ppc/powernv.rst b/docs/system/ppc/powernv.rst
index 09f39658587d..65606aa767aa 100644
--- a/docs/system/ppc/powernv.rst
+++ b/docs/system/ppc/powernv.rst
@@ -1,5 +1,5 @@
-PowerNV family boards (``powernv8``, ``powernv9``, ``powernv10``)
-==
+PowerNV family boards (``powernv8``, ``powernv9``, ``powernv10``, 
``powernv11``)
+
  
  PowerNV (as Non-Virtualized) is the "bare metal" platform using the

  OPAL firmware. It runs Linux on IBM and OpenPOWER systems and it can
@@ -15,11 +15,12 @@ beyond the scope of what QEMU addresses today.
  Supported devices
  -
  
- * Multi processor support for POWER8, POWER8NVL and POWER9.

+ * Multi processor support for POWER8, POWER8NVL, POWER9, Power10 and Power11.
   * XSCOM, serial communication sideband bus to configure chiplets.
   * Simple LPC Controller.
   * Processor Service Interface (PSI) Controller.
- * Interrupt Controller, XICS (POWER8) and XIVE (POWER9) and XIVE2 (Power10).
+ * Interrupt Controller, XICS (POWER8) and XIVE (POWER9) and XIVE2 (Power10 &
+   Power11).
   * POWER8 PHB3 PCIe Host bridge and POWER9 PHB4 PCIe Host bridge.
   * Simple OCC is an on-chip micro-controller used for power management tasks.
   * iBT device to handle BMC communication, with the internal BMC simulator
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 6e3a5ccdec76..939163f91784 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -456,6 +456,33 @@ static void pnv_chip_power10_dt_populate(PnvChip *chip, 
void *fdt)
  pnv_dt_lpc(chip, fdt, 0, PNV10_LPCM_BASE(chip), PNV10_LPCM_SIZE);
  }
  
+static void pnv_chip_power11_dt_populate(PnvChip *chip, void *fdt)

+{
+static const char compat[] = "ibm,power11-xscom\0ibm,xscom";
+int i;
+
+pnv_dt_xscom(chip, fdt, 0,
+ cpu_to_be64(PNV10_XSCOM_BASE(chip)),
+ cpu_to_be64(PNV10_XSCOM_SIZE),
+ compat, sizeof(compat));
+
+for (i = 0; i < chip->nr_cores; i++) {
+PnvCore *pnv_core = chip->cores[i];
+int offset;
+
+offset = pnv_dt_core(chip, pnv_core, fdt);
+
+_FDT((fdt_setprop(fdt, offset, "ibm,pa-features",
+   pa_features_31, sizeof(pa_features_31;
+}
+
+if (chip->ram_size) {
+pnv_dt_memory(fdt, chip->chip_id, chip->ram_start, chip->ram_size);
+}
+
+pnv_dt_lpc(chip, fdt, 0, PNV10_LPCM_BASE(chip), PNV10_LPCM_SIZE);
+}
+
  static void pnv_dt_rtc(ISADevice *d, void *fdt, int lpc_off)
  {
  uint32_t io_base = d->ioport_id;
@@ -1288,6 +1315,8 @@ static void pnv_chip_power10_intc_print_info(PnvChip 
*chip, PowerPCCPU *cpu,
  
  #define POWER10_CORE_MASK  (0xffull)
  
+#define POWER11_CORE_MASK  (0xffull)

+
  static void pnv_chip_power8_instance_init(Object *obj)
  {
  Pnv8Chip *chip8 = PNV8_CHIP(obj);
@@ -1831,7 +1860,8 @@ static void pnv_chip_power10_instance_init(Object *obj)
  }
  }
  
-static void pnv_chip_power10_quad_realize(Pnv10Chip *chip10, Error **errp)

+static void pnv_chip_power10_quad_realize(Pnv10Chip *chip10, Error **errp,
+const char *cpu_model)
  {
  PnvChip *chip = PNV_CHIP(chip10);
  int i;
@@ -1843,7 +1873,7 @@ static void pnv_chip_power10_quad_realize(Pnv10Chip 
*chip10, Error **errp)
  PnvQuad *eq = >quads[i];
  
  pnv_chip_quad_realize_one(chip, eq, chip->cores[i * 4],

-  PNV_QUAD_TYPE_NAME("power10"));
+  PNV_QUAD_TYPE_NAME_DYN(cpu_model));
  
  pnv_xscom_add_subregion(chip, PNV10_XSCOM_EQ_BASE(eq->quad_id),

  >xscom_regs);
@@ -1881,7 +1911,8 @@ static void pnv_chip_power10_phb_realize(PnvChip *chip, 
Error **errp)
  }
  }
  
-static void pnv_chip_power10_realize(DeviceState *dev, Error **errp)

+static void pnv_chip_power10_common_realize(DeviceState *dev, Error **errp,
+const char *cpu_model)
  {
  PnvChipClass *pcc = PNV_CHIP_GET_CLASS(dev);
  PnvChip *chip = PNV_CHIP(dev);
@@ -1898,7 +1929,7 @@ static

Re: [PATCH] vfio: container: Fix missing allocation of VFIOSpaprContainer

2024-05-27 Thread Cédric Le Goater

On 5/22/24 18:15, Shivaprasad G Bhat wrote:

On 5/13/24 17:53, Cédric Le Goater wrote:

Hello Shivaprasad,

On 5/9/24 21:14, Shivaprasad G Bhat wrote:

The commit 6ad359ec29 "(vfio/spapr: Move prereg_listener into
spapr container)" began to use the newly introduced VFIOSpaprContainer
structure.

After several refactors, today the container_of(container,
VFIOSpaprContainer, ABC) is used when VFIOSpaprContainer is actually
not allocated. On PPC64 systems, this dereference is leading to corruption
showing up as glibc malloc assertion during guest start when using vfio.

Patch adds the missing allocation while also making the structure movement
to vfio common header file.

Fixes: 6ad359ec29 "(vfio/spapr: Move prereg_listener into spapr container)"
Signed-off-by: Shivaprasad G Bhat 
---
  hw/vfio/container.c   |    6 --
  hw/vfio/spapr.c   |    6 --
  include/hw/vfio/vfio-common.h |    6 ++
  3 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/hw/vfio/container.c b/hw/vfio/container.c
index 77bdec276e..ecaf5786d9 100644
--- a/hw/vfio/container.c
+++ b/hw/vfio/container.c
@@ -539,6 +539,7 @@ static int vfio_connect_container(VFIOGroup *group, 
AddressSpace *as,
  {
  VFIOContainer *container;
  VFIOContainerBase *bcontainer;
+    VFIOSpaprContainer *scontainer;


We should do our best to avoid any direct use of ppc related attributes
in the common VFIO code. This comment also applies to VFIO_SPAPR_TCE*
which are still there because the clean up is not finished. So, this
proposal will have to be reworked.


Sure.

The first step is to finish the QOMification of VFIOContainer, so
that the VFIOContainer instance is created in vfio_connect_container()
with :

    container = qdev_new(iommu_type_name);


This requires the VFIOContainer to be a DeviceState object.

The existing base class TYPE_VFIO_IOMMU is an InterfaceClass.

I attempted VFIOContainer object declaration with TYPE_VFIO_IOMMU,

like

OBJECT_DECLARE_SIMPLE_TYPE(VFIOContainer, VFIO_IOMMU_LEGACY)




This means reworking this part (and vfio_set_iommu()) :

    ...
    container = g_malloc0(sizeof(*container));
    container->fd = fd;
    bcontainer = >bcontainer;

    if (!vfio_set_iommu(container, group->fd, space, errp)) {
    goto free_container_exit;
    }
    ...

VFIOSpaprContainer can then implement its own .init_instance() handler
to allocate/initialize attributes required by the pseries machines.



With my above changes,

I see the instance_init() is not supported for the InterfaceClass with the



Yes. We need an Object, hence my remark on "QOMification of VFIOContainer".
VFIOContainerBase needs to be reworked.

Thanks,

C.



checks from below

commit 422ca1432f7b44f2a9f3ad94a65d36927da021fa
Author: Marc-André Lureau 
Date:   Wed Sep 12 16:53:03 2018 +0400

     qom/object: add some interface asserts

Did you suggest me something else?







Thank you,

Shivaprasad



While doing this, please try to reduce the use of ->iommu_type which
is a design shortcut. I would like to completely remove it at some
point.

Thanks,

C.








  int ret, fd;
  VFIOAddressSpace *space;

@@ -611,7 +612,8 @@ static int vfio_connect_container(VFIOGroup *group, 
AddressSpace *as,
  goto close_fd_exit;
  }

-    container = g_malloc0(sizeof(*container));
+    scontainer = g_malloc0(sizeof(*scontainer));
+    container = >container;
  container->fd = fd;
  bcontainer = >bcontainer;

@@ -675,7 +677,7 @@ unregister_container_exit:
  vfio_cpr_unregister_container(bcontainer);

  free_container_exit:
-    g_free(container);
+    g_free(scontainer);

  close_fd_exit:
  close(fd);
diff --git a/hw/vfio/spapr.c b/hw/vfio/spapr.c
index 0d949bb728..78d218b7e7 100644
--- a/hw/vfio/spapr.c
+++ b/hw/vfio/spapr.c
@@ -24,12 +24,6 @@
  #include "qapi/error.h"
  #include "trace.h"

-typedef struct VFIOSpaprContainer {
-    VFIOContainer container;
-    MemoryListener prereg_listener;
-    QLIST_HEAD(, VFIOHostDMAWindow) hostwin_list;
-} VFIOSpaprContainer;
-
  static bool vfio_prereg_listener_skipped_section(MemoryRegionSection *section)
  {
  if (memory_region_is_iommu(section->mr)) {
diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index b9da6c08ef..010fa68ac6 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -82,6 +82,12 @@ typedef struct VFIOContainer {
  QLIST_HEAD(, VFIOGroup) group_list;
  } VFIOContainer;

+typedef struct VFIOSpaprContainer {
+    VFIOContainer container;
+    MemoryListener prereg_listener;
+    QLIST_HEAD(, VFIOHostDMAWindow) hostwin_list;
+} VFIOSpaprContainer;
+
  typedef struct VFIOHostDMAWindow {
  hwaddr min_iova;
  hwaddr max_iova;









Re: [PATCH v5 19/19] intel_iommu: Check compatibility with host IOMMU capabilities

2024-05-27 Thread Cédric Le Goater

On 5/8/24 11:03, Zhenzhong Duan wrote:

If check fails, host device (either VFIO or VDPA device) is not
compatible with current vIOMMU config and should not be passed to
guest.

Only aw_bits is checked for now, we don't care other capabilities
before scalable modern mode is introduced.

Signed-off-by: Yi Liu 
Signed-off-by: Zhenzhong Duan 
---
  hw/i386/intel_iommu.c | 27 +++
  1 file changed, 27 insertions(+)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 747c988bc4..07bfd4f99e 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -20,6 +20,7 @@
   */
  
  #include "qemu/osdep.h"

+#include CONFIG_DEVICES /* CONFIG_HOST_IOMMU_DEVICE */
  #include "qemu/error-report.h"
  #include "qemu/main-loop.h"
  #include "qapi/error.h"
@@ -3819,6 +3820,26 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, 
PCIBus *bus,
  return vtd_dev_as;
  }
  
+static bool vtd_check_hdev(IntelIOMMUState *s, VTDHostIOMMUDevice *vtd_hdev,

+   Error **errp)
+{
+#ifdef CONFIG_HOST_IOMMU_DEVICE
+HostIOMMUDevice *hiod = vtd_hdev->dev;
+int ret;
+
+/* Common checks */
+ret = host_iommu_device_get_cap(hiod, HOST_IOMMU_DEVICE_CAP_AW_BITS, errp);


To avoid CONFIG_HOST_IOMMU_DEVICE, host_iommu_device_get_cap() could be
open coded.


+if (ret < 0) {
+return false;
+}
+if (s->aw_bits > ret) {
+error_setg(errp, "aw-bits %d > host aw-bits %d", s->aw_bits, ret);
+return false;
+}
+#endif
+return true;
+}
+
  static bool vtd_dev_set_iommu_device(PCIBus *bus, void *opaque, int devfn,
   HostIOMMUDevice *hiod, Error **errp)
  {
@@ -3848,6 +3869,12 @@ static bool vtd_dev_set_iommu_device(PCIBus *bus, void 
*opaque, int devfn,
  vtd_hdev->iommu_state = s;
  vtd_hdev->dev = hiod;
  
+if (!vtd_check_hdev(s, vtd_hdev, errp)) {

+g_free(vtd_hdev);
+vtd_iommu_unlock(s);
+return false;
+}


This check could be first done before allocating vtd_hdev.


Thanks,

C.




  new_key = g_malloc(sizeof(*new_key));
  new_key->bus = bus;
  new_key->devfn = devfn;





Re: [PATCH v5 01/19] backends: Introduce HostIOMMUDevice abstract

2024-05-27 Thread Cédric Le Goater

On 5/13/24 12:28, Duan, Zhenzhong wrote:

Hi Cédric,


-Original Message-
From: Cédric Le Goater 
Subject: Re: [PATCH v5 01/19] backends: Introduce HostIOMMUDevice
abstract

Hello Zhenzhong,

On 5/8/24 11:03, Zhenzhong Duan wrote:

Introduce HostIOMMUDevice as an abstraction of host IOMMU device.

Introduce .realize() to initialize HostIOMMUDevice further after
instance init.

Introduce a macro CONFIG_HOST_IOMMU_DEVICE to define the usage
for VFIO, and VDPA in the future.


This looks like a way to work around some other problem, like
avoiding exposing Linux definitions on windows build.


Yes, I have used this MACRO in patch19 to fix build failure on windows.
Also need change HostIOMMUDeviceCaps::type to be uint32_t type.


Routine host_iommu_device_get_cap() could be open coded in vtd_check_hdev()
to avoid CONFIG_HOST_IOMMU_DEVICE.

Thanks,

C.







Thanks,

C.






Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 
---
   MAINTAINERS|  2 ++
   include/sysemu/host_iommu_device.h | 51

++

   backends/host_iommu_device.c   | 30 ++
   backends/Kconfig   |  5 +++
   backends/meson.build   |  1 +
   5 files changed, 89 insertions(+)
   create mode 100644 include/sysemu/host_iommu_device.h
   create mode 100644 backends/host_iommu_device.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 84391777db..5dab60bd04 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2191,6 +2191,8 @@ M: Zhenzhong Duan



   S: Supported
   F: backends/iommufd.c
   F: include/sysemu/iommufd.h
+F: backends/host_iommu_device.c
+F: include/sysemu/host_iommu_device.h
   F: include/qemu/chardev_open.h
   F: util/chardev_open.c
   F: docs/devel/vfio-iommufd.rst
diff --git a/include/sysemu/host_iommu_device.h

b/include/sysemu/host_iommu_device.h

new file mode 100644
index 00..2b58a94d62
--- /dev/null
+++ b/include/sysemu/host_iommu_device.h
@@ -0,0 +1,51 @@
+/*
+ * Host IOMMU device abstract declaration
+ *
+ * Copyright (C) 2024 Intel Corporation.
+ *
+ * Authors: Zhenzhong Duan 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#ifndef HOST_IOMMU_DEVICE_H
+#define HOST_IOMMU_DEVICE_H
+
+#include "qom/object.h"
+#include "qapi/error.h"
+
+#define TYPE_HOST_IOMMU_DEVICE "host-iommu-device"
+OBJECT_DECLARE_TYPE(HostIOMMUDevice, HostIOMMUDeviceClass,

HOST_IOMMU_DEVICE)

+
+struct HostIOMMUDevice {
+Object parent_obj;
+};
+
+/**
+ * struct HostIOMMUDeviceClass - The base class for all host IOMMU

devices.

+ *
+ * Different type of host devices (e.g., VFIO or VDPA device) or devices
+ * with different backend (e.g., VFIO legacy container or IOMMUFD

backend)

+ * can have different sub-classes.
+ */
+struct HostIOMMUDeviceClass {
+ObjectClass parent_class;
+
+/**
+ * @realize: initialize host IOMMU device instance further.
+ *
+ * Mandatory callback.
+ *
+ * @hiod: pointer to a host IOMMU device instance.
+ *
+ * @opaque: pointer to agent device of this host IOMMU device,
+ *  i.e., for VFIO, pointer to VFIODevice
+ *
+ * @errp: pass an Error out when realize fails.
+ *
+ * Returns: true on success, false on failure.
+ */
+bool (*realize)(HostIOMMUDevice *hiod, void *opaque, Error **errp);
+};
+#endif
diff --git a/backends/host_iommu_device.c

b/backends/host_iommu_device.c

new file mode 100644
index 00..41f2fdce20
--- /dev/null
+++ b/backends/host_iommu_device.c
@@ -0,0 +1,30 @@
+/*
+ * Host IOMMU device abstract
+ *
+ * Copyright (C) 2024 Intel Corporation.
+ *
+ * Authors: Zhenzhong Duan 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "sysemu/host_iommu_device.h"
+
+OBJECT_DEFINE_ABSTRACT_TYPE(HostIOMMUDevice,
+host_iommu_device,
+HOST_IOMMU_DEVICE,
+OBJECT)
+
+static void host_iommu_device_class_init(ObjectClass *oc, void *data)
+{
+}
+
+static void host_iommu_device_init(Object *obj)
+{
+}
+
+static void host_iommu_device_finalize(Object *obj)
+{
+}
diff --git a/backends/Kconfig b/backends/Kconfig
index 2cb23f62fa..34ab29e994 100644
--- a/backends/Kconfig
+++ b/backends/Kconfig
@@ -3,3 +3,8 @@ source tpm/Kconfig
   config IOMMUFD
   bool
   depends on VFIO
+
+config HOST_IOMMU_DEVICE
+bool
+default y
+depends on VFIO
diff --git a/backends/meson.build b/backends/meson.build
index 8b2b111497..2e975d641e 100644
--- a/backends/meson.build
+++ b/backends/meson.build
@@ -25,6 +25,7 @@ if have_vhost_user
   endif
   system_ss.add(when: 'CONFIG_VIRTIO_CRYPTO', if_true: files('cryptodev-

vhost.c'))

   system_ss.add(when: 'CONFIG_IOMMUFD', if_true: files('iommufd.c'))
+syste

Re: [PATCH v4 07/16] aspeed/smc: support dma start length and 1 byte length unit

2024-05-27 Thread Cédric Le Goater

On 5/27/24 10:02, Jamin Lin wrote:

DMA length is from 1 byte to 32MB for AST2600 and AST10x0
and DMA length is from 4 bytes to 32MB for AST2500.

In other words, if "R_DMA_LEN" is 0, it should move at least 1 byte
data for AST2600 and AST10x0 and 4 bytes data for AST2500.
To support all ASPEED SOCs, adds dma_start_length parameter to store
the start length, add helper routines function to compute the dma length
and update DMA_LENGTH mask to "1FF" to support dma 1 byte
length unit for AST2600 and AST1030.
Currently, only supports dma length 4 bytes aligned.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 



Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  hw/ssi/aspeed_smc.c | 43 ++---
  include/hw/ssi/aspeed_smc.h |  1 +
  2 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index 8a8d77b480..ffb13a12e8 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -178,13 +178,17 @@
   * DMA flash addresses should be 4 bytes aligned and the valid address
   * range is 0x2000 - 0x2FFF.
   *
- * DMA length is from 4 bytes to 32MB
+ * DMA length is from 4 bytes to 32MB (AST2500)
   *   0: 4 bytes
- *   0x7F: 32M bytes
+ *   0x1FC: 32M bytes
+ *
+ * DMA length is from 1 byte to 32MB (AST2600, AST10x0)
+ *   0: 1 byte
+ *   0x1FF: 32M bytes
   */
  #define DMA_DRAM_ADDR(asc, val)   ((val) & (asc)->dma_dram_mask)
  #define DMA_FLASH_ADDR(asc, val)  ((val) & (asc)->dma_flash_mask)
-#define DMA_LENGTH(val) ((val) & 0x01FC)
+#define DMA_LENGTH(val) ((val) & 0x01FF)
  
  /* Flash opcodes. */

  #define SPI_OP_READ   0x03/* Read data bytes (low frequency) */
@@ -843,6 +847,13 @@ static bool aspeed_smc_inject_read_failure(AspeedSMCState 
*s)
  }
  }
  
+static uint32_t aspeed_smc_dma_len(AspeedSMCState *s)

+{
+AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
+
+return QEMU_ALIGN_UP(s->regs[R_DMA_LEN] + asc->dma_start_length, 4);
+}
+
  /*
   * Accumulate the result of the reads to provide a checksum that will
   * be used to validate the read timing settings.
@@ -850,6 +861,7 @@ static bool aspeed_smc_inject_read_failure(AspeedSMCState 
*s)
  static void aspeed_smc_dma_checksum(AspeedSMCState *s)
  {
  MemTxResult result;
+uint32_t dma_len;
  uint32_t data;
  
  if (s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE) {

@@ -861,7 +873,9 @@ static void aspeed_smc_dma_checksum(AspeedSMCState *s)
  aspeed_smc_dma_calibration(s);
  }
  
-while (s->regs[R_DMA_LEN]) {

+dma_len = aspeed_smc_dma_len(s);
+
+while (dma_len) {
  data = address_space_ldl_le(>flash_as, s->regs[R_DMA_FLASH_ADDR],
  MEMTXATTRS_UNSPECIFIED, );
  if (result != MEMTX_OK) {
@@ -877,7 +891,8 @@ static void aspeed_smc_dma_checksum(AspeedSMCState *s)
   */
  s->regs[R_DMA_CHECKSUM] += data;
  s->regs[R_DMA_FLASH_ADDR] += 4;
-s->regs[R_DMA_LEN] -= 4;
+dma_len -= 4;
+s->regs[R_DMA_LEN] = dma_len;
  }
  
  if (s->inject_failure && aspeed_smc_inject_read_failure(s)) {

@@ -889,14 +904,17 @@ static void aspeed_smc_dma_checksum(AspeedSMCState *s)
  static void aspeed_smc_dma_rw(AspeedSMCState *s)
  {
  MemTxResult result;
+uint32_t dma_len;
  uint32_t data;
  
+dma_len = aspeed_smc_dma_len(s);

+
  trace_aspeed_smc_dma_rw(s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE ?
  "write" : "read",
  s->regs[R_DMA_FLASH_ADDR],
  s->regs[R_DMA_DRAM_ADDR],
-s->regs[R_DMA_LEN]);
-while (s->regs[R_DMA_LEN]) {
+dma_len);
+while (dma_len) {
  if (s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE) {
  data = address_space_ldl_le(>dram_as, s->regs[R_DMA_DRAM_ADDR],
  MEMTXATTRS_UNSPECIFIED, );
@@ -937,7 +955,8 @@ static void aspeed_smc_dma_rw(AspeedSMCState *s)
   */
  s->regs[R_DMA_FLASH_ADDR] += 4;
  s->regs[R_DMA_DRAM_ADDR] += 4;
-s->regs[R_DMA_LEN] -= 4;
+dma_len -= 4;
+s->regs[R_DMA_LEN] = dma_len;
  s->regs[R_DMA_CHECKSUM] += data;
  }
  }
@@ -1381,6 +1400,7 @@ static void aspeed_2400_fmc_class_init(ObjectClass 
*klass, void *data)
  asc->features  = ASPEED_SMC_FEATURE_DMA;
  asc->dma_flash_mask= 0x0FFC;
  asc->dma_dram_mask = 0x1FFC;
+asc->dma_start_length  = 4;
  asc->nregs = ASPEED_SMC_R_MAX;
  asc->segment_to_reg= aspeed_smc_segment_to_reg;
  asc->reg_to_segment= aspeed_smc_reg_to_segment;
@@ -1464,6 +1484,7 @@ static void aspeed_2500_fmc_class_init(ObjectC

Re: [PATCH v4 08/16] aspeed/smc: support 64 bits dma dram address

2024-05-27 Thread Cédric Le Goater

On 5/27/24 10:02, Jamin Lin wrote:

AST2700 support the maximum dram size is 8GiB
and has a "DMA DRAM Side Address High Part(0x7C)"
register to support 64 bits dma dram address.
Add helper routines functions to compute the dma dram
address, new features and update trace-event
to support 64 bits dram address.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 


I will move the addition of the "dram-base" property to another patch. See :

  https://patchew.org/QEMU/20240527124315.35356-1-...@redhat.com/

(Please review)

Else,

Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  hw/ssi/aspeed_smc.c | 52 +++--
  hw/ssi/trace-events |  2 +-
  include/hw/ssi/aspeed_smc.h |  1 +
  3 files changed, 46 insertions(+), 9 deletions(-)

diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index ffb13a12e8..df0c63469c 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -132,6 +132,9 @@
  #define   FMC_WDT2_CTRL_BOOT_SOURCE  BIT(4) /* O: primary 1: alternate */
  #define   FMC_WDT2_CTRL_EN   BIT(0)
  
+/* DMA DRAM Side Address High Part (AST2700) */

+#define R_DMA_DRAM_ADDR_HIGH   (0x7c / 4)
+
  /* DMA Control/Status Register */
  #define R_DMA_CTRL(0x80 / 4)
  #define   DMA_CTRL_REQUEST  (1 << 31)
@@ -187,6 +190,7 @@
   *   0x1FF: 32M bytes
   */
  #define DMA_DRAM_ADDR(asc, val)   ((val) & (asc)->dma_dram_mask)
+#define DMA_DRAM_ADDR_HIGH(val)   ((val) & 0xf)
  #define DMA_FLASH_ADDR(asc, val)  ((val) & (asc)->dma_flash_mask)
  #define DMA_LENGTH(val) ((val) & 0x01FF)
  
@@ -207,6 +211,7 @@ static const AspeedSegments aspeed_2500_spi2_segments[];

  #define ASPEED_SMC_FEATURE_DMA   0x1
  #define ASPEED_SMC_FEATURE_DMA_GRANT 0x2
  #define ASPEED_SMC_FEATURE_WDT_CONTROL 0x4
+#define ASPEED_SMC_FEATURE_DMA_DRAM_ADDR_HIGH 0x08
  
  static inline bool aspeed_smc_has_dma(const AspeedSMCClass *asc)

  {
@@ -218,6 +223,11 @@ static inline bool aspeed_smc_has_wdt_control(const 
AspeedSMCClass *asc)
  return !!(asc->features & ASPEED_SMC_FEATURE_WDT_CONTROL);
  }
  
+static inline bool aspeed_smc_has_dma64(const AspeedSMCClass *asc)

+{
+return !!(asc->features & ASPEED_SMC_FEATURE_DMA_DRAM_ADDR_HIGH);
+}
+
  #define aspeed_smc_error(fmt, ...)  \
  qemu_log_mask(LOG_GUEST_ERROR, "%s: " fmt "\n", __func__, ## __VA_ARGS__)
  
@@ -747,6 +757,8 @@ static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)

  (aspeed_smc_has_dma(asc) && addr == R_DMA_CTRL) ||
  (aspeed_smc_has_dma(asc) && addr == R_DMA_FLASH_ADDR) ||
  (aspeed_smc_has_dma(asc) && addr == R_DMA_DRAM_ADDR) ||
+(aspeed_smc_has_dma(asc) && aspeed_smc_has_dma64(asc) &&
+ addr == R_DMA_DRAM_ADDR_HIGH) ||
  (aspeed_smc_has_dma(asc) && addr == R_DMA_LEN) ||
  (aspeed_smc_has_dma(asc) && addr == R_DMA_CHECKSUM) ||
  (addr >= R_SEG_ADDR0 &&
@@ -847,6 +859,12 @@ static bool aspeed_smc_inject_read_failure(AspeedSMCState 
*s)
  }
  }
  
+static uint64_t aspeed_smc_dma_dram_addr(AspeedSMCState *s)

+{
+return s->regs[R_DMA_DRAM_ADDR] |
+((uint64_t) s->regs[R_DMA_DRAM_ADDR_HIGH] << 32);
+}
+
  static uint32_t aspeed_smc_dma_len(AspeedSMCState *s)
  {
  AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
@@ -903,24 +921,34 @@ static void aspeed_smc_dma_checksum(AspeedSMCState *s)
  
  static void aspeed_smc_dma_rw(AspeedSMCState *s)

  {
+AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
+uint64_t dma_dram_offset;
+uint64_t dma_dram_addr;
  MemTxResult result;
  uint32_t dma_len;
  uint32_t data;
  
  dma_len = aspeed_smc_dma_len(s);

+dma_dram_addr = aspeed_smc_dma_dram_addr(s);
+
+if (aspeed_smc_has_dma64(asc)) {
+dma_dram_offset = dma_dram_addr - s->dram_base;
+} else {
+dma_dram_offset = dma_dram_addr;
+}
  
  trace_aspeed_smc_dma_rw(s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE ?

  "write" : "read",
  s->regs[R_DMA_FLASH_ADDR],
-s->regs[R_DMA_DRAM_ADDR],
+dma_dram_offset,
  dma_len);
  while (dma_len) {
  if (s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE) {
-data = address_space_ldl_le(>dram_as, s->regs[R_DMA_DRAM_ADDR],
+data = address_space_ldl_le(>dram_as, dma_dram_offset,
  MEMTXATTRS_UNSPECIFIED, );
  if (result != MEMTX_OK) {
-aspeed_smc_error("DRAM read failed @%08x",
- s->regs[R_DMA_DRAM_ADDR]);
+aspeed_smc_error("DRAM read failed @%" PRIx64,
+  

[PATCH] aspeed/smc: Reintroduce "dram-base" property for AST2700

2024-05-27 Thread Cédric Le Goater
The Aspeed SMC device model use to have a 'sdram_base' property. It
was removed by commit d177892d4a48 ("aspeed/smc: Remove unused
"sdram-base" property") because previous changes simplified the DMA
transaction model to use an offset in RAM and not the physical
address.

The AST2700 SoC has larger address space (64-bit) and a new register
DMA DRAM Side Address High Part (0x7C) is introduced to deal with the
high bits of the DMA address. To be able to compute the offset of the
DMA transaction, as done on the other SoCs, we will need to know where
the DRAM is mapped in the address space. Re-introduce a "dram-base"
property to hold this value.

Signed-off-by: Cédric Le Goater 
---
 include/hw/ssi/aspeed_smc.h | 1 +
 hw/ssi/aspeed_smc.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
index 8e1dda556b91..8791cc0ecb11 100644
--- a/include/hw/ssi/aspeed_smc.h
+++ b/include/hw/ssi/aspeed_smc.h
@@ -76,6 +76,7 @@ struct AspeedSMCState {
 AddressSpace flash_as;
 MemoryRegion *dram_mr;
 AddressSpace dram_as;
+uint64_t dram_base;
 
 AspeedSMCFlash flashes[ASPEED_SMC_CS_MAX];
 
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index 6e1a84c19713..7075bc9d61b0 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -1220,6 +1220,7 @@ static const VMStateDescription vmstate_aspeed_smc = {
 
 static Property aspeed_smc_properties[] = {
 DEFINE_PROP_BOOL("inject-failure", AspeedSMCState, inject_failure, false),
+DEFINE_PROP_UINT64("dram-base", AspeedSMCState, dram_base, 0),
 DEFINE_PROP_LINK("dram", AspeedSMCState, dram_mr,
  TYPE_MEMORY_REGION, MemoryRegion *),
 DEFINE_PROP_END_OF_LIST(),
-- 
2.45.1




Re: [PATCH] hw/s390x: Remove unused macro VMSTATE_ADAPTER_ROUTES

2024-05-27 Thread Cédric Le Goater

On 5/27/24 14:13, Thomas Huth wrote:

It's not used anywhere, so let's simply remove it.

Signed-off-by: Thomas Huth 



Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  include/hw/s390x/s390_flic.h | 3 ---
  1 file changed, 3 deletions(-)

diff --git a/include/hw/s390x/s390_flic.h b/include/hw/s390x/s390_flic.h
index bcb081def5..382d9833f1 100644
--- a/include/hw/s390x/s390_flic.h
+++ b/include/hw/s390x/s390_flic.h
@@ -35,9 +35,6 @@ typedef struct AdapterRoutes {
  
  extern const VMStateDescription vmstate_adapter_routes;
  
-#define VMSTATE_ADAPTER_ROUTES(_f, _s) \

-VMSTATE_STRUCT(_f, _s, 1, vmstate_adapter_routes, AdapterRoutes)
-
  #define TYPE_S390_FLIC_COMMON "s390-flic"
  OBJECT_DECLARE_TYPE(S390FLICState, S390FLICStateClass,
  S390_FLIC_COMMON)





Re: [PATCH v4 05/16] aspeed/sdmc: Add AST2700 support

2024-05-27 Thread Cédric Le Goater

On 5/27/24 12:24, Philippe Mathieu-Daudé wrote:

Hi Jamin,

On 27/5/24 10:02, Jamin Lin wrote:

The SDRAM memory controller(DRAMC) controls the access to external
DDR4 and DDR5 SDRAM and power up to DDR4 and DDR5 PHY.

The DRAM memory controller of AST2700 is not backward compatible
to previous chips such AST2600, AST2500 and AST2400.

Max memory is now 8GiB on the AST2700. Introduce new
aspeed_2700_sdmc and class with read/write operation and
reset handlers.

Define DRAMC necessary protected registers and
unprotected registers for AST2700 and increase
the register set to 0x1000.

Add unlocked property to change controller protected status.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Reviewed-by: Cédric Le Goater 
---
  hw/misc/aspeed_sdmc.c | 190 +-
  include/hw/misc/aspeed_sdmc.h |   5 +-
  2 files changed, 193 insertions(+), 2 deletions(-)




diff --git a/include/hw/misc/aspeed_sdmc.h b/include/hw/misc/aspeed_sdmc.h
index ec2d59a14f..61c979583a 100644
--- a/include/hw/misc/aspeed_sdmc.h
+++ b/include/hw/misc/aspeed_sdmc.h
@@ -17,6 +17,7 @@ OBJECT_DECLARE_TYPE(AspeedSDMCState, AspeedSDMCClass, 
ASPEED_SDMC)
  #define TYPE_ASPEED_2400_SDMC TYPE_ASPEED_SDMC "-ast2400"
  #define TYPE_ASPEED_2500_SDMC TYPE_ASPEED_SDMC "-ast2500"
  #define TYPE_ASPEED_2600_SDMC TYPE_ASPEED_SDMC "-ast2600"
+#define TYPE_ASPEED_2700_SDMC TYPE_ASPEED_SDMC "-ast2700"
  /*
   * SDMC has 174 documented registers. In addition the u-boot device tree
@@ -29,7 +30,7 @@ OBJECT_DECLARE_TYPE(AspeedSDMCState, AspeedSDMCClass, 
ASPEED_SDMC)
   * time, and the other is in the DDR-PHY IP which is used during DDR-PHY
   * training.
   */
-#define ASPEED_SDMC_NR_REGS (0x500 >> 2)
+#define ASPEED_SDMC_NR_REGS (0x1000 >> 2)


This change breaks the migration stream.


Do you mean migration compat ? We never cared much about that
for the Aspeed machines.

Thanks,

C.






  struct AspeedSDMCState {
  /*< private >*/
@@ -41,6 +42,7 @@ struct AspeedSDMCState {
  uint32_t regs[ASPEED_SDMC_NR_REGS];
  uint64_t ram_size;
  uint64_t max_ram_size;
+    bool unlocked;
  };







Re: [RFC PATCH 00/10] ppc/pnv: Better big-core model, lpar-per-core, PC unit

2024-05-27 Thread Cédric Le Goater

On 5/27/24 09:32, Nicholas Piggin wrote:

On Mon May 27, 2024 at 4:25 PM AEST, Cédric Le Goater wrote:

On 5/26/24 14:26, Nicholas Piggin wrote:

Primary motivation for this series is to improve big-core support.
Other things like SPR indirect, timebase state, PC xscom, are required
for minimal big core support.

I'm still not 100% happy with the big-core topology model after this.
Maybe one day we add pnv big core and pnv small core structures. But


I haven't look at the proposal yet, but indeed, we could introduce
a new TYPE_PNV_CORE type for big cores only.


Yeah. It's still tricky because big-core structure contains the CPUs
if you are running in small core mode. So it would really have to be
a PnvCPUCore and PnvPervasiveCore or something, where the former is
either SMT4 and 1:1 with the latter or SMT8 and 1:2 depending on mode.

And some of the "CPU" type operations in big core mode still need to
operate on the small core.

For now, the accessors and helpers seem to be not too bad.


nothing is completely clean because big core mode still has certain
small core restrictions. I think for now we take a bit of mostly
abstracted ugliness in TCG code for the benefit of not spreading
hacks through pervasive (xscom) core addressing.

After this series, power9 and power10 get through skiboot/Linux boot

s

Have you tried SMT8 on powernv8 ? I remember seeing a hang if I am correct.
I don't think POWER8 deserves much attention anymore, we could deprecate
POWER8E and POWER8NVL. However, we should at least report an error if we
know a setup is broken.


Yeah it does have some problem. Maybe should just disable SMT unless
someone finds time to work it out.



The new _init routines would be a good place to do that.

Thanks,

C.




Thanks,
Nick





Re: [PATCH v3 08/16] aspeed/smc: support 64 bits dma dram address

2024-05-27 Thread Cédric Le Goater

Hello Jamin,


[ ... ]


See my aspeed-9.1 branch, I did some changes, mostly in the last patch.

* aspeed_smc_dma_len()

- can use QEMU_ALIGN_UP(). simpler.

* aspeed_smc_dma_rw():

- dram_addr ->  dma_dram_offset
- There is no need to protect updates of the R_DMA_DRAM_ADDR_HIGH
  register with aspeed_smc_has_dma_dram_addr_high() since it is
  already protected with MMIO accesses. Skip the check and update
  always.

* aspeed_smc_dma_dram_addr()

- same as above.

You can merge the changes in the respective patches if you agree.

Still on the TODO list :

- GIC review
- aspeed/soc: fix incorrect dram size for AST2700

Thanks,

C.


I merged this commit into my code base and thanks for your kindly support.
https://github.com/legoater/qemu/commit/d1bc2c776422a9d0d6af2b4414fae83fde1832ba

About GIC settings, you can refer to our kernel DTS setting for detail.
https://github.com/AspeedTech-BMC/linux/blob/aspeed-master-v6.6/arch/arm64/boot/dts/aspeed/aspeed-g7.dtsi#L143-L164


Could you please resend a v4 including all the changes we discussed ?

Thanks,

C.






Re: [PATCH 0/7] s390x/ccw: Error reporting cleanups

2024-05-27 Thread Cédric Le Goater

On 5/27/24 08:23, Thomas Huth wrote:

On 22/05/2024 19.01, Cédric Le Goater wrote:

Hello,

The first patches of this series simply apply the practices described
in the Rules section of the qapi/error.h file for routines taking an
'Error **' argument. The remaining patches are a fixup in the error
path of vfio_ccw_realize() and some error reporting adjustements.

Applies on top of this vfio PR :

   https://lore.kernel.org/qemu-devel/20240522095442.195243-1-...@redhat.com

Thanks,

C.

Cédric Le Goater (6):
   hw/s390x/ccw: Make s390_ccw_get_dev_info() return a bool
   s390x/css: Make CCWDeviceClass::realize return bool
   hw/s390x/ccw: Remove local Error variable from s390_ccw_realize()
   s390x/css: Make S390CCWDeviceClass::realize return bool
   vfio/ccw: Use the 'Error **errp' argument of vfio_ccw_realize()
   vfio/{ap,ccw}: Use warn_report_err() for IRQ notifier registration
 errors


Series
Reviewed-by: Thomas Huth 




Applied to vfio-next.

Thanks,

C.





Re: [RFC PATCH 00/10] ppc/pnv: Better big-core model, lpar-per-core, PC unit

2024-05-27 Thread Cédric Le Goater

On 5/26/24 14:26, Nicholas Piggin wrote:

Primary motivation for this series is to improve big-core support.
Other things like SPR indirect, timebase state, PC xscom, are required
for minimal big core support.

I'm still not 100% happy with the big-core topology model after this.
Maybe one day we add pnv big core and pnv small core structures. But


I haven't look at the proposal yet, but indeed, we could introduce
a new TYPE_PNV_CORE type for big cores only.


nothing is completely clean because big core mode still has certain
small core restrictions. I think for now we take a bit of mostly
abstracted ugliness in TCG code for the benefit of not spreading
hacks through pervasive (xscom) core addressing.

After this series, power9 and power10 get through skiboot/Linux boot

s

Have you tried SMT8 on powernv8 ? I remember seeing a hang if I am correct.
I don't think POWER8 deserves much attention anymore, we could deprecate
POWER8E and POWER8NVL. However, we should at least report an error if we
know a setup is broken.

Thanks,

C.



Not all big core registers are modeled
exactly (some are not shared between small core halves), but that
mostly doesn't matter for OPAL and it can be improved later.

Thanks,
Nick

Nicholas Piggin (10):
   ppc/pnv: Add pointer from PnvCPUState to PnvCore
   ppc/pnv: Move timebase state into PnvCore
   target/ppc: Improve SPR indirect registers
   ppc/pnv: specialise init for powernv8/9/10 machines
   ppc/pnv: Extend chip_pir class method to TIR as well
   ppc: Add a core_index to CPUPPCState for SMT vCPUs
   target/ppc: Add helpers to check for SMT sibling threads
   ppc/pnv: Invert the design for big-core machine modelling
   ppc/pnv: Implement POWER10 PC xscom registers for direct controls
   ppc/pnv: Add an LPAR per core machine option

  include/hw/core/cpu.h|   8 +
  include/hw/ppc/pnv.h |   6 +
  include/hw/ppc/pnv_chip.h|   3 +-
  include/hw/ppc/pnv_core.h|  31 
  target/ppc/cpu.h |  37 ++---
  hw/ppc/pnv.c | 297 ---
  hw/ppc/pnv_chiptod.c |   6 +-
  hw/ppc/pnv_core.c| 129 +--
  hw/ppc/spapr_cpu_core.c  |   7 +
  system/cpus.c|  10 ++
  target/ppc/cpu_init.c|  26 +--
  target/ppc/excp_helper.c |  16 +-
  target/ppc/misc_helper.c |  98 ++--
  target/ppc/timebase_helper.c |  82 +-
  14 files changed, 548 insertions(+), 208 deletions(-)






Re: [PATCH 6/7] vfio/ccw: Fix the missed unrealize() call in error path

2024-05-23 Thread Cédric Le Goater

On 5/22/24 19:01, Cédric Le Goater wrote:

From: Zhenzhong Duan 

When get name failed, we should call unrealize() so that
vfio_ccw_realize() is self contained.

Fixes: 909a6254eda ("vfio/ccw: Make vfio cdev pre-openable by passing a file 
handle")
Signed-off-by: Zhenzhong Duan 



Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  hw/vfio/ccw.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 
a468fa2342b97e0ee36bd5fb8443025cc90a0453..36f2677a448c5e31523dcc3de7d973ec70e4a13c
 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -588,7 +588,7 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)
  }
  
  if (!vfio_device_get_name(vbasedev, errp)) {

-return;
+goto out_unrealize;
  }
  
  if (!vfio_attach_device(cdev->mdevid, vbasedev,

@@ -631,6 +631,7 @@ out_region_err:
  vfio_detach_device(vbasedev);
  out_attach_dev_err:
  g_free(vbasedev->name);
+out_unrealize:
  if (cdc->unrealize) {
  cdc->unrealize(cdev);
  }





[PATCH 3/7] hw/s390x/ccw: Remove local Error variable from s390_ccw_realize()

2024-05-22 Thread Cédric Le Goater
Use the 'Error **errp' argument of s390_ccw_realize() instead and
remove the error_propagate() call.

Signed-off-by: Cédric Le Goater 
---
 hw/s390x/s390-ccw.c | 13 +
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/hw/s390x/s390-ccw.c b/hw/s390x/s390-ccw.c
index 
4b8ede701df90949720262b6fc1b65f4e505e34d..b3d14c61d732880a651edcf28a040ca723cb9f5b
 100644
--- a/hw/s390x/s390-ccw.c
+++ b/hw/s390x/s390-ccw.c
@@ -115,13 +115,12 @@ static void s390_ccw_realize(S390CCWDevice *cdev, char 
*sysfsdev, Error **errp)
 DeviceState *parent = DEVICE(ccw_dev);
 SubchDev *sch;
 int ret;
-Error *err = NULL;
 
-if (!s390_ccw_get_dev_info(cdev, sysfsdev, )) {
-goto out_err_propagate;
+if (!s390_ccw_get_dev_info(cdev, sysfsdev, errp)) {
+return;
 }
 
-sch = css_create_sch(ccw_dev->devno, );
+sch = css_create_sch(ccw_dev->devno, errp);
 if (!sch) {
 goto out_mdevid_free;
 }
@@ -132,12 +131,12 @@ static void s390_ccw_realize(S390CCWDevice *cdev, char 
*sysfsdev, Error **errp)
 ccw_dev->sch = sch;
 ret = css_sch_build_schib(sch, >hostid);
 if (ret) {
-error_setg_errno(, -ret, "%s: Failed to build initial schib",
+error_setg_errno(errp, -ret, "%s: Failed to build initial schib",
  __func__);
 goto out_err;
 }
 
-if (!ck->realize(ccw_dev, )) {
+if (!ck->realize(ccw_dev, errp)) {
 goto out_err;
 }
 
@@ -151,8 +150,6 @@ out_err:
 g_free(sch);
 out_mdevid_free:
 g_free(cdev->mdevid);
-out_err_propagate:
-error_propagate(errp, err);
 }
 
 static void s390_ccw_unrealize(S390CCWDevice *cdev)
-- 
2.45.1




[PATCH 6/7] vfio/ccw: Fix the missed unrealize() call in error path

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

When get name failed, we should call unrealize() so that
vfio_ccw_realize() is self contained.

Fixes: 909a6254eda ("vfio/ccw: Make vfio cdev pre-openable by passing a file 
handle")
Signed-off-by: Zhenzhong Duan 
---
 hw/vfio/ccw.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 
a468fa2342b97e0ee36bd5fb8443025cc90a0453..36f2677a448c5e31523dcc3de7d973ec70e4a13c
 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -588,7 +588,7 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)
 }
 
 if (!vfio_device_get_name(vbasedev, errp)) {
-return;
+goto out_unrealize;
 }
 
 if (!vfio_attach_device(cdev->mdevid, vbasedev,
@@ -631,6 +631,7 @@ out_region_err:
 vfio_detach_device(vbasedev);
 out_attach_dev_err:
 g_free(vbasedev->name);
+out_unrealize:
 if (cdc->unrealize) {
 cdc->unrealize(cdev);
 }
-- 
2.45.1




[PATCH 7/7] vfio/{ap, ccw}: Use warn_report_err() for IRQ notifier registration errors

2024-05-22 Thread Cédric Le Goater
vfio_ccw_register_irq_notifier() and vfio_ap_register_irq_notifier()
errors are currently reported using error_report_err(). Since they are
not considered as failing conditions, using warn_report_err() is more
appropriate.

Signed-off-by: Cédric Le Goater 
---
 hw/vfio/ap.c  | 2 +-
 hw/vfio/ccw.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/vfio/ap.c b/hw/vfio/ap.c
index 
c12531a7886a2fe87598be0861fba5923bd2c206..0c4354e3e70169ec072e16da0919936647d1d351
 100644
--- a/hw/vfio/ap.c
+++ b/hw/vfio/ap.c
@@ -172,7 +172,7 @@ static void vfio_ap_realize(DeviceState *dev, Error **errp)
  * Report this error, but do not make it a failing condition.
  * Lack of this IRQ in the host does not prevent normal operation.
  */
-error_report_err(err);
+warn_report_err(err);
 }
 
 return;
diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 
36f2677a448c5e31523dcc3de7d973ec70e4a13c..1f8e1272c7555cd0a770481d1ae92988f6e2e62e
 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -616,7 +616,7 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)
  * Report this error, but do not make it a failing condition.
  * Lack of this IRQ in the host does not prevent normal operation.
  */
-error_report_err(err);
+warn_report_err(err);
 }
 
 return;
-- 
2.45.1




[PATCH 4/7] s390x/css: Make S390CCWDeviceClass::realize return bool

2024-05-22 Thread Cédric Le Goater
Since the realize() handler of S390CCWDeviceClass takes an 'Error **'
argument, best practices suggest to return a bool. See the api/error.h
Rules section. While at it, modify the call in vfio_ccw_realize().

Signed-off-by: Cédric Le Goater 
---
 include/hw/s390x/s390-ccw.h | 2 +-
 hw/s390x/s390-ccw.c | 7 ---
 hw/vfio/ccw.c   | 3 +--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/include/hw/s390x/s390-ccw.h b/include/hw/s390x/s390-ccw.h
index 
2c807ee3a1ae8d85460fe65be8a62c64f212fe4b..2e0a70998132070996d6b0d083b8ddba5b9b87dc
 100644
--- a/include/hw/s390x/s390-ccw.h
+++ b/include/hw/s390x/s390-ccw.h
@@ -31,7 +31,7 @@ struct S390CCWDevice {
 
 struct S390CCWDeviceClass {
 CCWDeviceClass parent_class;
-void (*realize)(S390CCWDevice *dev, char *sysfsdev, Error **errp);
+bool (*realize)(S390CCWDevice *dev, char *sysfsdev, Error **errp);
 void (*unrealize)(S390CCWDevice *dev);
 IOInstEnding (*handle_request) (SubchDev *sch);
 int (*handle_halt) (SubchDev *sch);
diff --git a/hw/s390x/s390-ccw.c b/hw/s390x/s390-ccw.c
index 
b3d14c61d732880a651edcf28a040ca723cb9f5b..3c0975055089c3629dd76ce2e1484a4ef66d8d41
 100644
--- a/hw/s390x/s390-ccw.c
+++ b/hw/s390x/s390-ccw.c
@@ -108,7 +108,7 @@ static bool s390_ccw_get_dev_info(S390CCWDevice *cdev,
 return true;
 }
 
-static void s390_ccw_realize(S390CCWDevice *cdev, char *sysfsdev, Error **errp)
+static bool s390_ccw_realize(S390CCWDevice *cdev, char *sysfsdev, Error **errp)
 {
 CcwDevice *ccw_dev = CCW_DEVICE(cdev);
 CCWDeviceClass *ck = CCW_DEVICE_GET_CLASS(ccw_dev);
@@ -117,7 +117,7 @@ static void s390_ccw_realize(S390CCWDevice *cdev, char 
*sysfsdev, Error **errp)
 int ret;
 
 if (!s390_ccw_get_dev_info(cdev, sysfsdev, errp)) {
-return;
+return false;
 }
 
 sch = css_create_sch(ccw_dev->devno, errp);
@@ -142,7 +142,7 @@ static void s390_ccw_realize(S390CCWDevice *cdev, char 
*sysfsdev, Error **errp)
 
 css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid,
   parent->hotplugged, 1);
-return;
+return true;
 
 out_err:
 css_subch_assign(sch->cssid, sch->ssid, sch->schid, sch->devno, NULL);
@@ -150,6 +150,7 @@ out_err:
 g_free(sch);
 out_mdevid_free:
 g_free(cdev->mdevid);
+return false;
 }
 
 static void s390_ccw_unrealize(S390CCWDevice *cdev)
diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 
2600e62e37238779800dc2b3a0bd315d7633017b..9a8e052711fe2f7c067c52808b2af30d0ebfee0c
 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -582,8 +582,7 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)
 
 /* Call the class init function for subchannel. */
 if (cdc->realize) {
-cdc->realize(cdev, vcdev->vdev.sysfsdev, );
-if (err) {
+if (!cdc->realize(cdev, vcdev->vdev.sysfsdev, )) {
 goto out_err_propagate;
 }
 }
-- 
2.45.1




[PATCH 5/7] vfio/ccw: Use the 'Error **errp' argument of vfio_ccw_realize()

2024-05-22 Thread Cédric Le Goater
The local error variable is kept for vfio_ccw_register_irq_notifier()
because it is not considered as a failing condition. We will change
how error reporting is done in following changes.

Remove the error_propagate() call.

Cc: Zhenzhong Duan 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/ccw.c | 12 +---
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 
9a8e052711fe2f7c067c52808b2af30d0ebfee0c..a468fa2342b97e0ee36bd5fb8443025cc90a0453
 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -582,8 +582,8 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)
 
 /* Call the class init function for subchannel. */
 if (cdc->realize) {
-if (!cdc->realize(cdev, vcdev->vdev.sysfsdev, )) {
-goto out_err_propagate;
+if (!cdc->realize(cdev, vcdev->vdev.sysfsdev, errp)) {
+return;
 }
 }
 
@@ -596,17 +596,17 @@ static void vfio_ccw_realize(DeviceState *dev, Error 
**errp)
 goto out_attach_dev_err;
 }
 
-if (!vfio_ccw_get_region(vcdev, )) {
+if (!vfio_ccw_get_region(vcdev, errp)) {
 goto out_region_err;
 }
 
-if (!vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX, )) {
+if (!vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX, errp)) {
 goto out_io_notifier_err;
 }
 
 if (vcdev->crw_region) {
 if (!vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX,
-)) {
+errp)) {
 goto out_irq_notifier_err;
 }
 }
@@ -634,8 +634,6 @@ out_attach_dev_err:
 if (cdc->unrealize) {
 cdc->unrealize(cdev);
 }
-out_err_propagate:
-error_propagate(errp, err);
 }
 
 static void vfio_ccw_unrealize(DeviceState *dev)
-- 
2.45.1




[PATCH 0/7] s390x/ccw: Error reporting cleanups

2024-05-22 Thread Cédric Le Goater
Hello,

The first patches of this series simply apply the practices described
in the Rules section of the qapi/error.h file for routines taking an
'Error **' argument. The remaining patches are a fixup in the error
path of vfio_ccw_realize() and some error reporting adjustements.

Applies on top of this vfio PR :

  https://lore.kernel.org/qemu-devel/20240522095442.195243-1-...@redhat.com

Thanks,

C.

Cédric Le Goater (6):
  hw/s390x/ccw: Make s390_ccw_get_dev_info() return a bool
  s390x/css: Make CCWDeviceClass::realize return bool
  hw/s390x/ccw: Remove local Error variable from s390_ccw_realize()
  s390x/css: Make S390CCWDeviceClass::realize return bool
  vfio/ccw: Use the 'Error **errp' argument of vfio_ccw_realize()
  vfio/{ap,ccw}: Use warn_report_err() for IRQ notifier registration
errors

Zhenzhong Duan (1):
  vfio/ccw: Fix the missed unrealize() call in error path

 hw/s390x/ccw-device.h   |  2 +-
 include/hw/s390x/s390-ccw.h |  2 +-
 hw/s390x/ccw-device.c   |  3 ++-
 hw/s390x/s390-ccw.c | 29 +
 hw/vfio/ap.c|  2 +-
 hw/vfio/ccw.c   | 18 --
 6 files changed, 26 insertions(+), 30 deletions(-)

-- 
2.45.1




[PATCH 1/7] hw/s390x/ccw: Make s390_ccw_get_dev_info() return a bool

2024-05-22 Thread Cédric Le Goater
Since s390_ccw_get_dev_info() takes an 'Error **' argument, best
practices suggest to return a bool. See the qapi/error.h Rules
section. While at it, modify the call in s390_ccw_realize().

Signed-off-by: Cédric Le Goater 
---
 hw/s390x/s390-ccw.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/hw/s390x/s390-ccw.c b/hw/s390x/s390-ccw.c
index 
5261e66724f1cc3157b9413b0d5fdf5289c92503..a06e91dfb318e3500324851488c56806fa46c08d
 100644
--- a/hw/s390x/s390-ccw.c
+++ b/hw/s390x/s390-ccw.c
@@ -71,7 +71,7 @@ IOInstEnding s390_ccw_store(SubchDev *sch)
 return ret;
 }
 
-static void s390_ccw_get_dev_info(S390CCWDevice *cdev,
+static bool s390_ccw_get_dev_info(S390CCWDevice *cdev,
   char *sysfsdev,
   Error **errp)
 {
@@ -84,12 +84,12 @@ static void s390_ccw_get_dev_info(S390CCWDevice *cdev,
 error_setg(errp, "No host device provided");
 error_append_hint(errp,
   "Use -device vfio-ccw,sysfsdev=PATH_TO_DEVICE\n");
-return;
+return false;
 }
 
 if (!realpath(sysfsdev, dev_path)) {
 error_setg_errno(errp, errno, "Host device '%s' not found", sysfsdev);
-return;
+return false;
 }
 
 cdev->mdevid = g_path_get_basename(dev_path);
@@ -98,13 +98,14 @@ static void s390_ccw_get_dev_info(S390CCWDevice *cdev,
 tmp = g_path_get_basename(tmp_dir);
 if (sscanf(tmp, "%2x.%1x.%4x", , , ) != 3) {
 error_setg_errno(errp, errno, "Failed to read %s", tmp);
-return;
+return false;
 }
 
 cdev->hostid.cssid = cssid;
 cdev->hostid.ssid = ssid;
 cdev->hostid.devid = devid;
 cdev->hostid.valid = true;
+return true;
 }
 
 static void s390_ccw_realize(S390CCWDevice *cdev, char *sysfsdev, Error **errp)
@@ -116,8 +117,7 @@ static void s390_ccw_realize(S390CCWDevice *cdev, char 
*sysfsdev, Error **errp)
 int ret;
 Error *err = NULL;
 
-s390_ccw_get_dev_info(cdev, sysfsdev, );
-if (err) {
+if (!s390_ccw_get_dev_info(cdev, sysfsdev, )) {
 goto out_err_propagate;
 }
 
-- 
2.45.1




[PATCH 2/7] s390x/css: Make CCWDeviceClass::realize return bool

2024-05-22 Thread Cédric Le Goater
Since the realize() handler of CCWDeviceClass takes an 'Error **'
argument, best practices suggest to return a bool. See the api/error.h
Rules section. While at it, modify the call in s390_ccw_realize().

Signed-off-by: Cédric Le Goater 
---
 hw/s390x/ccw-device.h | 2 +-
 hw/s390x/ccw-device.c | 3 ++-
 hw/s390x/s390-ccw.c   | 3 +--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/s390x/ccw-device.h b/hw/s390x/ccw-device.h
index 
6dff95225df11c63f9b66975019026b215c8c448..5feeb0ee7a268b8709043b5bbc56b06e707a448d
 100644
--- a/hw/s390x/ccw-device.h
+++ b/hw/s390x/ccw-device.h
@@ -36,7 +36,7 @@ extern const VMStateDescription vmstate_ccw_dev;
 struct CCWDeviceClass {
 DeviceClass parent_class;
 void (*unplug)(HotplugHandler *, DeviceState *, Error **);
-void (*realize)(CcwDevice *, Error **);
+bool (*realize)(CcwDevice *, Error **);
 void (*refill_ids)(CcwDevice *);
 };
 
diff --git a/hw/s390x/ccw-device.c b/hw/s390x/ccw-device.c
index 
fb8c1acc64d5002c861a4913f292d8346dbef192..a7d682e5af9ce90e7e2fad8c24b30e39328c7cf4
 100644
--- a/hw/s390x/ccw-device.c
+++ b/hw/s390x/ccw-device.c
@@ -31,9 +31,10 @@ static void ccw_device_refill_ids(CcwDevice *dev)
 dev->subch_id.valid = true;
 }
 
-static void ccw_device_realize(CcwDevice *dev, Error **errp)
+static bool ccw_device_realize(CcwDevice *dev, Error **errp)
 {
 ccw_device_refill_ids(dev);
+return true;
 }
 
 static Property ccw_device_properties[] = {
diff --git a/hw/s390x/s390-ccw.c b/hw/s390x/s390-ccw.c
index 
a06e91dfb318e3500324851488c56806fa46c08d..4b8ede701df90949720262b6fc1b65f4e505e34d
 100644
--- a/hw/s390x/s390-ccw.c
+++ b/hw/s390x/s390-ccw.c
@@ -137,8 +137,7 @@ static void s390_ccw_realize(S390CCWDevice *cdev, char 
*sysfsdev, Error **errp)
 goto out_err;
 }
 
-ck->realize(ccw_dev, );
-if (err) {
+if (!ck->realize(ccw_dev, )) {
 goto out_err;
 }
 
-- 
2.45.1




[PULL 30/47] vfio/display: Fix error path in call site of ramfb_setup()

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

vfio_display_dmabuf_init() and vfio_display_region_init() calls
ramfb_setup() without checking its return value.

So we may run into a situation that vfio_display_probe() succeed
but errp is set. This is risky and may lead to assert failure in
error_setv().

Cc: Gerd Hoffmann 
Fixes: b290659fc3d ("hw/vfio/display: add ramfb support")
Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/display.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/hw/vfio/display.c b/hw/vfio/display.c
index 
fe624a6c9b86e7204e2763ab62ef60903f19d350..d28b724102d5970cb2b9dc7464dc7575b6f441d9
 100644
--- a/hw/vfio/display.c
+++ b/hw/vfio/display.c
@@ -361,6 +361,9 @@ static int vfio_display_dmabuf_init(VFIOPCIDevice *vdev, 
Error **errp)
   vdev);
 if (vdev->enable_ramfb) {
 vdev->dpy->ramfb = ramfb_setup(errp);
+if (!vdev->dpy->ramfb) {
+return -EINVAL;
+}
 }
 vfio_display_edid_init(vdev);
 return 0;
@@ -488,6 +491,9 @@ static int vfio_display_region_init(VFIOPCIDevice *vdev, 
Error **errp)
   vdev);
 if (vdev->enable_ramfb) {
 vdev->dpy->ramfb = ramfb_setup(errp);
+if (!vdev->dpy->ramfb) {
+return -EINVAL;
+}
 }
 return 0;
 }
-- 
2.45.1




[PULL 24/47] vfio/container: Make vfio_connect_container() return bool

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

This is to follow the coding standand to return bool if 'Error **'
is used to pass error.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/container.c | 18 +++---
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/hw/vfio/container.c b/hw/vfio/container.c
index 
f2e9560a1906c4151535260e3488ee80ca90e78b..802828ddff061fef25b8e4c997a68348d4be9892
 100644
--- a/hw/vfio/container.c
+++ b/hw/vfio/container.c
@@ -536,8 +536,8 @@ static bool vfio_legacy_setup(VFIOContainerBase 
*bcontainer, Error **errp)
 return true;
 }
 
-static int vfio_connect_container(VFIOGroup *group, AddressSpace *as,
-  Error **errp)
+static bool vfio_connect_container(VFIOGroup *group, AddressSpace *as,
+   Error **errp)
 {
 VFIOContainer *container;
 VFIOContainerBase *bcontainer;
@@ -589,19 +589,18 @@ static int vfio_connect_container(VFIOGroup *group, 
AddressSpace *as,
 error_report("vfio: error disconnecting group %d from"
  " container", group->groupid);
 }
-return ret;
+return false;
 }
 group->container = container;
 QLIST_INSERT_HEAD(>group_list, group, container_next);
 vfio_kvm_device_add_group(group);
-return 0;
+return true;
 }
 }
 
 fd = qemu_open_old("/dev/vfio/vfio", O_RDWR);
 if (fd < 0) {
 error_setg_errno(errp, errno, "failed to open /dev/vfio/vfio");
-ret = -errno;
 goto put_space_exit;
 }
 
@@ -609,7 +608,6 @@ static int vfio_connect_container(VFIOGroup *group, 
AddressSpace *as,
 if (ret != VFIO_API_VERSION) {
 error_setg(errp, "supported vfio version: %d, "
"reported version: %d", VFIO_API_VERSION, ret);
-ret = -EINVAL;
 goto close_fd_exit;
 }
 
@@ -636,7 +634,6 @@ static int vfio_connect_container(VFIOGroup *group, 
AddressSpace *as,
 assert(bcontainer->ops->setup);
 
 if (!bcontainer->ops->setup(bcontainer, errp)) {
-ret = -EINVAL;
 goto enable_discards_exit;
 }
 
@@ -652,7 +649,6 @@ static int vfio_connect_container(VFIOGroup *group, 
AddressSpace *as,
 memory_listener_register(>listener, bcontainer->space->as);
 
 if (bcontainer->error) {
-ret = -1;
 error_propagate_prepend(errp, bcontainer->error,
 "memory listener initialization failed: ");
 goto listener_release_exit;
@@ -660,7 +656,7 @@ static int vfio_connect_container(VFIOGroup *group, 
AddressSpace *as,
 
 bcontainer->initialized = true;
 
-return 0;
+return true;
 listener_release_exit:
 QLIST_REMOVE(group, container_next);
 QLIST_REMOVE(bcontainer, next);
@@ -685,7 +681,7 @@ close_fd_exit:
 put_space_exit:
 vfio_put_address_space(space);
 
-return ret;
+return false;
 }
 
 static void vfio_disconnect_container(VFIOGroup *group)
@@ -772,7 +768,7 @@ static VFIOGroup *vfio_get_group(int groupid, AddressSpace 
*as, Error **errp)
 group->groupid = groupid;
 QLIST_INIT(>device_list);
 
-if (vfio_connect_container(group, as, errp)) {
+if (!vfio_connect_container(group, as, errp)) {
 error_prepend(errp, "failed to setup container for group %d: ",
   groupid);
 goto close_fd_exit;
-- 
2.45.1




[PULL 45/47] vfio/pci-quirks: Make vfio_add_*_cap() return bool

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

This is to follow the coding standand in qapi/error.h to return bool
for bool-valued functions.

Include below functions:
vfio_add_virt_caps()
vfio_add_nv_gpudirect_cap()
vfio_add_vmd_shadow_cap()

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/pci.h|  2 +-
 hw/vfio/pci-quirks.c | 42 +++---
 hw/vfio/pci.c|  3 +--
 3 files changed, 21 insertions(+), 26 deletions(-)

diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
index 
f1586810726584ecfc35ef685646faacabefbec0..bf67df2fbc09b3d0fd97d25dfaa5290ab33b03ea
 100644
--- a/hw/vfio/pci.h
+++ b/hw/vfio/pci.h
@@ -212,7 +212,7 @@ void vfio_bar_quirk_setup(VFIOPCIDevice *vdev, int nr);
 void vfio_bar_quirk_exit(VFIOPCIDevice *vdev, int nr);
 void vfio_bar_quirk_finalize(VFIOPCIDevice *vdev, int nr);
 void vfio_setup_resetfn_quirk(VFIOPCIDevice *vdev);
-int vfio_add_virt_caps(VFIOPCIDevice *vdev, Error **errp);
+bool vfio_add_virt_caps(VFIOPCIDevice *vdev, Error **errp);
 void vfio_quirk_reset(VFIOPCIDevice *vdev);
 VFIOQuirk *vfio_quirk_alloc(int nr_mem);
 void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr);
diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
index 
ca27917159785f760f688c8db0a9ac492080d74b..39dae72497e0315eeb580dbcd5255c58bc38c8ed
 100644
--- a/hw/vfio/pci-quirks.c
+++ b/hw/vfio/pci-quirks.c
@@ -1536,7 +1536,7 @@ static bool is_valid_std_cap_offset(uint8_t pos)
 pos <= (PCI_CFG_SPACE_SIZE - PCI_CAP_SIZEOF));
 }
 
-static int vfio_add_nv_gpudirect_cap(VFIOPCIDevice *vdev, Error **errp)
+static bool vfio_add_nv_gpudirect_cap(VFIOPCIDevice *vdev, Error **errp)
 {
 ERRP_GUARD();
 PCIDevice *pdev = >pdev;
@@ -1545,18 +1545,18 @@ static int vfio_add_nv_gpudirect_cap(VFIOPCIDevice 
*vdev, Error **errp)
 uint8_t tmp;
 
 if (vdev->nv_gpudirect_clique == 0xFF) {
-return 0;
+return true;
 }
 
 if (!vfio_pci_is(vdev, PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID)) {
 error_setg(errp, "NVIDIA GPUDirect Clique ID: invalid device vendor");
-return -EINVAL;
+return false;
 }
 
 if (pci_get_byte(pdev->config + PCI_CLASS_DEVICE + 1) !=
 PCI_BASE_CLASS_DISPLAY) {
 error_setg(errp, "NVIDIA GPUDirect Clique ID: unsupported PCI class");
-return -EINVAL;
+return false;
 }
 
 /*
@@ -1572,7 +1572,7 @@ static int vfio_add_nv_gpudirect_cap(VFIOPCIDevice *vdev, 
Error **errp)
 vdev->config_offset + PCI_CAPABILITY_LIST);
 if (ret != 1 || !is_valid_std_cap_offset(tmp)) {
 error_setg(errp, "NVIDIA GPUDirect Clique ID: error getting cap list");
-return -EINVAL;
+return false;
 }
 
 do {
@@ -1590,13 +1590,13 @@ static int vfio_add_nv_gpudirect_cap(VFIOPCIDevice 
*vdev, Error **errp)
 pos = 0xD4;
 } else {
 error_setg(errp, "NVIDIA GPUDirect Clique ID: invalid config space");
-return -EINVAL;
+return false;
 }
 
 ret = pci_add_capability(pdev, PCI_CAP_ID_VNDR, pos, 8, errp);
 if (ret < 0) {
 error_prepend(errp, "Failed to add NVIDIA GPUDirect cap: ");
-return ret;
+return false;
 }
 
 memset(vdev->emulated_config_bits + pos, 0xFF, 8);
@@ -1608,7 +1608,7 @@ static int vfio_add_nv_gpudirect_cap(VFIOPCIDevice *vdev, 
Error **errp)
 pci_set_byte(pdev->config + pos++, vdev->nv_gpudirect_clique << 3);
 pci_set_byte(pdev->config + pos, 0);
 
-return 0;
+return true;
 }
 
 /*
@@ -1629,7 +1629,7 @@ static int vfio_add_nv_gpudirect_cap(VFIOPCIDevice *vdev, 
Error **errp)
  */
 #define VMD_SHADOW_CAP_VER 1
 #define VMD_SHADOW_CAP_LEN 24
-static int vfio_add_vmd_shadow_cap(VFIOPCIDevice *vdev, Error **errp)
+static bool vfio_add_vmd_shadow_cap(VFIOPCIDevice *vdev, Error **errp)
 {
 ERRP_GUARD();
 uint8_t membar_phys[16];
@@ -1639,7 +1639,7 @@ static int vfio_add_vmd_shadow_cap(VFIOPCIDevice *vdev, 
Error **errp)
   vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, 0x467F) ||
   vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, 0x4C3D) ||
   vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, 0x9A0B))) {
-return 0;
+return true;
 }
 
 ret = pread(vdev->vbasedev.fd, membar_phys, 16,
@@ -1647,14 +1647,14 @@ static int vfio_add_vmd_shadow_cap(VFIOPCIDevice *vdev, 
Error **errp)
 if (ret != 16) {
 error_report("VMD %s cannot read MEMBARs (%d)",
  vdev->vbasedev.name, ret);
-return -EFAULT;
+return false;
 }
 
 ret = pci_add_capability(>pdev, PCI_CAP_ID_VNDR, pos,
  VMD_SHADOW_CAP_LEN, errp);
 if (ret < 0) {
 error_prepend(errp, "Failed to add VMD MEMBAR Shadow cap: ");
-return ret;
+return false;
 }
 
 memset(v

[PULL 46/47] vfio: Use g_autofree in all call site of vfio_get_region_info()

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

There are some exceptions when pointer to vfio_region_info is reused.
In that case, the pointed memory is freed manually.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/helpers.c |  7 ++-
 hw/vfio/igd.c |  5 ++---
 hw/vfio/pci.c | 13 +++--
 3 files changed, 7 insertions(+), 18 deletions(-)

diff --git a/hw/vfio/helpers.c b/hw/vfio/helpers.c
index 
4b079dc383683a71d1d96507a0fb66a4bc3ba923..27ea26aa48f67e6518f871ac651ab8d2703cc611
 100644
--- a/hw/vfio/helpers.c
+++ b/hw/vfio/helpers.c
@@ -343,7 +343,7 @@ static int vfio_setup_region_sparse_mmaps(VFIORegion 
*region,
 int vfio_region_setup(Object *obj, VFIODevice *vbasedev, VFIORegion *region,
   int index, const char *name)
 {
-struct vfio_region_info *info;
+g_autofree struct vfio_region_info *info = NULL;
 int ret;
 
 ret = vfio_get_region_info(vbasedev, index, );
@@ -376,8 +376,6 @@ int vfio_region_setup(Object *obj, VFIODevice *vbasedev, 
VFIORegion *region,
 }
 }
 
-g_free(info);
-
 trace_vfio_region_setup(vbasedev->name, index, name,
 region->flags, region->fd_offset, region->size);
 return 0;
@@ -594,14 +592,13 @@ int vfio_get_dev_region_info(VFIODevice *vbasedev, 
uint32_t type,
 
 bool vfio_has_region_cap(VFIODevice *vbasedev, int region, uint16_t cap_type)
 {
-struct vfio_region_info *info = NULL;
+g_autofree struct vfio_region_info *info = NULL;
 bool ret = false;
 
 if (!vfio_get_region_info(vbasedev, region, )) {
 if (vfio_get_region_info_cap(info, cap_type)) {
 ret = true;
 }
-g_free(info);
 }
 
 return ret;
diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
index 
402fc5ce1da966fda1340f328e0611cb1a2a0635..1e79202f2bd136b0bafd4f08c2f1407e467e0d65
 100644
--- a/hw/vfio/igd.c
+++ b/hw/vfio/igd.c
@@ -367,8 +367,8 @@ static const MemoryRegionOps vfio_igd_index_quirk = {
 
 void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
 {
-struct vfio_region_info *rom = NULL, *opregion = NULL,
-*host = NULL, *lpc = NULL;
+g_autofree struct vfio_region_info *rom = NULL;
+struct vfio_region_info *opregion = NULL, *host = NULL, *lpc = NULL;
 VFIOQuirk *quirk;
 VFIOIGDQuirk *igd;
 PCIDevice *lpc_bridge;
@@ -609,7 +609,6 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
 trace_vfio_pci_igd_bdsm_enabled(vdev->vbasedev.name, ggms_mb + gms_mb);
 
 out:
-g_free(rom);
 g_free(opregion);
 g_free(host);
 g_free(lpc);
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 
35ad9b582f6b99510a812edab5c2855c697a1da2..74a79bdf61f9aeb4860d532b6c076dd3491dd0ab
 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -879,7 +879,7 @@ static void vfio_update_msi(VFIOPCIDevice *vdev)
 
 static void vfio_pci_load_rom(VFIOPCIDevice *vdev)
 {
-struct vfio_region_info *reg_info;
+g_autofree struct vfio_region_info *reg_info = NULL;
 uint64_t size;
 off_t off = 0;
 ssize_t bytes;
@@ -897,8 +897,6 @@ static void vfio_pci_load_rom(VFIOPCIDevice *vdev)
 vdev->rom_size = size = reg_info->size;
 vdev->rom_offset = reg_info->offset;
 
-g_free(reg_info);
-
 if (!vdev->rom_size) {
 vdev->rom_read_failed = true;
 error_report("vfio-pci: Cannot read device rom at "
@@ -2668,7 +2666,7 @@ static VFIODeviceOps vfio_pci_ops = {
 bool vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp)
 {
 VFIODevice *vbasedev = >vbasedev;
-struct vfio_region_info *reg_info;
+g_autofree struct vfio_region_info *reg_info = NULL;
 int ret;
 
 ret = vfio_get_region_info(vbasedev, VFIO_PCI_VGA_REGION_INDEX, _info);
@@ -2685,7 +2683,6 @@ bool vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp)
 error_setg(errp, "unexpected VGA info, flags 0x%lx, size 0x%lx",
(unsigned long)reg_info->flags,
(unsigned long)reg_info->size);
-g_free(reg_info);
 return false;
 }
 
@@ -2694,8 +2691,6 @@ bool vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp)
 vdev->vga->fd_offset = reg_info->offset;
 vdev->vga->fd = vdev->vbasedev.fd;
 
-g_free(reg_info);
-
 vdev->vga->region[QEMU_PCI_VGA_MEM].offset = QEMU_PCI_VGA_MEM_BASE;
 vdev->vga->region[QEMU_PCI_VGA_MEM].nr = QEMU_PCI_VGA_MEM;
 QLIST_INIT(>vga->region[QEMU_PCI_VGA_MEM].quirks);
@@ -2736,7 +2731,7 @@ bool vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp)
 static bool vfio_populate_device(VFIOPCIDevice *vdev, Error **errp)
 {
 VFIODevice *vbasedev = >vbasedev;
-struct vfio_region_info *reg_info;
+g_autofree struct vfio_region_info *reg_info = NULL;
 struct vfio_irq_info irq_info = { .argsz = sizeof(irq_info) };
 int i, ret = -1;
 
@@ -27

[PULL 16/47] vfio/migration: Emit VFIO migration QAPI event

2024-05-22 Thread Cédric Le Goater
From: Avihai Horon 

Emit VFIO migration QAPI event when a VFIO device changes its migration
state. This can be used by management applications to get updates on the
current state of the VFIO device for their own purposes.

A new per VFIO device capability, "migration-events", is added so events
can be enabled only for the required devices. It is disabled by default.

Signed-off-by: Avihai Horon 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 include/hw/vfio/vfio-common.h |  1 +
 hw/vfio/migration.c   | 59 +--
 hw/vfio/pci.c |  2 ++
 3 files changed, 59 insertions(+), 3 deletions(-)

diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index 
b6ac24953667bc5f72f28480a6bf0f4722069cb9..878e34a12874f63fcb8bbc8dc8ca3d2dfa84fdb4
 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -115,6 +115,7 @@ typedef struct VFIODevice {
 bool no_mmap;
 bool ram_block_discard_allowed;
 OnOffAuto enable_migration;
+bool migration_events;
 VFIODeviceOps *ops;
 unsigned int num_irqs;
 unsigned int num_regions;
diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
index 
c4403a38ddb5e7e09fbcde0ad4132653ecaf0d24..af579b868d7caa726fde1eeb73c832ebc3136a7a
 100644
--- a/hw/vfio/migration.c
+++ b/hw/vfio/migration.c
@@ -24,6 +24,7 @@
 #include "migration/register.h"
 #include "migration/blocker.h"
 #include "qapi/error.h"
+#include "qapi/qapi-events-vfio.h"
 #include "exec/ramlist.h"
 #include "exec/ram_addr.h"
 #include "pci.h"
@@ -80,6 +81,58 @@ static const char *mig_state_to_str(enum 
vfio_device_mig_state state)
 }
 }
 
+static VfioMigrationState
+mig_state_to_qapi_state(enum vfio_device_mig_state state)
+{
+switch (state) {
+case VFIO_DEVICE_STATE_STOP:
+return QAPI_VFIO_MIGRATION_STATE_STOP;
+case VFIO_DEVICE_STATE_RUNNING:
+return QAPI_VFIO_MIGRATION_STATE_RUNNING;
+case VFIO_DEVICE_STATE_STOP_COPY:
+return QAPI_VFIO_MIGRATION_STATE_STOP_COPY;
+case VFIO_DEVICE_STATE_RESUMING:
+return QAPI_VFIO_MIGRATION_STATE_RESUMING;
+case VFIO_DEVICE_STATE_RUNNING_P2P:
+return QAPI_VFIO_MIGRATION_STATE_RUNNING_P2P;
+case VFIO_DEVICE_STATE_PRE_COPY:
+return QAPI_VFIO_MIGRATION_STATE_PRE_COPY;
+case VFIO_DEVICE_STATE_PRE_COPY_P2P:
+return QAPI_VFIO_MIGRATION_STATE_PRE_COPY_P2P;
+default:
+g_assert_not_reached();
+}
+}
+
+static void vfio_migration_send_event(VFIODevice *vbasedev)
+{
+VFIOMigration *migration = vbasedev->migration;
+DeviceState *dev = vbasedev->dev;
+g_autofree char *qom_path = NULL;
+Object *obj;
+
+if (!vbasedev->migration_events) {
+return;
+}
+
+g_assert(vbasedev->ops->vfio_get_object);
+obj = vbasedev->ops->vfio_get_object(vbasedev);
+g_assert(obj);
+qom_path = object_get_canonical_path(obj);
+
+qapi_event_send_vfio_migration(
+dev->id, qom_path, mig_state_to_qapi_state(migration->device_state));
+}
+
+static void vfio_migration_set_device_state(VFIODevice *vbasedev,
+enum vfio_device_mig_state state)
+{
+VFIOMigration *migration = vbasedev->migration;
+
+migration->device_state = state;
+vfio_migration_send_event(vbasedev);
+}
+
 static int vfio_migration_set_state(VFIODevice *vbasedev,
 enum vfio_device_mig_state new_state,
 enum vfio_device_mig_state recover_state,
@@ -131,12 +184,12 @@ static int vfio_migration_set_state(VFIODevice *vbasedev,
 goto reset_device;
 }
 
-migration->device_state = recover_state;
+vfio_migration_set_device_state(vbasedev, recover_state);
 
 return ret;
 }
 
-migration->device_state = new_state;
+vfio_migration_set_device_state(vbasedev, new_state);
 if (mig_state->data_fd != -1) {
 if (migration->data_fd != -1) {
 /*
@@ -162,7 +215,7 @@ reset_device:
  strerror(errno));
 }
 
-migration->device_state = VFIO_DEVICE_STATE_RUNNING;
+vfio_migration_set_device_state(vbasedev, VFIO_DEVICE_STATE_RUNNING);
 
 return ret;
 }
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 
4789d43c0f9cc7ef94b73adc815377f7222d8c57..b5d1d398b120076c85cdd92d61793393f65e8554
 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -3388,6 +3388,8 @@ static Property vfio_pci_dev_properties[] = {
 VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT, false),
 DEFINE_PROP_ON_OFF_AUTO("enable-migration", VFIOPCIDevice,
 vbasedev.enable_migration, ON_OFF_AUTO_AUTO),
+DEFINE_PROP_BOOL("migration-events", VFIOPCIDevice,
+ vbasedev.migration_

[PULL 21/47] vfio: Make VFIOIOMMUClass::attach_device() and its wrapper return bool

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

Make VFIOIOMMUClass::attach_device() and its wrapper function
vfio_attach_device() return bool.

This is to follow the coding standand to return bool if 'Error **'
is used to pass error.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 include/hw/vfio/vfio-common.h |  4 ++--
 include/hw/vfio/vfio-container-base.h |  4 ++--
 hw/vfio/ap.c  |  6 ++
 hw/vfio/ccw.c |  6 ++
 hw/vfio/common.c  |  4 ++--
 hw/vfio/container.c   | 14 +++---
 hw/vfio/iommufd.c | 11 +--
 hw/vfio/pci.c |  5 ++---
 hw/vfio/platform.c|  7 +++
 9 files changed, 27 insertions(+), 34 deletions(-)

diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index 
878e34a12874f63fcb8bbc8dc8ca3d2dfa84fdb4..e85817e65e65317d08bc2b17b738449198784796
 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -222,8 +222,8 @@ void vfio_region_exit(VFIORegion *region);
 void vfio_region_finalize(VFIORegion *region);
 void vfio_reset_handler(void *opaque);
 struct vfio_device_info *vfio_get_device_info(int fd);
-int vfio_attach_device(char *name, VFIODevice *vbasedev,
-   AddressSpace *as, Error **errp);
+bool vfio_attach_device(char *name, VFIODevice *vbasedev,
+AddressSpace *as, Error **errp);
 void vfio_detach_device(VFIODevice *vbasedev);
 
 int vfio_kvm_device_add_fd(int fd, Error **errp);
diff --git a/include/hw/vfio/vfio-container-base.h 
b/include/hw/vfio/vfio-container-base.h
index 
b04057ad1aff73d974ecec718d0fe45f7a930b59..44927ca8c3583246145defe043ac34da604d39bf
 100644
--- a/include/hw/vfio/vfio-container-base.h
+++ b/include/hw/vfio/vfio-container-base.h
@@ -117,8 +117,8 @@ struct VFIOIOMMUClass {
 int (*dma_unmap)(const VFIOContainerBase *bcontainer,
  hwaddr iova, ram_addr_t size,
  IOMMUTLBEntry *iotlb);
-int (*attach_device)(const char *name, VFIODevice *vbasedev,
- AddressSpace *as, Error **errp);
+bool (*attach_device)(const char *name, VFIODevice *vbasedev,
+  AddressSpace *as, Error **errp);
 void (*detach_device)(VFIODevice *vbasedev);
 
 /* migration feature */
diff --git a/hw/vfio/ap.c b/hw/vfio/ap.c
index 
8bb024e2fde4a1d72346dee4b662d762374326b9..ba653ef70f08ebdf482009baafc62eb33ebda9a8
 100644
--- a/hw/vfio/ap.c
+++ b/hw/vfio/ap.c
@@ -154,7 +154,6 @@ static void vfio_ap_unregister_irq_notifier(VFIOAPDevice 
*vapdev,
 static void vfio_ap_realize(DeviceState *dev, Error **errp)
 {
 ERRP_GUARD();
-int ret;
 Error *err = NULL;
 VFIOAPDevice *vapdev = VFIO_AP_DEVICE(dev);
 VFIODevice *vbasedev = >vdev;
@@ -163,9 +162,8 @@ static void vfio_ap_realize(DeviceState *dev, Error **errp)
 return;
 }
 
-ret = vfio_attach_device(vbasedev->name, vbasedev,
- _space_memory, errp);
-if (ret) {
+if (!vfio_attach_device(vbasedev->name, vbasedev,
+_space_memory, errp)) {
 goto error;
 }
 
diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 
1c630f6e9abe93ae0c2b5615d4409669f096c8c9..89bb98016764e65cf826183d7a38c59d429f6eeb
 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -579,7 +579,6 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)
 S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
 VFIODevice *vbasedev = >vdev;
 Error *err = NULL;
-int ret;
 
 /* Call the class init function for subchannel. */
 if (cdc->realize) {
@@ -593,9 +592,8 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)
 return;
 }
 
-ret = vfio_attach_device(cdev->mdevid, vbasedev,
- _space_memory, errp);
-if (ret) {
+if (!vfio_attach_device(cdev->mdevid, vbasedev,
+_space_memory, errp)) {
 goto out_attach_dev_err;
 }
 
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 
1fbd10801d35079341a833fa68a43de2b758cde0..c04a259ffd7cfcfba480335bea1ddff787f47bdc
 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -1523,8 +1523,8 @@ retry:
 return info;
 }
 
-int vfio_attach_device(char *name, VFIODevice *vbasedev,
-   AddressSpace *as, Error **errp)
+bool vfio_attach_device(char *name, VFIODevice *vbasedev,
+AddressSpace *as, Error **errp)
 {
 const VFIOIOMMUClass *ops =
 VFIO_IOMMU_CLASS(object_class_by_name(TYPE_VFIO_IOMMU_LEGACY));
diff --git a/hw/vfio/container.c b/hw/vfio/container.c
index 
9534120d4ac835bb58e37667dad8d39205404c08..e7c416774791d506cc7c4696fb6a6d94dc809c8e
 100644
--- a/hw/vfio/container.c
+++ b/hw/vfio/container.c
@@ -910,8 +910,8 @@ static in

[PULL 22/47] vfio: Make VFIOIOMMUClass::setup() return bool

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

This is to follow the coding standand to return bool if 'Error **'
is used to pass error.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 include/hw/vfio/vfio-container-base.h |  2 +-
 hw/vfio/container.c   | 10 +-
 hw/vfio/spapr.c   | 12 +---
 3 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/include/hw/vfio/vfio-container-base.h 
b/include/hw/vfio/vfio-container-base.h
index 
44927ca8c3583246145defe043ac34da604d39bf..202e23cb6b800983b036bf3808c0ec38b1c363d0
 100644
--- a/include/hw/vfio/vfio-container-base.h
+++ b/include/hw/vfio/vfio-container-base.h
@@ -110,7 +110,7 @@ struct VFIOIOMMUClass {
 InterfaceClass parent_class;
 
 /* basic feature */
-int (*setup)(VFIOContainerBase *bcontainer, Error **errp);
+bool (*setup)(VFIOContainerBase *bcontainer, Error **errp);
 int (*dma_map)(const VFIOContainerBase *bcontainer,
hwaddr iova, ram_addr_t size,
void *vaddr, bool readonly);
diff --git a/hw/vfio/container.c b/hw/vfio/container.c
index 
e7c416774791d506cc7c4696fb6a6d94dc809c8e..f2e9560a1906c4151535260e3488ee80ca90e78b
 100644
--- a/hw/vfio/container.c
+++ b/hw/vfio/container.c
@@ -507,7 +507,7 @@ static void vfio_get_iommu_info_migration(VFIOContainer 
*container,
 }
 }
 
-static int vfio_legacy_setup(VFIOContainerBase *bcontainer, Error **errp)
+static bool vfio_legacy_setup(VFIOContainerBase *bcontainer, Error **errp)
 {
 VFIOContainer *container = container_of(bcontainer, VFIOContainer,
 bcontainer);
@@ -517,7 +517,7 @@ static int vfio_legacy_setup(VFIOContainerBase *bcontainer, 
Error **errp)
 ret = vfio_get_iommu_info(container, );
 if (ret) {
 error_setg_errno(errp, -ret, "Failed to get VFIO IOMMU info");
-return ret;
+return false;
 }
 
 if (info->flags & VFIO_IOMMU_INFO_PGSIZES) {
@@ -533,7 +533,7 @@ static int vfio_legacy_setup(VFIOContainerBase *bcontainer, 
Error **errp)
 vfio_get_info_iova_range(info, bcontainer);
 
 vfio_get_iommu_info_migration(container, info);
-return 0;
+return true;
 }
 
 static int vfio_connect_container(VFIOGroup *group, AddressSpace *as,
@@ -635,8 +635,8 @@ static int vfio_connect_container(VFIOGroup *group, 
AddressSpace *as,
 
 assert(bcontainer->ops->setup);
 
-ret = bcontainer->ops->setup(bcontainer, errp);
-if (ret) {
+if (!bcontainer->ops->setup(bcontainer, errp)) {
+ret = -EINVAL;
 goto enable_discards_exit;
 }
 
diff --git a/hw/vfio/spapr.c b/hw/vfio/spapr.c
index 
0d949bb728212534a7e2296e491aa8d95f45945d..148b257c9ca6a0f957115f8060ddb50e377dfcb8
 100644
--- a/hw/vfio/spapr.c
+++ b/hw/vfio/spapr.c
@@ -458,8 +458,8 @@ static void vfio_spapr_container_release(VFIOContainerBase 
*bcontainer)
 }
 }
 
-static int vfio_spapr_container_setup(VFIOContainerBase *bcontainer,
-  Error **errp)
+static bool vfio_spapr_container_setup(VFIOContainerBase *bcontainer,
+   Error **errp)
 {
 VFIOContainer *container = container_of(bcontainer, VFIOContainer,
 bcontainer);
@@ -480,7 +480,7 @@ static int vfio_spapr_container_setup(VFIOContainerBase 
*bcontainer,
 ret = ioctl(fd, VFIO_IOMMU_ENABLE);
 if (ret) {
 error_setg_errno(errp, errno, "failed to enable container");
-return -errno;
+return false;
 }
 } else {
 scontainer->prereg_listener = vfio_prereg_listener;
@@ -488,7 +488,6 @@ static int vfio_spapr_container_setup(VFIOContainerBase 
*bcontainer,
 memory_listener_register(>prereg_listener,
  _space_memory);
 if (bcontainer->error) {
-ret = -1;
 error_propagate_prepend(errp, bcontainer->error,
 "RAM memory listener initialization failed: ");
 goto listener_unregister_exit;
@@ -500,7 +499,6 @@ static int vfio_spapr_container_setup(VFIOContainerBase 
*bcontainer,
 if (ret) {
 error_setg_errno(errp, errno,
  "VFIO_IOMMU_SPAPR_TCE_GET_INFO failed");
-ret = -errno;
 goto listener_unregister_exit;
 }
 
@@ -527,13 +525,13 @@ static int vfio_spapr_container_setup(VFIOContainerBase 
*bcontainer,
   0x1000);
 }
 
-return 0;
+return true;
 
 listener_unregister_exit:
 if (v2) {
 memory_listener_unregister(>prereg_listener);
 }
-return ret;
+return false;
 }
 
 static void vfio_iommu_spapr_class_init(ObjectClass *klass, void *data)
-- 
2.45.1




[PULL 27/47] vfio/iommufd: Make iommufd_cdev_*() return bool

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

This is to follow the coding standand to return bool if 'Error **'
is used to pass error.

The changed functions include:

iommufd_cdev_kvm_device_add
iommufd_cdev_connect_and_bind
iommufd_cdev_attach_ioas_hwpt
iommufd_cdev_detach_ioas_hwpt
iommufd_cdev_attach_container
iommufd_cdev_get_info_iova_range

After the change, all functions in hw/vfio/iommufd.c follows the
standand.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/iommufd.c | 88 +--
 1 file changed, 39 insertions(+), 49 deletions(-)

diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
index 
4c6992fca11969bc8fe26c11e902e2521d6bff7a..84c86b970e756d34b202d5b18ae51c30c730e092
 100644
--- a/hw/vfio/iommufd.c
+++ b/hw/vfio/iommufd.c
@@ -49,9 +49,9 @@ static int iommufd_cdev_unmap(const VFIOContainerBase 
*bcontainer,
  container->ioas_id, iova, size);
 }
 
-static int iommufd_cdev_kvm_device_add(VFIODevice *vbasedev, Error **errp)
+static bool iommufd_cdev_kvm_device_add(VFIODevice *vbasedev, Error **errp)
 {
-return vfio_kvm_device_add_fd(vbasedev->fd, errp);
+return !vfio_kvm_device_add_fd(vbasedev->fd, errp);
 }
 
 static void iommufd_cdev_kvm_device_del(VFIODevice *vbasedev)
@@ -63,18 +63,16 @@ static void iommufd_cdev_kvm_device_del(VFIODevice 
*vbasedev)
 }
 }
 
-static int iommufd_cdev_connect_and_bind(VFIODevice *vbasedev, Error **errp)
+static bool iommufd_cdev_connect_and_bind(VFIODevice *vbasedev, Error **errp)
 {
 IOMMUFDBackend *iommufd = vbasedev->iommufd;
 struct vfio_device_bind_iommufd bind = {
 .argsz = sizeof(bind),
 .flags = 0,
 };
-int ret;
 
-ret = iommufd_backend_connect(iommufd, errp);
-if (ret) {
-return ret;
+if (iommufd_backend_connect(iommufd, errp)) {
+return false;
 }
 
 /*
@@ -82,15 +80,13 @@ static int iommufd_cdev_connect_and_bind(VFIODevice 
*vbasedev, Error **errp)
  * in KVM. Especially for some emulated devices, it requires
  * to have kvm information in the device open.
  */
-ret = iommufd_cdev_kvm_device_add(vbasedev, errp);
-if (ret) {
+if (!iommufd_cdev_kvm_device_add(vbasedev, errp)) {
 goto err_kvm_device_add;
 }
 
 /* Bind device to iommufd */
 bind.iommufd = iommufd->fd;
-ret = ioctl(vbasedev->fd, VFIO_DEVICE_BIND_IOMMUFD, );
-if (ret) {
+if (ioctl(vbasedev->fd, VFIO_DEVICE_BIND_IOMMUFD, )) {
 error_setg_errno(errp, errno, "error bind device fd=%d to iommufd=%d",
  vbasedev->fd, bind.iommufd);
 goto err_bind;
@@ -99,12 +95,12 @@ static int iommufd_cdev_connect_and_bind(VFIODevice 
*vbasedev, Error **errp)
 vbasedev->devid = bind.out_devid;
 trace_iommufd_cdev_connect_and_bind(bind.iommufd, vbasedev->name,
 vbasedev->fd, vbasedev->devid);
-return ret;
+return true;
 err_bind:
 iommufd_cdev_kvm_device_del(vbasedev);
 err_kvm_device_add:
 iommufd_backend_disconnect(iommufd);
-return ret;
+return false;
 }
 
 static void iommufd_cdev_unbind_and_disconnect(VFIODevice *vbasedev)
@@ -176,10 +172,10 @@ out:
 return ret;
 }
 
-static int iommufd_cdev_attach_ioas_hwpt(VFIODevice *vbasedev, uint32_t id,
+static bool iommufd_cdev_attach_ioas_hwpt(VFIODevice *vbasedev, uint32_t id,
  Error **errp)
 {
-int ret, iommufd = vbasedev->iommufd->fd;
+int iommufd = vbasedev->iommufd->fd;
 struct vfio_device_attach_iommufd_pt attach_data = {
 .argsz = sizeof(attach_data),
 .flags = 0,
@@ -187,38 +183,38 @@ static int iommufd_cdev_attach_ioas_hwpt(VFIODevice 
*vbasedev, uint32_t id,
 };
 
 /* Attach device to an IOAS or hwpt within iommufd */
-ret = ioctl(vbasedev->fd, VFIO_DEVICE_ATTACH_IOMMUFD_PT, _data);
-if (ret) {
+if (ioctl(vbasedev->fd, VFIO_DEVICE_ATTACH_IOMMUFD_PT, _data)) {
 error_setg_errno(errp, errno,
  "[iommufd=%d] error attach %s (%d) to id=%d",
  iommufd, vbasedev->name, vbasedev->fd, id);
-} else {
-trace_iommufd_cdev_attach_ioas_hwpt(iommufd, vbasedev->name,
-vbasedev->fd, id);
+return false;
 }
-return ret;
+
+trace_iommufd_cdev_attach_ioas_hwpt(iommufd, vbasedev->name,
+vbasedev->fd, id);
+return true;
 }
 
-static int iommufd_cdev_detach_ioas_hwpt(VFIODevice *vbasedev, Error **errp)
+static bool iommufd_cdev_detach_ioas_hwpt(VFIODevice *vbasedev, Error **errp)
 {
-int ret, iommufd = vbasedev->iommufd->fd;
+int iommufd = vbasedev->iommufd->fd;
 struct vfio_device_detach_iommufd_pt detach_data

[PULL 29/47] backends/iommufd: Make iommufd_backend_*() return bool

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

This is to follow the coding standand to return bool if 'Error **'
is used to pass error.

The changed functions include:

iommufd_backend_connect
iommufd_backend_alloc_ioas

By this chance, simplify the functions a bit by avoiding duplicate
recordings, e.g., log through either error interface or trace, not
both.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 include/sysemu/iommufd.h |  6 +++---
 backends/iommufd.c   | 29 +
 hw/vfio/iommufd.c|  5 ++---
 backends/trace-events|  4 ++--
 4 files changed, 20 insertions(+), 24 deletions(-)

diff --git a/include/sysemu/iommufd.h b/include/sysemu/iommufd.h
index 
9af27ebd6ccb78ca8e16aa3c62629aab9f7f31e4..293bfbe967215381532b8267227dde61fa9157b7
 100644
--- a/include/sysemu/iommufd.h
+++ b/include/sysemu/iommufd.h
@@ -23,11 +23,11 @@ struct IOMMUFDBackend {
 /*< public >*/
 };
 
-int iommufd_backend_connect(IOMMUFDBackend *be, Error **errp);
+bool iommufd_backend_connect(IOMMUFDBackend *be, Error **errp);
 void iommufd_backend_disconnect(IOMMUFDBackend *be);
 
-int iommufd_backend_alloc_ioas(IOMMUFDBackend *be, uint32_t *ioas_id,
-   Error **errp);
+bool iommufd_backend_alloc_ioas(IOMMUFDBackend *be, uint32_t *ioas_id,
+Error **errp);
 void iommufd_backend_free_id(IOMMUFDBackend *be, uint32_t id);
 int iommufd_backend_map_dma(IOMMUFDBackend *be, uint32_t ioas_id, hwaddr iova,
 ram_addr_t size, void *vaddr, bool readonly);
diff --git a/backends/iommufd.c b/backends/iommufd.c
index 
76a0204852f73466a9f31492a08d89d468bff7c0..c506afbdac4beddb7dac88f74f10544f7a083e58
 100644
--- a/backends/iommufd.c
+++ b/backends/iommufd.c
@@ -72,24 +72,22 @@ static void iommufd_backend_class_init(ObjectClass *oc, 
void *data)
 object_class_property_add_str(oc, "fd", NULL, iommufd_backend_set_fd);
 }
 
-int iommufd_backend_connect(IOMMUFDBackend *be, Error **errp)
+bool iommufd_backend_connect(IOMMUFDBackend *be, Error **errp)
 {
-int fd, ret = 0;
+int fd;
 
 if (be->owned && !be->users) {
 fd = qemu_open_old("/dev/iommu", O_RDWR);
 if (fd < 0) {
 error_setg_errno(errp, errno, "/dev/iommu opening failed");
-ret = fd;
-goto out;
+return false;
 }
 be->fd = fd;
 }
 be->users++;
-out:
-trace_iommufd_backend_connect(be->fd, be->owned,
-  be->users, ret);
-return ret;
+
+trace_iommufd_backend_connect(be->fd, be->owned, be->users);
+return true;
 }
 
 void iommufd_backend_disconnect(IOMMUFDBackend *be)
@@ -106,25 +104,24 @@ out:
 trace_iommufd_backend_disconnect(be->fd, be->users);
 }
 
-int iommufd_backend_alloc_ioas(IOMMUFDBackend *be, uint32_t *ioas_id,
-   Error **errp)
+bool iommufd_backend_alloc_ioas(IOMMUFDBackend *be, uint32_t *ioas_id,
+Error **errp)
 {
-int ret, fd = be->fd;
+int fd = be->fd;
 struct iommu_ioas_alloc alloc_data  = {
 .size = sizeof(alloc_data),
 .flags = 0,
 };
 
-ret = ioctl(fd, IOMMU_IOAS_ALLOC, _data);
-if (ret) {
+if (ioctl(fd, IOMMU_IOAS_ALLOC, _data)) {
 error_setg_errno(errp, errno, "Failed to allocate ioas");
-return ret;
+return false;
 }
 
 *ioas_id = alloc_data.out_ioas_id;
-trace_iommufd_backend_alloc_ioas(fd, *ioas_id, ret);
+trace_iommufd_backend_alloc_ioas(fd, *ioas_id);
 
-return ret;
+return true;
 }
 
 void iommufd_backend_free_id(IOMMUFDBackend *be, uint32_t id)
diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
index 
6a446b16dcd64838dc9ebb6150cd5ed85ec6fef3..554f9a6292454f51015ab3a56df3fab6a482ccb7
 100644
--- a/hw/vfio/iommufd.c
+++ b/hw/vfio/iommufd.c
@@ -71,7 +71,7 @@ static bool iommufd_cdev_connect_and_bind(VFIODevice 
*vbasedev, Error **errp)
 .flags = 0,
 };
 
-if (iommufd_backend_connect(iommufd, errp)) {
+if (!iommufd_backend_connect(iommufd, errp)) {
 return false;
 }
 
@@ -346,8 +346,7 @@ static bool iommufd_cdev_attach(const char *name, 
VFIODevice *vbasedev,
 }
 
 /* Need to allocate a new dedicated container */
-ret = iommufd_backend_alloc_ioas(vbasedev->iommufd, _id, errp);
-if (ret < 0) {
+if (!iommufd_backend_alloc_ioas(vbasedev->iommufd, _id, errp)) {
 goto err_alloc_ioas;
 }
 
diff --git a/backends/trace-events b/backends/trace-events
index 
d45c6e31a67ed66d94787f60eb08a525cf6ff68b..211e6f374adcef25be0409ce3e42cbed6f31b744
 100644
--- a/backends/trace-events
+++ b/backends/trace-events
@@ -7,11 +7,11 @@ dbus_vmstate_loading(const char *id) "id: %s"
 dbus_vmstate_saving(const char *id) "

[PULL 13/47] vfio/ccw: Make vfio_ccw_register_irq_notifier() return a bool

2024-05-22 Thread Cédric Le Goater
Since vfio_ccw_register_irq_notifier() takes an 'Error **' argument,
best practices suggest to return a bool. See the qapi/error.h Rules
section.

Reviewed-by: Markus Armbruster 
Reviewed-by: Eric Farman 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/ccw.c | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 
6764388bc47a970329fce2233626ccb8178e0165..1c630f6e9abe93ae0c2b5615d4409669f096c8c9
 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -379,7 +379,7 @@ read_err:
 css_inject_io_interrupt(sch);
 }
 
-static void vfio_ccw_register_irq_notifier(VFIOCCWDevice *vcdev,
+static bool vfio_ccw_register_irq_notifier(VFIOCCWDevice *vcdev,
unsigned int irq,
Error **errp)
 {
@@ -405,13 +405,13 @@ static void vfio_ccw_register_irq_notifier(VFIOCCWDevice 
*vcdev,
 break;
 default:
 error_setg(errp, "vfio: Unsupported device irq(%d)", irq);
-return;
+return false;
 }
 
 if (vdev->num_irqs < irq + 1) {
 error_setg(errp, "vfio: IRQ %u not available (number of irqs %u)",
irq, vdev->num_irqs);
-return;
+return false;
 }
 
 argsz = sizeof(*irq_info);
@@ -421,14 +421,14 @@ static void vfio_ccw_register_irq_notifier(VFIOCCWDevice 
*vcdev,
 if (ioctl(vdev->fd, VFIO_DEVICE_GET_IRQ_INFO,
   irq_info) < 0 || irq_info->count < 1) {
 error_setg_errno(errp, errno, "vfio: Error getting irq info");
-return;
+return false;
 }
 
 if (event_notifier_init(notifier, 0)) {
 error_setg_errno(errp, errno,
  "vfio: Unable to init event notifier for irq (%d)",
  irq);
-return;
+return false;
 }
 
 fd = event_notifier_get_fd(notifier);
@@ -439,6 +439,8 @@ static void vfio_ccw_register_irq_notifier(VFIOCCWDevice 
*vcdev,
 qemu_set_fd_handler(fd, NULL, NULL, vcdev);
 event_notifier_cleanup(notifier);
 }
+
+return true;
 }
 
 static void vfio_ccw_unregister_irq_notifier(VFIOCCWDevice *vcdev,
@@ -602,20 +604,18 @@ static void vfio_ccw_realize(DeviceState *dev, Error 
**errp)
 goto out_region_err;
 }
 
-vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX, );
-if (err) {
+if (!vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX, )) {
 goto out_io_notifier_err;
 }
 
 if (vcdev->crw_region) {
-vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX, );
-if (err) {
+if (!vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX,
+)) {
 goto out_irq_notifier_err;
 }
 }
 
-vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_REQ_IRQ_INDEX, );
-if (err) {
+if (!vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_REQ_IRQ_INDEX, )) {
 /*
  * Report this error, but do not make it a failing condition.
  * Lack of this IRQ in the host does not prevent normal operation.
-- 
2.45.1




[PULL 47/47] vfio/igd: Use g_autofree in vfio_probe_igd_bar4_quirk()

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

Pointer opregion, host and lpc are allocated and freed in
vfio_probe_igd_bar4_quirk(). Use g_autofree to automatically
free them.

Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/igd.c | 27 ---
 1 file changed, 12 insertions(+), 15 deletions(-)

diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
index 
1e79202f2bd136b0bafd4f08c2f1407e467e0d65..d320d032a7f3b19df0d055178f6fefe4bdfd8668
 100644
--- a/hw/vfio/igd.c
+++ b/hw/vfio/igd.c
@@ -368,7 +368,9 @@ static const MemoryRegionOps vfio_igd_index_quirk = {
 void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
 {
 g_autofree struct vfio_region_info *rom = NULL;
-struct vfio_region_info *opregion = NULL, *host = NULL, *lpc = NULL;
+g_autofree struct vfio_region_info *opregion = NULL;
+g_autofree struct vfio_region_info *host = NULL;
+g_autofree struct vfio_region_info *lpc = NULL;
 VFIOQuirk *quirk;
 VFIOIGDQuirk *igd;
 PCIDevice *lpc_bridge;
@@ -426,7 +428,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
 if ((ret || !rom->size) && !vdev->pdev.romfile) {
 error_report("IGD device %s has no ROM, legacy mode disabled",
  vdev->vbasedev.name);
-goto out;
+return;
 }
 
 /*
@@ -437,7 +439,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
 error_report("IGD device %s hotplugged, ROM disabled, "
  "legacy mode disabled", vdev->vbasedev.name);
 vdev->rom_read_failed = true;
-goto out;
+return;
 }
 
 /*
@@ -450,7 +452,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
 if (ret) {
 error_report("IGD device %s does not support OpRegion access,"
  "legacy mode disabled", vdev->vbasedev.name);
-goto out;
+return;
 }
 
 ret = vfio_get_dev_region_info(>vbasedev,
@@ -459,7 +461,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
 if (ret) {
 error_report("IGD device %s does not support host bridge access,"
  "legacy mode disabled", vdev->vbasedev.name);
-goto out;
+return;
 }
 
 ret = vfio_get_dev_region_info(>vbasedev,
@@ -468,7 +470,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
 if (ret) {
 error_report("IGD device %s does not support LPC bridge access,"
  "legacy mode disabled", vdev->vbasedev.name);
-goto out;
+return;
 }
 
 gmch = vfio_pci_read_config(>pdev, IGD_GMCH, 4);
@@ -482,7 +484,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
 error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
 error_report("IGD device %s failed to enable VGA access, "
  "legacy mode disabled", vdev->vbasedev.name);
-goto out;
+return;
 }
 
 /* Create our LPC/ISA bridge */
@@ -490,7 +492,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
 if (ret) {
 error_report("IGD device %s failed to create LPC bridge, "
  "legacy mode disabled", vdev->vbasedev.name);
-goto out;
+return;
 }
 
 /* Stuff some host values into the VM PCI host bridge */
@@ -498,14 +500,14 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int 
nr)
 if (ret) {
 error_report("IGD device %s failed to modify host bridge, "
  "legacy mode disabled", vdev->vbasedev.name);
-goto out;
+return;
 }
 
 /* Setup OpRegion access */
 if (!vfio_pci_igd_opregion_init(vdev, opregion, )) {
 error_append_hint(, "IGD legacy mode disabled\n");
 error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
-goto out;
+return;
 }
 
 /* Setup our quirk to munge GTT addresses to the VM allocated buffer */
@@ -607,9 +609,4 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
 }
 
 trace_vfio_pci_igd_bdsm_enabled(vdev->vbasedev.name, ggms_mb + gms_mb);
-
-out:
-g_free(opregion);
-g_free(host);
-g_free(lpc);
 }
-- 
2.45.1




[PULL 03/47] migration: Extend migration_file_set_error() with Error* argument

2024-05-22 Thread Cédric Le Goater
Use it to update the current error of the migration stream if
available and if not, simply print out the error. Next changes will
update with an error to report.

Reviewed-by: Avihai Horon 
Acked-by: Fabiano Rosas 
Reviewed-by: Eric Auger 
Signed-off-by: Cédric Le Goater 
---
 include/migration/misc.h | 2 +-
 hw/vfio/common.c | 4 ++--
 hw/vfio/migration.c  | 4 ++--
 migration/migration.c| 6 --
 4 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/include/migration/misc.h b/include/migration/misc.h
index 
bf7339cc1e6430226127fb6a878d06b458170858..bfadc5613bac614a316e5aed7da95d8c7845cf42
 100644
--- a/include/migration/misc.h
+++ b/include/migration/misc.h
@@ -97,7 +97,7 @@ void migration_add_notifier_mode(NotifierWithReturn *notify,
 
 void migration_remove_notifier(NotifierWithReturn *notify);
 bool migration_is_running(void);
-void migration_file_set_error(int err);
+void migration_file_set_error(int ret, Error *err);
 
 /* True if incoming migration entered POSTCOPY_INCOMING_DISCARD */
 bool migration_in_incoming_postcopy(void);
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 
b5102f54a6474a50c6366e8fbce23812d55e384e..2c97de6c730d963d961bf81c0831326c0e25afa7
 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -147,10 +147,10 @@ bool vfio_viommu_preset(VFIODevice *vbasedev)
 return vbasedev->bcontainer->space->as != _space_memory;
 }
 
-static void vfio_set_migration_error(int err)
+static void vfio_set_migration_error(int ret)
 {
 if (migration_is_setup_or_active()) {
-migration_file_set_error(err);
+migration_file_set_error(ret, NULL);
 }
 }
 
diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
index 
06ae40969b6c19037e190008e14f28be646278cd..bf2fd0759ba6e4fb103cc5c1a43edb180a3d0de4
 100644
--- a/hw/vfio/migration.c
+++ b/hw/vfio/migration.c
@@ -726,7 +726,7 @@ static void vfio_vmstate_change_prepare(void *opaque, bool 
running,
  * Migration should be aborted in this case, but vm_state_notify()
  * currently does not support reporting failures.
  */
-migration_file_set_error(ret);
+migration_file_set_error(ret, NULL);
 }
 
 trace_vfio_vmstate_change_prepare(vbasedev->name, running,
@@ -756,7 +756,7 @@ static void vfio_vmstate_change(void *opaque, bool running, 
RunState state)
  * Migration should be aborted in this case, but vm_state_notify()
  * currently does not support reporting failures.
  */
-migration_file_set_error(ret);
+migration_file_set_error(ret, NULL);
 }
 
 trace_vfio_vmstate_change(vbasedev->name, running, RunState_str(state),
diff --git a/migration/migration.c b/migration/migration.c
index 
e88b24f1e6cbe82dad3f890c00e264d2ab6ad355..70d66a441bf04761decf91dbe57ce52c57fde58f
 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -2994,13 +2994,15 @@ static MigThrError postcopy_pause(MigrationState *s)
 }
 }
 
-void migration_file_set_error(int err)
+void migration_file_set_error(int ret, Error *err)
 {
 MigrationState *s = current_migration;
 
 WITH_QEMU_LOCK_GUARD(>qemu_file_lock) {
 if (s->to_dst_file) {
-qemu_file_set_error(s->to_dst_file, err);
+qemu_file_set_error_obj(s->to_dst_file, ret, err);
+} else if (err) {
+error_report_err(err);
 }
 }
 }
-- 
2.45.1




[PULL 01/47] vfio: Add Error** argument to .set_dirty_page_tracking() handler

2024-05-22 Thread Cédric Le Goater
We will use the Error object to improve error reporting in the
.log_global*() handlers of VFIO. Add documentation while at it.

Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Avihai Horon 
Reviewed-by: Eric Auger 
Signed-off-by: Cédric Le Goater 
---
 include/hw/vfio/vfio-container-base.h | 18 --
 hw/vfio/common.c  |  4 ++--
 hw/vfio/container-base.c  |  4 ++--
 hw/vfio/container.c   |  6 +++---
 4 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/include/hw/vfio/vfio-container-base.h 
b/include/hw/vfio/vfio-container-base.h
index 
3582d5f97a37877b2adfc0d0b06996c82403f8b7..326ceea52a2030eec9dad289a9845866c4a8c090
 100644
--- a/include/hw/vfio/vfio-container-base.h
+++ b/include/hw/vfio/vfio-container-base.h
@@ -82,7 +82,7 @@ int vfio_container_add_section_window(VFIOContainerBase 
*bcontainer,
 void vfio_container_del_section_window(VFIOContainerBase *bcontainer,
MemoryRegionSection *section);
 int vfio_container_set_dirty_page_tracking(VFIOContainerBase *bcontainer,
-   bool start);
+   bool start, Error **errp);
 int vfio_container_query_dirty_bitmap(const VFIOContainerBase *bcontainer,
   VFIOBitmap *vbmap,
   hwaddr iova, hwaddr size);
@@ -121,9 +121,23 @@ struct VFIOIOMMUClass {
 int (*attach_device)(const char *name, VFIODevice *vbasedev,
  AddressSpace *as, Error **errp);
 void (*detach_device)(VFIODevice *vbasedev);
+
 /* migration feature */
+
+/**
+ * @set_dirty_page_tracking
+ *
+ * Start or stop dirty pages tracking on VFIO container
+ *
+ * @bcontainer: #VFIOContainerBase on which to de/activate dirty
+ *  page tracking
+ * @start: indicates whether to start or stop dirty pages tracking
+ * @errp: pointer to Error*, to store an error if it happens.
+ *
+ * Returns zero to indicate success and negative for error
+ */
 int (*set_dirty_page_tracking)(const VFIOContainerBase *bcontainer,
-   bool start);
+   bool start, Error **errp);
 int (*query_dirty_bitmap)(const VFIOContainerBase *bcontainer,
   VFIOBitmap *vbmap,
   hwaddr iova, hwaddr size);
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 
8f9cbdc0264044ce587877a7d19d14b28527291b..485e53916491f1164d29e739fb7106c0c77df737
 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -1076,7 +1076,7 @@ static bool vfio_listener_log_global_start(MemoryListener 
*listener,
 if (vfio_devices_all_device_dirty_tracking(bcontainer)) {
 ret = vfio_devices_dma_logging_start(bcontainer);
 } else {
-ret = vfio_container_set_dirty_page_tracking(bcontainer, true);
+ret = vfio_container_set_dirty_page_tracking(bcontainer, true, NULL);
 }
 
 if (ret) {
@@ -1096,7 +1096,7 @@ static void vfio_listener_log_global_stop(MemoryListener 
*listener)
 if (vfio_devices_all_device_dirty_tracking(bcontainer)) {
 vfio_devices_dma_logging_stop(bcontainer);
 } else {
-ret = vfio_container_set_dirty_page_tracking(bcontainer, false);
+ret = vfio_container_set_dirty_page_tracking(bcontainer, false, NULL);
 }
 
 if (ret) {
diff --git a/hw/vfio/container-base.c b/hw/vfio/container-base.c
index 
913ae49077c4f09b7b27517c1231cfbe4befb7fb..7c0764121d24b02b6c4e66e368d7dff78a6d65aa
 100644
--- a/hw/vfio/container-base.c
+++ b/hw/vfio/container-base.c
@@ -53,14 +53,14 @@ void vfio_container_del_section_window(VFIOContainerBase 
*bcontainer,
 }
 
 int vfio_container_set_dirty_page_tracking(VFIOContainerBase *bcontainer,
-   bool start)
+   bool start, Error **errp)
 {
 if (!bcontainer->dirty_pages_supported) {
 return 0;
 }
 
 g_assert(bcontainer->ops->set_dirty_page_tracking);
-return bcontainer->ops->set_dirty_page_tracking(bcontainer, start);
+return bcontainer->ops->set_dirty_page_tracking(bcontainer, start, errp);
 }
 
 int vfio_container_query_dirty_bitmap(const VFIOContainerBase *bcontainer,
diff --git a/hw/vfio/container.c b/hw/vfio/container.c
index 
77bdec276ec49cb9cd767c0de42ec801b4421572..c35221fbe7dc5453050f97cd186fc958e24f28f7
 100644
--- a/hw/vfio/container.c
+++ b/hw/vfio/container.c
@@ -209,7 +209,7 @@ static int vfio_legacy_dma_map(const VFIOContainerBase 
*bcontainer, hwaddr iova,
 
 static int
 vfio_legacy_set_dirty_page_tracking(const VFIOContainerBase *bcontainer,
-bool start)
+bool start, Error **errp)
 {
 const VFIOContainer *container = container_of(bcon

[PULL 18/47] vfio/migration: Enhance VFIO migration state tracing

2024-05-22 Thread Cédric Le Goater
From: Avihai Horon 

Move trace_vfio_migration_set_state() to the top of the function, add
recover_state to it, and add a new trace event to
vfio_migration_set_device_state().

This improves tracing of device state changes as state changes are now
also logged when vfio_migration_set_state() fails (covering recover
state and device reset transitions) and in no-op state transitions to
the same state.

Suggested-by: Cédric Le Goater 
Signed-off-by: Avihai Horon 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/migration.c  | 8 ++--
 hw/vfio/trace-events | 3 ++-
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
index 
56edffaf6251e28e39ef32991394697abb1b9e55..34d4be2ce1b13626a8690d4787366ee41a9ebe1e
 100644
--- a/hw/vfio/migration.c
+++ b/hw/vfio/migration.c
@@ -129,6 +129,9 @@ static void vfio_migration_set_device_state(VFIODevice 
*vbasedev,
 {
 VFIOMigration *migration = vbasedev->migration;
 
+trace_vfio_migration_set_device_state(vbasedev->name,
+  mig_state_to_str(state));
+
 migration->device_state = state;
 vfio_migration_send_event(vbasedev);
 }
@@ -150,6 +153,9 @@ static int vfio_migration_set_state(VFIODevice *vbasedev,
 g_strdup_printf("%s: Failed setting device state to %s.",
 vbasedev->name, mig_state_to_str(new_state));
 
+trace_vfio_migration_set_state(vbasedev->name, mig_state_to_str(new_state),
+   mig_state_to_str(recover_state));
+
 if (new_state == migration->device_state) {
 return 0;
 }
@@ -209,8 +215,6 @@ static int vfio_migration_set_state(VFIODevice *vbasedev,
 migration->data_fd = mig_state->data_fd;
 }
 
-trace_vfio_migration_set_state(vbasedev->name, 
mig_state_to_str(new_state));
-
 return 0;
 
 reset_device:
diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events
index 
f0474b244bf04d044e8327c88bf49aef349afcca..64161bf6f44cffd73851a90b70694120a5fb2a82
 100644
--- a/hw/vfio/trace-events
+++ b/hw/vfio/trace-events
@@ -152,7 +152,8 @@ vfio_load_device_config_state(const char *name) " (%s)"
 vfio_load_state(const char *name, uint64_t data) " (%s) data 0x%"PRIx64
 vfio_load_state_device_data(const char *name, uint64_t data_size, int ret) " 
(%s) size 0x%"PRIx64" ret %d"
 vfio_migration_realize(const char *name) " (%s)"
-vfio_migration_set_state(const char *name, const char *state) " (%s) state %s"
+vfio_migration_set_device_state(const char *name, const char *state) " (%s) 
state %s"
+vfio_migration_set_state(const char *name, const char *new_state, const char 
*recover_state) " (%s) new state %s, recover state %s"
 vfio_migration_state_notifier(const char *name, int state) " (%s) state %d"
 vfio_save_block(const char *name, int data_size) " (%s) data_size %d"
 vfio_save_cleanup(const char *name) " (%s)"
-- 
2.45.1




[PULL 05/47] vfio/migration: Add Error** argument to .vfio_save_config() handler

2024-05-22 Thread Cédric Le Goater
Use vmstate_save_state_with_err() to improve error reporting in the
callers and store a reported error under the migration stream. Add
documentation while at it.

Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Eric Auger 
Reviewed-by: Avihai Horon 
Signed-off-by: Cédric Le Goater 
---
 include/hw/vfio/vfio-common.h | 25 -
 hw/vfio/migration.c   | 25 ++---
 hw/vfio/pci.c |  5 +++--
 3 files changed, 45 insertions(+), 10 deletions(-)

diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index 
d66e27db02a4db8329204f88d02a204eedf1caa1..3ff633ad3b395e953a55683f5f0308bca50af3dd
 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -133,7 +133,30 @@ struct VFIODeviceOps {
 int (*vfio_hot_reset_multi)(VFIODevice *vdev);
 void (*vfio_eoi)(VFIODevice *vdev);
 Object *(*vfio_get_object)(VFIODevice *vdev);
-void (*vfio_save_config)(VFIODevice *vdev, QEMUFile *f);
+
+/**
+ * @vfio_save_config
+ *
+ * Save device config state
+ *
+ * @vdev: #VFIODevice for which to save the config
+ * @f: #QEMUFile where to send the data
+ * @errp: pointer to Error*, to store an error if it happens.
+ *
+ * Returns zero to indicate success and negative for error
+ */
+int (*vfio_save_config)(VFIODevice *vdev, QEMUFile *f, Error **errp);
+
+/**
+ * @vfio_load_config
+ *
+ * Load device config state
+ *
+ * @vdev: #VFIODevice for which to load the config
+ * @f: #QEMUFile where to get the data
+ *
+ * Returns zero to indicate success and negative for error
+ */
 int (*vfio_load_config)(VFIODevice *vdev, QEMUFile *f);
 };
 
diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
index 
43fed0dbdbe3415ae2dd68fbe45b302b85a80fa4..5d91364f3bbc34060d84b4b4b1823eadbc7b12bf
 100644
--- a/hw/vfio/migration.c
+++ b/hw/vfio/migration.c
@@ -193,21 +193,30 @@ static int vfio_load_buffer(QEMUFile *f, VFIODevice 
*vbasedev,
 return ret;
 }
 
-static int vfio_save_device_config_state(QEMUFile *f, void *opaque)
+static int vfio_save_device_config_state(QEMUFile *f, void *opaque,
+ Error **errp)
 {
 VFIODevice *vbasedev = opaque;
+int ret;
 
 qemu_put_be64(f, VFIO_MIG_FLAG_DEV_CONFIG_STATE);
 
 if (vbasedev->ops && vbasedev->ops->vfio_save_config) {
-vbasedev->ops->vfio_save_config(vbasedev, f);
+ret = vbasedev->ops->vfio_save_config(vbasedev, f, errp);
+if (ret) {
+return ret;
+}
 }
 
 qemu_put_be64(f, VFIO_MIG_FLAG_END_OF_STATE);
 
 trace_vfio_save_device_config_state(vbasedev->name);
 
-return qemu_file_get_error(f);
+ret = qemu_file_get_error(f);
+if (ret < 0) {
+error_setg_errno(errp, -ret, "Failed to save state");
+}
+return ret;
 }
 
 static int vfio_load_device_config_state(QEMUFile *f, void *opaque)
@@ -592,13 +601,15 @@ static int vfio_save_complete_precopy(QEMUFile *f, void 
*opaque)
 static void vfio_save_state(QEMUFile *f, void *opaque)
 {
 VFIODevice *vbasedev = opaque;
+Error *local_err = NULL;
 int ret;
 
-ret = vfio_save_device_config_state(f, opaque);
+ret = vfio_save_device_config_state(f, opaque, _err);
 if (ret) {
-error_report("%s: Failed to save device config space",
- vbasedev->name);
-qemu_file_set_error(f, ret);
+error_prepend(_err,
+  "vfio: Failed to save device config space of %s - ",
+  vbasedev->name);
+qemu_file_set_error_obj(f, ret, local_err);
 }
 }
 
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 
64780d1b793345c8e8996fe6b7987059ce831c11..fc6e54e871508bb0e2a3ac9079a195c086531f21
 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -2586,11 +2586,12 @@ static const VMStateDescription vmstate_vfio_pci_config 
= {
 }
 };
 
-static void vfio_pci_save_config(VFIODevice *vbasedev, QEMUFile *f)
+static int vfio_pci_save_config(VFIODevice *vbasedev, QEMUFile *f, Error 
**errp)
 {
 VFIOPCIDevice *vdev = container_of(vbasedev, VFIOPCIDevice, vbasedev);
 
-vmstate_save_state(f, _vfio_pci_config, vdev, NULL);
+return vmstate_save_state_with_err(f, _vfio_pci_config, vdev, NULL,
+   errp);
 }
 
 static int vfio_pci_load_config(VFIODevice *vbasedev, QEMUFile *f)
-- 
2.45.1




[PULL 33/47] vfio/helpers: Make vfio_set_irq_signaling() return bool

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

This is to follow the coding standand in qapi/error.h to return bool
for bool-valued functions.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 include/hw/vfio/vfio-common.h |  4 ++--
 hw/vfio/ap.c  |  8 +++
 hw/vfio/ccw.c |  8 +++
 hw/vfio/helpers.c | 18 ++--
 hw/vfio/pci.c | 40 ++-
 hw/vfio/platform.c| 18 +++-
 6 files changed, 46 insertions(+), 50 deletions(-)

diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index 
b7bb4f5304addcdb03c971f27f99e5350ad0940a..b712799caffdc950b593a87d569d7f5281976e2f
 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -207,8 +207,8 @@ void vfio_spapr_container_deinit(VFIOContainer *container);
 void vfio_disable_irqindex(VFIODevice *vbasedev, int index);
 void vfio_unmask_single_irqindex(VFIODevice *vbasedev, int index);
 void vfio_mask_single_irqindex(VFIODevice *vbasedev, int index);
-int vfio_set_irq_signaling(VFIODevice *vbasedev, int index, int subindex,
-   int action, int fd, Error **errp);
+bool vfio_set_irq_signaling(VFIODevice *vbasedev, int index, int subindex,
+int action, int fd, Error **errp);
 void vfio_region_write(void *opaque, hwaddr addr,
uint64_t data, unsigned size);
 uint64_t vfio_region_read(void *opaque,
diff --git a/hw/vfio/ap.c b/hw/vfio/ap.c
index 
ba653ef70f08ebdf482009baafc62eb33ebda9a8..d8a9615feec065e98f53831912087d9878fdff9c
 100644
--- a/hw/vfio/ap.c
+++ b/hw/vfio/ap.c
@@ -117,8 +117,8 @@ static bool vfio_ap_register_irq_notifier(VFIOAPDevice 
*vapdev,
 fd = event_notifier_get_fd(notifier);
 qemu_set_fd_handler(fd, fd_read, NULL, vapdev);
 
-if (vfio_set_irq_signaling(vdev, irq, 0, VFIO_IRQ_SET_ACTION_TRIGGER, fd,
-   errp)) {
+if (!vfio_set_irq_signaling(vdev, irq, 0, VFIO_IRQ_SET_ACTION_TRIGGER, fd,
+errp)) {
 qemu_set_fd_handler(fd, NULL, NULL, vapdev);
 event_notifier_cleanup(notifier);
 }
@@ -141,8 +141,8 @@ static void vfio_ap_unregister_irq_notifier(VFIOAPDevice 
*vapdev,
 return;
 }
 
-if (vfio_set_irq_signaling(>vdev, irq, 0,
-   VFIO_IRQ_SET_ACTION_TRIGGER, -1, )) {
+if (!vfio_set_irq_signaling(>vdev, irq, 0,
+VFIO_IRQ_SET_ACTION_TRIGGER, -1, )) {
 warn_reportf_err(err, VFIO_MSG_PREFIX, vapdev->vdev.name);
 }
 
diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 
89bb98016764e65cf826183d7a38c59d429f6eeb..1f578a3c75d975e12bbac52b3683e6fd193801cb
 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -434,8 +434,8 @@ static bool vfio_ccw_register_irq_notifier(VFIOCCWDevice 
*vcdev,
 fd = event_notifier_get_fd(notifier);
 qemu_set_fd_handler(fd, fd_read, NULL, vcdev);
 
-if (vfio_set_irq_signaling(vdev, irq, 0,
-   VFIO_IRQ_SET_ACTION_TRIGGER, fd, errp)) {
+if (!vfio_set_irq_signaling(vdev, irq, 0,
+VFIO_IRQ_SET_ACTION_TRIGGER, fd, errp)) {
 qemu_set_fd_handler(fd, NULL, NULL, vcdev);
 event_notifier_cleanup(notifier);
 }
@@ -464,8 +464,8 @@ static void vfio_ccw_unregister_irq_notifier(VFIOCCWDevice 
*vcdev,
 return;
 }
 
-if (vfio_set_irq_signaling(>vdev, irq, 0,
-   VFIO_IRQ_SET_ACTION_TRIGGER, -1, )) {
+if (!vfio_set_irq_signaling(>vdev, irq, 0,
+VFIO_IRQ_SET_ACTION_TRIGGER, -1, )) {
 warn_reportf_err(err, VFIO_MSG_PREFIX, vcdev->vdev.name);
 }
 
diff --git a/hw/vfio/helpers.c b/hw/vfio/helpers.c
index 
1f3bdd9bf059beec186d87ba4772f2f6e34bc7d4..9edbc966884de12e7248af8d50d87f26c8cd2764
 100644
--- a/hw/vfio/helpers.c
+++ b/hw/vfio/helpers.c
@@ -107,12 +107,12 @@ static const char *index_to_str(VFIODevice *vbasedev, int 
index)
 }
 }
 
-int vfio_set_irq_signaling(VFIODevice *vbasedev, int index, int subindex,
-   int action, int fd, Error **errp)
+bool vfio_set_irq_signaling(VFIODevice *vbasedev, int index, int subindex,
+int action, int fd, Error **errp)
 {
 ERRP_GUARD();
 g_autofree struct vfio_irq_set *irq_set = NULL;
-int argsz, ret = 0;
+int argsz;
 const char *name;
 int32_t *pfd;
 
@@ -127,15 +127,11 @@ int vfio_set_irq_signaling(VFIODevice *vbasedev, int 
index, int subindex,
 pfd = (int32_t *)_set->data;
 *pfd = fd;
 
-if (ioctl(vbasedev->fd, VFIO_DEVICE_SET_IRQS, irq_set)) {
-ret = -errno;
+if (!ioctl(vbasedev->fd, VFIO_DEVICE_SET_IRQS, irq_set)) {
+return true;
 }
 
-if (!ret) {
-return 0;
-}
-
-error_setg_errno(errp, 

[PULL 26/47] vfio/container: Make vfio_get_device() return bool

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

This is to follow the coding standand to return bool if 'Error **'
is used to pass error.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/container.c | 16 +++-
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/hw/vfio/container.c b/hw/vfio/container.c
index 
e330b2897423b97fee467884f4237669ceff4756..53649e397cab94f8a2b61e6d66f21d635556e04e
 100644
--- a/hw/vfio/container.c
+++ b/hw/vfio/container.c
@@ -802,8 +802,8 @@ static void vfio_put_group(VFIOGroup *group)
 g_free(group);
 }
 
-static int vfio_get_device(VFIOGroup *group, const char *name,
-   VFIODevice *vbasedev, Error **errp)
+static bool vfio_get_device(VFIOGroup *group, const char *name,
+VFIODevice *vbasedev, Error **errp)
 {
 g_autofree struct vfio_device_info *info = NULL;
 int fd;
@@ -815,14 +815,14 @@ static int vfio_get_device(VFIOGroup *group, const char 
*name,
 error_append_hint(errp,
   "Verify all devices in group %d are bound to vfio- "
   "or pci-stub and not already in use\n", group->groupid);
-return fd;
+return false;
 }
 
 info = vfio_get_device_info(fd);
 if (!info) {
 error_setg_errno(errp, errno, "error getting device info");
 close(fd);
-return -1;
+return false;
 }
 
 /*
@@ -837,7 +837,7 @@ static int vfio_get_device(VFIOGroup *group, const char 
*name,
 error_setg(errp, "Inconsistent setting of support for discarding "
"RAM (e.g., balloon) within group");
 close(fd);
-return -1;
+return false;
 }
 
 if (!group->ram_block_discard_allowed) {
@@ -858,7 +858,7 @@ static int vfio_get_device(VFIOGroup *group, const char 
*name,
 
 vbasedev->reset_works = !!(info->flags & VFIO_DEVICE_FLAGS_RESET);
 
-return 0;
+return true;
 }
 
 static void vfio_put_base_device(VFIODevice *vbasedev)
@@ -911,7 +911,6 @@ static bool vfio_legacy_attach_device(const char *name, 
VFIODevice *vbasedev,
 VFIODevice *vbasedev_iter;
 VFIOGroup *group;
 VFIOContainerBase *bcontainer;
-int ret;
 
 if (groupid < 0) {
 return false;
@@ -931,8 +930,7 @@ static bool vfio_legacy_attach_device(const char *name, 
VFIODevice *vbasedev,
 return false;
 }
 }
-ret = vfio_get_device(group, name, vbasedev, errp);
-if (ret) {
+if (!vfio_get_device(group, name, vbasedev, errp)) {
 vfio_put_group(group);
 return false;
 }
-- 
2.45.1




[PULL 40/47] vfio/pci: Make vfio_intx_enable() return bool

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

This is to follow the coding standand in qapi/error.h to return bool
for bool-valued functions.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/pci.c | 19 ---
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 
46d3c618596d95266543e9a0ebc65c04d9a7cc5d..7f35cb8a29176840412652afe5ab31cd52a1bf06
 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -261,7 +261,7 @@ static void vfio_irqchip_change(Notifier *notify, void 
*data)
 vfio_intx_update(vdev, >intx.route);
 }
 
-static int vfio_intx_enable(VFIOPCIDevice *vdev, Error **errp)
+static bool vfio_intx_enable(VFIOPCIDevice *vdev, Error **errp)
 {
 uint8_t pin = vfio_pci_read_config(>pdev, PCI_INTERRUPT_PIN, 1);
 Error *err = NULL;
@@ -270,7 +270,7 @@ static int vfio_intx_enable(VFIOPCIDevice *vdev, Error 
**errp)
 
 
 if (!pin) {
-return 0;
+return true;
 }
 
 vfio_disable_interrupts(vdev);
@@ -292,7 +292,7 @@ static int vfio_intx_enable(VFIOPCIDevice *vdev, Error 
**errp)
 ret = event_notifier_init(>intx.interrupt, 0);
 if (ret) {
 error_setg_errno(errp, -ret, "event_notifier_init failed");
-return ret;
+return false;
 }
 fd = event_notifier_get_fd(>intx.interrupt);
 qemu_set_fd_handler(fd, vfio_intx_interrupt, NULL, vdev);
@@ -301,7 +301,7 @@ static int vfio_intx_enable(VFIOPCIDevice *vdev, Error 
**errp)
 VFIO_IRQ_SET_ACTION_TRIGGER, fd, errp)) {
 qemu_set_fd_handler(fd, NULL, NULL, vdev);
 event_notifier_cleanup(>intx.interrupt);
-return -errno;
+return false;
 }
 
 if (!vfio_intx_enable_kvm(vdev, )) {
@@ -311,7 +311,7 @@ static int vfio_intx_enable(VFIOPCIDevice *vdev, Error 
**errp)
 vdev->interrupt = VFIO_INT_INTx;
 
 trace_vfio_intx_enable(vdev->vbasedev.name);
-return 0;
+return true;
 }
 
 static void vfio_intx_disable(VFIOPCIDevice *vdev)
@@ -836,8 +836,7 @@ static void vfio_msix_disable(VFIOPCIDevice *vdev)
 vfio_disable_irqindex(>vbasedev, VFIO_PCI_MSIX_IRQ_INDEX);
 
 vfio_msi_disable_common(vdev);
-vfio_intx_enable(vdev, );
-if (err) {
+if (!vfio_intx_enable(vdev, )) {
 error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
 }
 
@@ -2450,8 +2449,7 @@ void vfio_pci_post_reset(VFIOPCIDevice *vdev)
 Error *err = NULL;
 int nr;
 
-vfio_intx_enable(vdev, );
-if (err) {
+if (!vfio_intx_enable(vdev, )) {
 error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
 }
 
@@ -3194,8 +3192,7 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
  vfio_intx_routing_notifier);
 vdev->irqchip_change_notifier.notify = vfio_irqchip_change;
 kvm_irqchip_add_change_notifier(>irqchip_change_notifier);
-ret = vfio_intx_enable(vdev, errp);
-if (ret) {
+if (!vfio_intx_enable(vdev, errp)) {
 goto out_deregister;
 }
 }
-- 
2.45.1




[PULL 20/47] vfio/pci: Use g_autofree in iommufd_cdev_get_info_iova_range()

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

Local pointer info is freed before return from
iommufd_cdev_get_info_iova_range().

Use 'g_autofree' to avoid the g_free() calls.

Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/iommufd.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
index 
8827ffe636e2aba1551ba794bf666a7a214590b7..c6441279728fcede1dde2a099c076ad04c464a1f
 100644
--- a/hw/vfio/iommufd.c
+++ b/hw/vfio/iommufd.c
@@ -258,7 +258,7 @@ static int 
iommufd_cdev_get_info_iova_range(VFIOIOMMUFDContainer *container,
 uint32_t ioas_id, Error **errp)
 {
 VFIOContainerBase *bcontainer = >bcontainer;
-struct iommu_ioas_iova_ranges *info;
+g_autofree struct iommu_ioas_iova_ranges *info = NULL;
 struct iommu_iova_range *iova_ranges;
 int ret, sz, fd = container->be->fd;
 
@@ -291,12 +291,10 @@ static int 
iommufd_cdev_get_info_iova_range(VFIOIOMMUFDContainer *container,
 }
 bcontainer->pgsizes = info->out_iova_alignment;
 
-g_free(info);
 return 0;
 
 error:
 ret = -errno;
-g_free(info);
 error_setg_errno(errp, errno, "Cannot get IOVA ranges");
 return ret;
 }
-- 
2.45.1




[PULL 19/47] vfio/pci: Use g_autofree in vfio_realize

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

Local pointer name is allocated before vfio_attach_device() call
and freed after the call.

Same for tmp when calling realpath().

Use 'g_autofree' to avoid the g_free() calls.

Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/pci.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 
b5d1d398b120076c85cdd92d61793393f65e8554..84f7bff664fd7595b75cce1f6974068144f0d42d
 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -2972,12 +2972,13 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
 ERRP_GUARD();
 VFIOPCIDevice *vdev = VFIO_PCI(pdev);
 VFIODevice *vbasedev = >vbasedev;
-char *tmp, *subsys;
+char *subsys;
 Error *err = NULL;
 int i, ret;
 bool is_mdev;
 char uuid[UUID_STR_LEN];
-char *name;
+g_autofree char *name = NULL;
+g_autofree char *tmp = NULL;
 
 if (vbasedev->fd < 0 && !vbasedev->sysfsdev) {
 if (!(~vdev->host.domain || ~vdev->host.bus ||
@@ -3008,7 +3009,6 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
  */
 tmp = g_strdup_printf("%s/subsystem", vbasedev->sysfsdev);
 subsys = realpath(tmp, NULL);
-g_free(tmp);
 is_mdev = subsys && (strcmp(subsys, "/sys/bus/mdev") == 0);
 free(subsys);
 
@@ -3029,7 +3029,6 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
 
 ret = vfio_attach_device(name, vbasedev,
  pci_device_iommu_address_space(pdev), errp);
-g_free(name);
 if (ret) {
 goto error;
 }
-- 
2.45.1




[PULL 34/47] vfio/helpers: Make vfio_device_get_name() return bool

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

This is to follow the coding standand in qapi/error.h to return bool
for bool-valued functions.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 include/hw/vfio/vfio-common.h | 2 +-
 hw/vfio/ap.c  | 2 +-
 hw/vfio/ccw.c | 2 +-
 hw/vfio/helpers.c | 8 
 hw/vfio/pci.c | 2 +-
 hw/vfio/platform.c| 5 ++---
 6 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index 
b712799caffdc950b593a87d569d7f5281976e2f..4cb1ab8645dcdf604f3c2bb29328668fd5eb7284
 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -279,7 +279,7 @@ int vfio_get_dirty_bitmap(const VFIOContainerBase 
*bcontainer, uint64_t iova,
   uint64_t size, ram_addr_t ram_addr, Error **errp);
 
 /* Returns 0 on success, or a negative errno. */
-int vfio_device_get_name(VFIODevice *vbasedev, Error **errp);
+bool vfio_device_get_name(VFIODevice *vbasedev, Error **errp);
 void vfio_device_set_fd(VFIODevice *vbasedev, const char *str, Error **errp);
 void vfio_device_init(VFIODevice *vbasedev, int type, VFIODeviceOps *ops,
   DeviceState *dev, bool ram_discard);
diff --git a/hw/vfio/ap.c b/hw/vfio/ap.c
index 
d8a9615feec065e98f53831912087d9878fdff9c..c12531a7886a2fe87598be0861fba5923bd2c206
 100644
--- a/hw/vfio/ap.c
+++ b/hw/vfio/ap.c
@@ -158,7 +158,7 @@ static void vfio_ap_realize(DeviceState *dev, Error **errp)
 VFIOAPDevice *vapdev = VFIO_AP_DEVICE(dev);
 VFIODevice *vbasedev = >vdev;
 
-if (vfio_device_get_name(vbasedev, errp) < 0) {
+if (!vfio_device_get_name(vbasedev, errp)) {
 return;
 }
 
diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 
1f578a3c75d975e12bbac52b3683e6fd193801cb..8850ca17c84632d278e27819cd52e104ed436d6c
 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -588,7 +588,7 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)
 }
 }
 
-if (vfio_device_get_name(vbasedev, errp) < 0) {
+if (!vfio_device_get_name(vbasedev, errp)) {
 return;
 }
 
diff --git a/hw/vfio/helpers.c b/hw/vfio/helpers.c
index 
9edbc966884de12e7248af8d50d87f26c8cd2764..4b079dc383683a71d1d96507a0fb66a4bc3ba923
 100644
--- a/hw/vfio/helpers.c
+++ b/hw/vfio/helpers.c
@@ -607,7 +607,7 @@ bool vfio_has_region_cap(VFIODevice *vbasedev, int region, 
uint16_t cap_type)
 return ret;
 }
 
-int vfio_device_get_name(VFIODevice *vbasedev, Error **errp)
+bool vfio_device_get_name(VFIODevice *vbasedev, Error **errp)
 {
 ERRP_GUARD();
 struct stat st;
@@ -616,7 +616,7 @@ int vfio_device_get_name(VFIODevice *vbasedev, Error **errp)
 if (stat(vbasedev->sysfsdev, ) < 0) {
 error_setg_errno(errp, errno, "no such host device");
 error_prepend(errp, VFIO_MSG_PREFIX, vbasedev->sysfsdev);
-return -errno;
+return false;
 }
 /* User may specify a name, e.g: VFIO platform device */
 if (!vbasedev->name) {
@@ -625,7 +625,7 @@ int vfio_device_get_name(VFIODevice *vbasedev, Error **errp)
 } else {
 if (!vbasedev->iommufd) {
 error_setg(errp, "Use FD passing only with iommufd backend");
-return -EINVAL;
+return false;
 }
 /*
  * Give a name with fd so any function printing out vbasedev->name
@@ -636,7 +636,7 @@ int vfio_device_get_name(VFIODevice *vbasedev, Error **errp)
 }
 }
 
-return 0;
+return true;
 }
 
 void vfio_device_set_fd(VFIODevice *vbasedev, const char *str, Error **errp)
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 
358da4497b8ab9b58b4f36252d1857279efbe521..aad012c34885ff2a5a39039777962236b41b
 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -2999,7 +2999,7 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
 vdev->host.slot, vdev->host.function);
 }
 
-if (vfio_device_get_name(vbasedev, errp) < 0) {
+if (!vfio_device_get_name(vbasedev, errp)) {
 return;
 }
 
diff --git a/hw/vfio/platform.c b/hw/vfio/platform.c
index 
3233ca86918a22b69265b83a1a9dec8b6b59380f..e1a32863d919fe09a743f5fb108f9787984d4378
 100644
--- a/hw/vfio/platform.c
+++ b/hw/vfio/platform.c
@@ -545,9 +545,8 @@ static int vfio_base_device_init(VFIODevice *vbasedev, 
Error **errp)
  vbasedev->name);
 }
 
-ret = vfio_device_get_name(vbasedev, errp);
-if (ret) {
-return ret;
+if (!vfio_device_get_name(vbasedev, errp)) {
+return -EINVAL;
 }
 
 if (!vfio_attach_device(vbasedev->name, vbasedev,
-- 
2.45.1




[PULL 32/47] vfio/helpers: Use g_autofree in vfio_set_irq_signaling()

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

Local pointer irq_set is freed before return from
vfio_set_irq_signaling().

Use 'g_autofree' to avoid the g_free() calls.

Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/helpers.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/hw/vfio/helpers.c b/hw/vfio/helpers.c
index 
47b4096c05ee8915c42b763fa18754c425aa00f6..1f3bdd9bf059beec186d87ba4772f2f6e34bc7d4
 100644
--- a/hw/vfio/helpers.c
+++ b/hw/vfio/helpers.c
@@ -111,7 +111,7 @@ int vfio_set_irq_signaling(VFIODevice *vbasedev, int index, 
int subindex,
int action, int fd, Error **errp)
 {
 ERRP_GUARD();
-struct vfio_irq_set *irq_set;
+g_autofree struct vfio_irq_set *irq_set = NULL;
 int argsz, ret = 0;
 const char *name;
 int32_t *pfd;
@@ -130,7 +130,6 @@ int vfio_set_irq_signaling(VFIODevice *vbasedev, int index, 
int subindex,
 if (ioctl(vbasedev->fd, VFIO_DEVICE_SET_IRQS, irq_set)) {
 ret = -errno;
 }
-g_free(irq_set);
 
 if (!ret) {
 return 0;
-- 
2.45.1




[PULL 43/47] vfio/pci: Use g_autofree for vfio_region_info pointer

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

Pointer opregion is freed after vfio_pci_igd_opregion_init().
Use 'g_autofree' to avoid the g_free() calls.

Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/pci.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 
c3323912dd773e80ad2dbbefc5d833e8a33cd147..8379d2284a20bed0c0bd24e46bbb39e321dc9767
 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -3143,7 +3143,7 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
 
 if (!vdev->igd_opregion &&
 vdev->features & VFIO_FEATURE_ENABLE_IGD_OPREGION) {
-struct vfio_region_info *opregion;
+g_autofree struct vfio_region_info *opregion = NULL;
 
 if (vdev->pdev.qdev.hotplugged) {
 error_setg(errp,
@@ -3162,7 +3162,6 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
 }
 
 ret = vfio_pci_igd_opregion_init(vdev, opregion, errp);
-g_free(opregion);
 if (ret) {
 goto out_teardown;
 }
-- 
2.45.1




[PULL 23/47] vfio: Make VFIOIOMMUClass::add_window() and its wrapper return bool

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

Make VFIOIOMMUClass::add_window() and its wrapper function
vfio_container_add_section_window() return bool.

This is to follow the coding standand to return bool if 'Error **'
is used to pass error.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 include/hw/vfio/vfio-container-base.h | 12 ++--
 hw/vfio/common.c  |  2 +-
 hw/vfio/container-base.c  |  8 
 hw/vfio/spapr.c   | 16 
 4 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/include/hw/vfio/vfio-container-base.h 
b/include/hw/vfio/vfio-container-base.h
index 
202e23cb6b800983b036bf3808c0ec38b1c363d0..2776481fc97ef5720b10a4e3b3e6deaa075ece75
 100644
--- a/include/hw/vfio/vfio-container-base.h
+++ b/include/hw/vfio/vfio-container-base.h
@@ -76,9 +76,9 @@ int vfio_container_dma_map(VFIOContainerBase *bcontainer,
 int vfio_container_dma_unmap(VFIOContainerBase *bcontainer,
  hwaddr iova, ram_addr_t size,
  IOMMUTLBEntry *iotlb);
-int vfio_container_add_section_window(VFIOContainerBase *bcontainer,
-  MemoryRegionSection *section,
-  Error **errp);
+bool vfio_container_add_section_window(VFIOContainerBase *bcontainer,
+   MemoryRegionSection *section,
+   Error **errp);
 void vfio_container_del_section_window(VFIOContainerBase *bcontainer,
MemoryRegionSection *section);
 int vfio_container_set_dirty_page_tracking(VFIOContainerBase *bcontainer,
@@ -156,9 +156,9 @@ struct VFIOIOMMUClass {
 int (*pci_hot_reset)(VFIODevice *vbasedev, bool single);
 
 /* SPAPR specific */
-int (*add_window)(VFIOContainerBase *bcontainer,
-  MemoryRegionSection *section,
-  Error **errp);
+bool (*add_window)(VFIOContainerBase *bcontainer,
+   MemoryRegionSection *section,
+   Error **errp);
 void (*del_window)(VFIOContainerBase *bcontainer,
MemoryRegionSection *section);
 void (*release)(VFIOContainerBase *bcontainer);
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 
c04a259ffd7cfcfba480335bea1ddff787f47bdc..f9619a1dfbc689b10d70a60ce21b9b018f32391f
 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -588,7 +588,7 @@ static void vfio_listener_region_add(MemoryListener 
*listener,
 return;
 }
 
-if (vfio_container_add_section_window(bcontainer, section, )) {
+if (!vfio_container_add_section_window(bcontainer, section, )) {
 goto fail;
 }
 
diff --git a/hw/vfio/container-base.c b/hw/vfio/container-base.c
index 
26f4bb464a720c9895b35c7c9e01c84d6322c3c9..760d9d0622b2e847ecb3368c88df772efb06043f
 100644
--- a/hw/vfio/container-base.c
+++ b/hw/vfio/container-base.c
@@ -31,12 +31,12 @@ int vfio_container_dma_unmap(VFIOContainerBase *bcontainer,
 return bcontainer->ops->dma_unmap(bcontainer, iova, size, iotlb);
 }
 
-int vfio_container_add_section_window(VFIOContainerBase *bcontainer,
-  MemoryRegionSection *section,
-  Error **errp)
+bool vfio_container_add_section_window(VFIOContainerBase *bcontainer,
+   MemoryRegionSection *section,
+   Error **errp)
 {
 if (!bcontainer->ops->add_window) {
-return 0;
+return true;
 }
 
 return bcontainer->ops->add_window(bcontainer, section, errp);
diff --git a/hw/vfio/spapr.c b/hw/vfio/spapr.c
index 
148b257c9ca6a0f957115f8060ddb50e377dfcb8..47b040f1bcca7dd0b5cf052d941b43541e98a3c5
 100644
--- a/hw/vfio/spapr.c
+++ b/hw/vfio/spapr.c
@@ -323,7 +323,7 @@ static int vfio_spapr_create_window(VFIOContainer 
*container,
 return 0;
 }
 
-static int
+static bool
 vfio_spapr_container_add_section_window(VFIOContainerBase *bcontainer,
 MemoryRegionSection *section,
 Error **errp)
@@ -351,13 +351,13 @@ vfio_spapr_container_add_section_window(VFIOContainerBase 
*bcontainer,
 error_setg(errp, "Container %p can't map guest IOVA region"
" 0x%"HWADDR_PRIx"..0x%"HWADDR_PRIx, container,
iova, end);
-return -EINVAL;
+return false;
 }
-return 0;
+return true;
 }
 
 if (container->iommu_type != VFIO_SPAPR_TCE_v2_IOMMU) {
-return 0;
+return true;
 }
 
 /* For now intersections are not allowed, we may relax this later */
@@ -373,14 +373,14 @@ vfio_spapr_container_add_section_window(VFIOContainerBase 
*bcontainer,
  

  1   2   3   4   5   6   7   8   9   10   >