[PULL 03/15] hw/intc: Move some files out of the target-specific source set

2023-01-17 Thread Laurent Vivier
From: Philippe Mathieu-Daudé 

The Goldfish interrupt controller is not target specific.

While the Exynos interrupt combiner is only used by the ARM
targets, we can build this device once for all.

Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20221209170042.71169-3-phi...@linaro.org>
[thuth: Change patch title, and also move 'exynos4210_gic.c']
Signed-off-by: Thomas Huth 
Reviewed-by: Richard Henderson 
Message-Id: <20230112134928.1026006-3-th...@redhat.com>
Signed-off-by: Laurent Vivier 
---
 hw/intc/meson.build | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/intc/meson.build b/hw/intc/meson.build
index cd9f1ee8880f..0988cae8ab06 100644
--- a/hw/intc/meson.build
+++ b/hw/intc/meson.build
@@ -13,6 +13,8 @@ softmmu_ss.add(when: 'CONFIG_ARM_GICV3_TCG', if_true: files(
   'arm_gicv3_redist.c',
 ))
 softmmu_ss.add(when: 'CONFIG_ETRAXFS', if_true: files('etraxfs_pic.c'))
+softmmu_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210_gic.c', 
'exynos4210_combiner.c'))
+softmmu_ss.add(when: 'CONFIG_GOLDFISH_PIC', if_true: files('goldfish_pic.c'))
 softmmu_ss.add(when: 'CONFIG_HEATHROW_PIC', if_true: files('heathrow_pic.c'))
 softmmu_ss.add(when: 'CONFIG_I8259', if_true: files('i8259_common.c', 
'i8259.c'))
 softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('imx_avic.c', 'imx_gpcv2.c'))
@@ -39,7 +41,6 @@ specific_ss.add(when: 'CONFIG_ARM_GIC_KVM', if_true: 
files('arm_gic_kvm.c'))
 specific_ss.add(when: ['CONFIG_ARM_GIC_KVM', 'TARGET_AARCH64'], if_true: 
files('arm_gicv3_kvm.c', 'arm_gicv3_its_kvm.c'))
 specific_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('armv7m_nvic.c'))
 specific_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_vic.c'))
-specific_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210_gic.c', 
'exynos4210_combiner.c'))
 specific_ss.add(when: 'CONFIG_GRLIB', if_true: files('grlib_irqmp.c'))
 specific_ss.add(when: 'CONFIG_IOAPIC', if_true: files('ioapic.c'))
 specific_ss.add(when: 'CONFIG_LOONGSON_LIOINTC', if_true: 
files('loongson_liointc.c'))
@@ -66,7 +67,6 @@ specific_ss.add(when: 'CONFIG_PSERIES', if_true: 
files('xics_spapr.c', 'spapr_xi
 specific_ss.add(when: 'CONFIG_XIVE', if_true: files('xive.c'))
 specific_ss.add(when: ['CONFIG_KVM', 'CONFIG_XIVE'],
if_true: files('spapr_xive_kvm.c'))
-specific_ss.add(when: 'CONFIG_GOLDFISH_PIC', if_true: files('goldfish_pic.c'))
 specific_ss.add(when: 'CONFIG_M68K_IRQC', if_true: files('m68k_irqc.c'))
 specific_ss.add(when: 'CONFIG_NIOS2_VIC', if_true: files('nios2_vic.c'))
 specific_ss.add(when: 'CONFIG_LOONGARCH_IPI', if_true: 
files('loongarch_ipi.c'))
-- 
2.38.1




[PULL 00/15] Trivial branch for 8.0 patches

2023-01-17 Thread Laurent Vivier
The following changes since commit a8d6abe1292e1db1ad9be5b2b124b9c01bcda094:

  Merge tag 'mips-20230113' of https://github.com/philmd/qemu into staging 
(2023-01-16 11:24:11 +)

are available in the Git repository at:

  https://gitlab.com/laurent_vivier/qemu.git 
tags/trivial-branch-for-8.0-pull-request

for you to fetch changes up to b93b3cb1bb72f313d8c33791e0a82a25da780cf0:

  hw/ssi/sifive_spi.c: spelling: reigster (2023-01-17 10:02:37 +0100)


trivial branch pull request 20230118



Guoyi Tu (1):
  Call qemu_socketpair() instead of socketpair() when possible

Hoa Nguyen (1):
  hw/cxl/cxl-host: Fix an error message typo

Marc-André Lureau (1):
  ccid-card-emulated: fix cast warning/error

Michael Tokarev (2):
  hw/cxl/cxl-cdat.c: spelling: missmatch
  hw/ssi/sifive_spi.c: spelling: reigster

Philippe Mathieu-Daudé (5):
  hw/display: Move omap_lcdc.c out of target-specific source set
  hw/intc: Move some files out of the target-specific source set
  hw/tpm: Move tpm_ppi.c out of target-specific source set
  hw/arm: Move various units to softmmu_ss[]
  hw/i386/pc: Remove unused 'owner' argument from pc_pci_as_mapping_init

Thomas Huth (4):
  hw/cpu: Mark arm11 and realview mpcore as target-independent code
  hw/intc: Mark more interrupt-controller files as target independent
  hw/usb: Mark the XLNX_VERSAL-related files as target-independent
  tests/qtest/test-hmp: Improve the check for verbose mode

Yuval Shaia (1):
  hw/pvrdma: Protect against buggy or malicious guest driver

 backends/tpm/tpm_emulator.c |  2 +-
 hw/arm/meson.build  | 11 +++
 hw/cpu/meson.build  |  4 ++--
 hw/cxl/cxl-cdat.c   |  2 +-
 hw/cxl/cxl-host.c   |  2 +-
 hw/display/meson.build  |  2 +-
 hw/i386/pc.c|  2 +-
 hw/intc/meson.build | 12 ++--
 hw/pci-host/i440fx.c|  3 +--
 hw/pci-host/q35.c   |  3 +--
 hw/rdma/vmw/pvrdma_cmd.c|  6 ++
 hw/ssi/sifive_spi.c |  2 +-
 hw/tpm/meson.build  |  4 ++--
 hw/usb/ccid-card-emulated.c |  2 +-
 hw/usb/meson.build  |  4 ++--
 include/hw/i386/pc.h|  2 +-
 tests/qtest/dbus-display-test.c |  5 +++--
 tests/qtest/migration-test.c|  2 +-
 tests/qtest/test-hmp.c  |  2 +-
 tests/unit/test-crypto-tlssession.c |  4 ++--
 tests/unit/test-io-channel-tls.c|  2 +-
 21 files changed, 43 insertions(+), 35 deletions(-)

-- 
2.38.1




[PULL 02/15] hw/display: Move omap_lcdc.c out of target-specific source set

2023-01-17 Thread Laurent Vivier
From: Philippe Mathieu-Daudé 

While only used by the ARM targets, this device can be built
once for all.

Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20221209170042.71169-2-phi...@linaro.org>
Signed-off-by: Thomas Huth 
Reviewed-by: Richard Henderson 
Message-Id: <20230112134928.1026006-2-th...@redhat.com>
Signed-off-by: Laurent Vivier 
---
 hw/display/meson.build | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/display/meson.build b/hw/display/meson.build
index f860c2c562ac..f470179122c5 100644
--- a/hw/display/meson.build
+++ b/hw/display/meson.build
@@ -115,7 +115,7 @@ if config_all_devices.has_key('CONFIG_VIRTIO_VGA')
   hw_display_modules += {'virtio-vga-gl': virtio_vga_gl_ss}
 endif
 
-specific_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_lcdc.c'))
+softmmu_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_lcdc.c'))
 
 softmmu_ss.add(when: 'CONFIG_ALL', if_true: files('acpi-vga-stub.c'))
 modules += { 'hw-display': hw_display_modules }
-- 
2.38.1




[PULL 04/15] hw/tpm: Move tpm_ppi.c out of target-specific source set

2023-01-17 Thread Laurent Vivier
From: Philippe Mathieu-Daudé 

The TPM Physical Presence Interface is not target specific.
Build this file once for all targets.

Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20221209170042.71169-4-phi...@linaro.org>
[thuth: Drop the CONFIG_SOFTMMU statements, they are not needed here]
Signed-off-by: Thomas Huth 
Reviewed-by: Richard Henderson 
Message-Id: <20230112134928.1026006-4-th...@redhat.com>
Signed-off-by: Laurent Vivier 
---
 hw/tpm/meson.build | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/tpm/meson.build b/hw/tpm/meson.build
index 1c68d81d6ab2..7abc2d794a84 100644
--- a/hw/tpm/meson.build
+++ b/hw/tpm/meson.build
@@ -2,7 +2,7 @@ softmmu_ss.add(when: 'CONFIG_TPM_TIS', if_true: 
files('tpm_tis_common.c'))
 softmmu_ss.add(when: 'CONFIG_TPM_TIS_ISA', if_true: files('tpm_tis_isa.c'))
 softmmu_ss.add(when: 'CONFIG_TPM_TIS_SYSBUS', if_true: 
files('tpm_tis_sysbus.c'))
 softmmu_ss.add(when: 'CONFIG_TPM_CRB', if_true: files('tpm_crb.c'))
+softmmu_ss.add(when: 'CONFIG_TPM_TIS', if_true: files('tpm_ppi.c'))
+softmmu_ss.add(when: 'CONFIG_TPM_CRB', if_true: files('tpm_ppi.c'))
 
-specific_ss.add(when: ['CONFIG_SOFTMMU', 'CONFIG_TPM_TIS'], if_true: 
files('tpm_ppi.c'))
-specific_ss.add(when: ['CONFIG_SOFTMMU', 'CONFIG_TPM_CRB'], if_true: 
files('tpm_ppi.c'))
 specific_ss.add(when: 'CONFIG_TPM_SPAPR', if_true: files('tpm_spapr.c'))
-- 
2.38.1




[PULL 06/15] hw/cpu: Mark arm11 and realview mpcore as target-independent code

2023-01-17 Thread Laurent Vivier
From: Thomas Huth 

Seems like there is nothing target-specific in here, so these files
can be moved to softmmu_ss to avoid that they get compiled twice
(once for qemu-system-arm and once for qemu-system-aarch64).

Signed-off-by: Thomas Huth 
Reviewed-by: Richard Henderson 
Message-Id: <20230112134928.1026006-6-th...@redhat.com>
Signed-off-by: Laurent Vivier 
---
 hw/cpu/meson.build | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/cpu/meson.build b/hw/cpu/meson.build
index 9e52fee9e778..e37490074f5e 100644
--- a/hw/cpu/meson.build
+++ b/hw/cpu/meson.build
@@ -1,6 +1,6 @@
 softmmu_ss.add(files('core.c', 'cluster.c'))
 
-specific_ss.add(when: 'CONFIG_ARM11MPCORE', if_true: files('arm11mpcore.c'))
-specific_ss.add(when: 'CONFIG_REALVIEW', if_true: files('realview_mpcore.c'))
+softmmu_ss.add(when: 'CONFIG_ARM11MPCORE', if_true: files('arm11mpcore.c'))
+softmmu_ss.add(when: 'CONFIG_REALVIEW', if_true: files('realview_mpcore.c'))
 specific_ss.add(when: 'CONFIG_A9MPCORE', if_true: files('a9mpcore.c'))
 specific_ss.add(when: 'CONFIG_A15MPCORE', if_true: files('a15mpcore.c'))
-- 
2.38.1




[PULL 10/15] hw/i386/pc: Remove unused 'owner' argument from pc_pci_as_mapping_init

2023-01-17 Thread Laurent Vivier
From: Philippe Mathieu-Daudé 

This argument was added 9 years ago in commit 83d08f2673
("pc: map PCI address space as catchall region for not mapped
addresses") and has never been used since, so remove it.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Bernhard Beschow 
Message-Id: <20230105173826.56748-1-phi...@linaro.org>
Signed-off-by: Laurent Vivier 
---
 hw/i386/pc.c | 2 +-
 hw/pci-host/i440fx.c | 3 +--
 hw/pci-host/q35.c| 3 +--
 include/hw/i386/pc.h | 2 +-
 4 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index d489ecc0d1cd..6e592bd969aa 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -782,7 +782,7 @@ void pc_guest_info_init(PCMachineState *pcms)
 }
 
 /* setup pci memory address space mapping into system address space */
-void pc_pci_as_mapping_init(Object *owner, MemoryRegion *system_memory,
+void pc_pci_as_mapping_init(MemoryRegion *system_memory,
 MemoryRegion *pci_address_space)
 {
 /* Set to lower priority than RAM */
diff --git a/hw/pci-host/i440fx.c b/hw/pci-host/i440fx.c
index d5426ef4a53c..262f82c30380 100644
--- a/hw/pci-host/i440fx.c
+++ b/hw/pci-host/i440fx.c
@@ -272,8 +272,7 @@ PCIBus *i440fx_init(const char *pci_type,
  IO_APIC_DEFAULT_ADDRESS - 1);
 
 /* setup pci memory mapping */
-pc_pci_as_mapping_init(OBJECT(f), f->system_memory,
-   f->pci_address_space);
+pc_pci_as_mapping_init(f->system_memory, f->pci_address_space);
 
 /* if *disabled* show SMRAM to all CPUs */
 memory_region_init_alias(>smram_region, OBJECT(d), "smram-region",
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index 20da1213747c..26390863d605 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -574,8 +574,7 @@ static void mch_realize(PCIDevice *d, Error **errp)
 }
 
 /* setup pci memory mapping */
-pc_pci_as_mapping_init(OBJECT(mch), mch->system_memory,
-   mch->pci_address_space);
+pc_pci_as_mapping_init(mch->system_memory, mch->pci_address_space);
 
 /* if *disabled* show SMRAM to all CPUs */
 memory_region_init_alias(>smram_region, OBJECT(mch), "smram-region",
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 991f905f5d25..88a120bc234b 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -156,7 +156,7 @@ void pc_guest_info_init(PCMachineState *pcms);
 #define PCI_HOST_ABOVE_4G_MEM_SIZE "above-4g-mem-size"
 
 
-void pc_pci_as_mapping_init(Object *owner, MemoryRegion *system_memory,
+void pc_pci_as_mapping_init(MemoryRegion *system_memory,
 MemoryRegion *pci_address_space);
 
 void xen_load_linux(PCMachineState *pcms);
-- 
2.38.1




[PULL 11/15] ccid-card-emulated: fix cast warning/error

2023-01-17 Thread Laurent Vivier
From: Marc-André Lureau 

../hw/usb/ccid-card-emulated.c: In function 'handle_apdu_thread':
../hw/usb/ccid-card-emulated.c:251:24: error: cast from pointer to integer of 
different size [-Werror=pointer-to-int-cast]
  251 | assert((unsigned long)event > 1000);

Signed-off-by: Marc-André Lureau 
Reviewed-by: Thomas Huth 
Message-Id: <20230103110814.3726795-2-marcandre.lur...@redhat.com>
Signed-off-by: Laurent Vivier 
---
 hw/usb/ccid-card-emulated.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/usb/ccid-card-emulated.c b/hw/usb/ccid-card-emulated.c
index ee41a818014b..c32866007549 100644
--- a/hw/usb/ccid-card-emulated.c
+++ b/hw/usb/ccid-card-emulated.c
@@ -248,7 +248,7 @@ static void *handle_apdu_thread(void* arg)
 WITH_QEMU_LOCK_GUARD(>vreader_mutex) {
 while (!QSIMPLEQ_EMPTY(>guest_apdu_list)) {
 event = QSIMPLEQ_FIRST(>guest_apdu_list);
-assert((unsigned long)event > 1000);
+assert(event != NULL);
 QSIMPLEQ_REMOVE_HEAD(>guest_apdu_list, entry);
 if (event->p.data.type != EMUL_GUEST_APDU) {
 DPRINTF(card, 1, "unexpected message in 
handle_apdu_thread\n");
-- 
2.38.1




[PULL 05/15] hw/arm: Move various units to softmmu_ss[]

2023-01-17 Thread Laurent Vivier
From: Philippe Mathieu-Daudé 

arm_ss[] units are built twice: once for 32-bit word size and
once for 64-bit. The following units don't require any word
size knowledge and can be moved to softmmu_ss[] (where they
are built once):

 - smmu-common.c
 - exynos4_boards.c
 - bcm2835_peripherals.c
 - tosa.c

Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20230110164406.94366-2-phi...@linaro.org>
Signed-off-by: Thomas Huth 
Reviewed-by: Richard Henderson 
Message-Id: <20230112134928.1026006-5-th...@redhat.com>
Signed-off-by: Laurent Vivier 
---
 hw/arm/meson.build | 11 +++
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/hw/arm/meson.build b/hw/arm/meson.build
index 76d4d650e42e..b03604560392 100644
--- a/hw/arm/meson.build
+++ b/hw/arm/meson.build
@@ -3,7 +3,6 @@ arm_ss.add(files('boot.c'), fdt)
 arm_ss.add(when: 'CONFIG_ARM_VIRT', if_true: files('virt.c'))
 arm_ss.add(when: 'CONFIG_ACPI', if_true: files('virt-acpi-build.c'))
 arm_ss.add(when: 'CONFIG_DIGIC', if_true: files('digic_boards.c'))
-arm_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4_boards.c'))
 arm_ss.add(when: 'CONFIG_EMCRAFT_SF2', if_true: files('msf2-som.c'))
 arm_ss.add(when: 'CONFIG_HIGHBANK', if_true: files('highbank.c'))
 arm_ss.add(when: 'CONFIG_INTEGRATOR', if_true: files('integratorcp.c'))
@@ -19,7 +18,6 @@ arm_ss.add(when: 'CONFIG_SX1', if_true: files('omap_sx1.c'))
 arm_ss.add(when: 'CONFIG_CHEETAH', if_true: files('palm.c'))
 arm_ss.add(when: 'CONFIG_GUMSTIX', if_true: files('gumstix.c'))
 arm_ss.add(when: 'CONFIG_SPITZ', if_true: files('spitz.c'))
-arm_ss.add(when: 'CONFIG_TOSA', if_true: files('tosa.c'))
 arm_ss.add(when: 'CONFIG_Z2', if_true: files('z2.c'))
 arm_ss.add(when: 'CONFIG_REALVIEW', if_true: files('realview.c'))
 arm_ss.add(when: 'CONFIG_SBSA_REF', if_true: files('sbsa-ref.c'))
@@ -39,7 +37,7 @@ arm_ss.add(when: 'CONFIG_OMAP', if_true: files('omap1.c', 
'omap2.c'))
 arm_ss.add(when: 'CONFIG_STRONGARM', if_true: files('strongarm.c'))
 arm_ss.add(when: 'CONFIG_ALLWINNER_A10', if_true: files('allwinner-a10.c', 
'cubieboard.c'))
 arm_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-h3.c', 
'orangepi.c'))
-arm_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_peripherals.c', 
'bcm2836.c', 'raspi.c'))
+arm_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2836.c', 'raspi.c'))
 arm_ss.add(when: 'CONFIG_STM32F100_SOC', if_true: files('stm32f100_soc.c'))
 arm_ss.add(when: 'CONFIG_STM32F205_SOC', if_true: files('stm32f205_soc.c'))
 arm_ss.add(when: 'CONFIG_STM32F405_SOC', if_true: files('stm32f405_soc.c'))
@@ -60,8 +58,13 @@ arm_ss.add(when: 'CONFIG_MSF2', if_true: files('msf2-soc.c'))
 arm_ss.add(when: 'CONFIG_MUSCA', if_true: files('musca.c'))
 arm_ss.add(when: 'CONFIG_ARMSSE', if_true: files('armsse.c'))
 arm_ss.add(when: 'CONFIG_FSL_IMX7', if_true: files('fsl-imx7.c', 
'mcimx7d-sabre.c'))
-arm_ss.add(when: 'CONFIG_ARM_SMMUV3', if_true: files('smmu-common.c', 
'smmuv3.c'))
+arm_ss.add(when: 'CONFIG_ARM_SMMUV3', if_true: files('smmuv3.c'))
 arm_ss.add(when: 'CONFIG_FSL_IMX6UL', if_true: files('fsl-imx6ul.c', 
'mcimx6ul-evk.c'))
 arm_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_soc.c'))
 
+softmmu_ss.add(when: 'CONFIG_ARM_SMMUV3', if_true: files('smmu-common.c'))
+softmmu_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4_boards.c'))
+softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_peripherals.c'))
+softmmu_ss.add(when: 'CONFIG_TOSA', if_true: files('tosa.c'))
+
 hw_arch += {'arm': arm_ss}
-- 
2.38.1




[PULL 12/15] hw/pvrdma: Protect against buggy or malicious guest driver

2023-01-17 Thread Laurent Vivier
From: Yuval Shaia 

Guest driver might execute HW commands when shared buffers are not yet
allocated.
This could happen on purpose (malicious guest) or because of some other
guest/host address mapping error.
We need to protect againts such case.

Fixes: CVE-2022-1050

Reported-by: Raven 
Signed-off-by: Yuval Shaia 
Message-Id: <20220403095234.2210-1-yuval.shaia...@gmail.com>
Signed-off-by: Laurent Vivier 
---
 hw/rdma/vmw/pvrdma_cmd.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/hw/rdma/vmw/pvrdma_cmd.c b/hw/rdma/vmw/pvrdma_cmd.c
index 1eca6328c924..c6ed02598211 100644
--- a/hw/rdma/vmw/pvrdma_cmd.c
+++ b/hw/rdma/vmw/pvrdma_cmd.c
@@ -776,6 +776,12 @@ int pvrdma_exec_cmd(PVRDMADev *dev)
 
 dsr_info = >dsr_info;
 
+if (!dsr_info->dsr) {
+/* Buggy or malicious guest driver */
+rdma_error_report("Exec command without dsr, req or rsp buffers");
+goto out;
+}
+
 if (dsr_info->req->hdr.cmd >= sizeof(cmd_handlers) /
   sizeof(struct cmd_handler)) {
 rdma_error_report("Unsupported command");
-- 
2.38.1




[PULL 13/15] hw/cxl/cxl-cdat.c: spelling: missmatch

2023-01-17 Thread Laurent Vivier
From: Michael Tokarev 

Introduced by: aba578bdace5303a441f8a37aad781b5cb06f38c

Signed-off-by: Michael Tokarev 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221215123749.1026775-1-...@msgid.tls.msk.ru>
Signed-off-by: Laurent Vivier 
---
 hw/cxl/cxl-cdat.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/cxl/cxl-cdat.c b/hw/cxl/cxl-cdat.c
index 3653aa56f0d4..137abd0992cb 100644
--- a/hw/cxl/cxl-cdat.c
+++ b/hw/cxl/cxl-cdat.c
@@ -146,7 +146,7 @@ static void ct3_load_cdat(CDATObject *cdat, Error **errp)
 num_ent++;
 }
 if (i != file_size) {
-error_setg(errp, "CDAT: File length missmatch");
+error_setg(errp, "CDAT: File length mismatch");
 return;
 }
 
-- 
2.38.1




[PULL 09/15] tests/qtest/test-hmp: Improve the check for verbose mode

2023-01-17 Thread Laurent Vivier
From: Thomas Huth 

Running the test-hmp with V=2 up to V=9 runs the test in verbose mode,
but running for example with V=10 falls back to non-verbose mode ...
Improve this oddity by properly treating the argument as a number.

Signed-off-by: Thomas Huth 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20230109101306.271444-1-th...@redhat.com>
Signed-off-by: Laurent Vivier 
---
 tests/qtest/test-hmp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/qtest/test-hmp.c b/tests/qtest/test-hmp.c
index f8b22abe4cac..b4a920df8983 100644
--- a/tests/qtest/test-hmp.c
+++ b/tests/qtest/test-hmp.c
@@ -151,7 +151,7 @@ int main(int argc, char **argv)
 {
 char *v_env = getenv("V");
 
-if (v_env && *v_env >= '2') {
+if (v_env && atoi(v_env) >= 2) {
 verbose = true;
 }
 
-- 
2.38.1




[PULL 01/15] Call qemu_socketpair() instead of socketpair() when possible

2023-01-17 Thread Laurent Vivier
From: Guoyi Tu 

As qemu_socketpair() was introduced in commit 3c63b4e9
("oslib-posix: Introduce qemu_socketpair()"), it's time
to replace the other existing socketpair() calls with
qemu_socketpair() if possible

Signed-off-by: Guoyi Tu 
Acked-by: Thomas Huth 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: 
Signed-off-by: Laurent Vivier 
---
 backends/tpm/tpm_emulator.c | 2 +-
 tests/qtest/dbus-display-test.c | 5 +++--
 tests/qtest/migration-test.c| 2 +-
 tests/unit/test-crypto-tlssession.c | 4 ++--
 tests/unit/test-io-channel-tls.c| 2 +-
 5 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/backends/tpm/tpm_emulator.c b/backends/tpm/tpm_emulator.c
index 49cc3d749dc4..67e7b212e3eb 100644
--- a/backends/tpm/tpm_emulator.c
+++ b/backends/tpm/tpm_emulator.c
@@ -553,7 +553,7 @@ static int tpm_emulator_prepare_data_fd(TPMEmulator 
*tpm_emu)
 Error *err = NULL;
 int fds[2] = { -1, -1 };
 
-if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
+if (qemu_socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
 error_report("tpm-emulator: Failed to create socketpair");
 return -1;
 }
diff --git a/tests/qtest/dbus-display-test.c b/tests/qtest/dbus-display-test.c
index cb1b62d1d11a..fef025ac6f83 100644
--- a/tests/qtest/dbus-display-test.c
+++ b/tests/qtest/dbus-display-test.c
@@ -1,5 +1,6 @@
 #include "qemu/osdep.h"
 #include "qemu/dbus.h"
+#include "qemu/sockets.h"
 #include 
 #include 
 #include "libqtest.h"
@@ -36,7 +37,7 @@ test_setup(QTestState **qts, GDBusConnection **conn)
 
 *qts = qtest_init("-display dbus,p2p=yes -name dbus-test");
 
-g_assert_cmpint(socketpair(AF_UNIX, SOCK_STREAM, 0, pair), ==, 0);
+g_assert_cmpint(qemu_socketpair(AF_UNIX, SOCK_STREAM, 0, pair), ==, 0);
 
 qtest_qmp_add_client(*qts, "@dbus-display", pair[1]);
 
@@ -152,7 +153,7 @@ test_dbus_display_console(void)
 
 test_setup(, );
 
-g_assert_cmpint(socketpair(AF_UNIX, SOCK_STREAM, 0, pair), ==, 0);
+g_assert_cmpint(qemu_socketpair(AF_UNIX, SOCK_STREAM, 0, pair), ==, 0);
 fd_list = g_unix_fd_list_new();
 idx = g_unix_fd_list_append(fd_list, pair[1], NULL);
 
diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c
index dbde726adf8c..1dd32c9506bf 100644
--- a/tests/qtest/migration-test.c
+++ b/tests/qtest/migration-test.c
@@ -1661,7 +1661,7 @@ static void *test_migrate_fd_start_hook(QTestState *from,
 int pair[2];
 
 /* Create two connected sockets for migration */
-ret = socketpair(PF_LOCAL, SOCK_STREAM, 0, pair);
+ret = qemu_socketpair(PF_LOCAL, SOCK_STREAM, 0, pair);
 g_assert_cmpint(ret, ==, 0);
 
 /* Send the 1st socket to the target */
diff --git a/tests/unit/test-crypto-tlssession.c 
b/tests/unit/test-crypto-tlssession.c
index 615a1344b4aa..b12e7b687927 100644
--- a/tests/unit/test-crypto-tlssession.c
+++ b/tests/unit/test-crypto-tlssession.c
@@ -82,7 +82,7 @@ static void test_crypto_tls_session_psk(void)
 int ret;
 
 /* We'll use this for our fake client-server connection */
-ret = socketpair(AF_UNIX, SOCK_STREAM, 0, channel);
+ret = qemu_socketpair(AF_UNIX, SOCK_STREAM, 0, channel);
 g_assert(ret == 0);
 
 /*
@@ -236,7 +236,7 @@ static void test_crypto_tls_session_x509(const void *opaque)
 int ret;
 
 /* We'll use this for our fake client-server connection */
-ret = socketpair(AF_UNIX, SOCK_STREAM, 0, channel);
+ret = qemu_socketpair(AF_UNIX, SOCK_STREAM, 0, channel);
 g_assert(ret == 0);
 
 /*
diff --git a/tests/unit/test-io-channel-tls.c b/tests/unit/test-io-channel-tls.c
index cc39247556f3..e036ac5df4c2 100644
--- a/tests/unit/test-io-channel-tls.c
+++ b/tests/unit/test-io-channel-tls.c
@@ -121,7 +121,7 @@ static void test_io_channel_tls(const void *opaque)
 GMainContext *mainloop;
 
 /* We'll use this for our fake client-server connection */
-g_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, channel) == 0);
+g_assert(qemu_socketpair(AF_UNIX, SOCK_STREAM, 0, channel) == 0);
 
 #define CLIENT_CERT_DIR "tests/test-io-channel-tls-client/"
 #define SERVER_CERT_DIR "tests/test-io-channel-tls-server/"
-- 
2.38.1




[PULL 08/15] hw/usb: Mark the XLNX_VERSAL-related files as target-independent

2023-01-17 Thread Laurent Vivier
From: Thomas Huth 

Seems like there is nothing target-specific in here, so these files
can be moved to softmmu_ss to avoid that they get compiled twice
(once for qemu-system-arm and once for qemu-system-aarch64).

Signed-off-by: Thomas Huth 
Reviewed-by: Richard Henderson 
Message-Id: <20230112134928.1026006-8-th...@redhat.com>
Signed-off-by: Laurent Vivier 
---
 hw/usb/meson.build | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/usb/meson.build b/hw/usb/meson.build
index 793df42e2127..bdf34cbd3e30 100644
--- a/hw/usb/meson.build
+++ b/hw/usb/meson.build
@@ -30,8 +30,8 @@ softmmu_ss.add(when: 'CONFIG_TUSB6010', if_true: 
files('tusb6010.c'))
 softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('chipidea.c'))
 softmmu_ss.add(when: 'CONFIG_IMX_USBPHY', if_true: files('imx-usb-phy.c'))
 softmmu_ss.add(when: 'CONFIG_VT82C686', if_true: files('vt82c686-uhci-pci.c'))
-specific_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: 
files('xlnx-versal-usb2-ctrl-regs.c'))
-specific_ss.add(when: 'CONFIG_XLNX_USB_SUBSYS', if_true: 
files('xlnx-usb-subsystem.c'))
+softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: 
files('xlnx-versal-usb2-ctrl-regs.c'))
+softmmu_ss.add(when: 'CONFIG_XLNX_USB_SUBSYS', if_true: 
files('xlnx-usb-subsystem.c'))
 
 # emulated usb devices
 softmmu_ss.add(when: 'CONFIG_USB', if_true: files('dev-hub.c'))
-- 
2.38.1




[PULL 07/15] hw/intc: Mark more interrupt-controller files as target independent

2023-01-17 Thread Laurent Vivier
From: Thomas Huth 

Seems like there is also nothing target-specific in here, so these
files can be moved to softmmu_ss to avoid that they get compiled
twice (once for qemu-system-arm and once for qemu-system-aarch64).

Signed-off-by: Thomas Huth 
Reviewed-by: Richard Henderson 
Message-Id: <20230112134928.1026006-7-th...@redhat.com>
Signed-off-by: Laurent Vivier 
---
 hw/intc/meson.build | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/intc/meson.build b/hw/intc/meson.build
index 0988cae8ab06..8be459b41c6e 100644
--- a/hw/intc/meson.build
+++ b/hw/intc/meson.build
@@ -12,6 +12,8 @@ softmmu_ss.add(when: 'CONFIG_ARM_GICV3_TCG', if_true: files(
   'arm_gicv3_its.c',
   'arm_gicv3_redist.c',
 ))
+softmmu_ss.add(when: 'CONFIG_ALLWINNER_A10_PIC', if_true: 
files('allwinner-a10-pic.c'))
+softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_vic.c'))
 softmmu_ss.add(when: 'CONFIG_ETRAXFS', if_true: files('etraxfs_pic.c'))
 softmmu_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210_gic.c', 
'exynos4210_combiner.c'))
 softmmu_ss.add(when: 'CONFIG_GOLDFISH_PIC', if_true: files('goldfish_pic.c'))
@@ -19,8 +21,10 @@ softmmu_ss.add(when: 'CONFIG_HEATHROW_PIC', if_true: 
files('heathrow_pic.c'))
 softmmu_ss.add(when: 'CONFIG_I8259', if_true: files('i8259_common.c', 
'i8259.c'))
 softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('imx_avic.c', 'imx_gpcv2.c'))
 softmmu_ss.add(when: 'CONFIG_IOAPIC', if_true: files('ioapic_common.c'))
+softmmu_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_intc.c'))
 softmmu_ss.add(when: 'CONFIG_OPENPIC', if_true: files('openpic.c'))
 softmmu_ss.add(when: 'CONFIG_PL190', if_true: files('pl190.c'))
+softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_ic.c', 
'bcm2836_control.c'))
 softmmu_ss.add(when: 'CONFIG_REALVIEW', if_true: files('realview_gic.c'))
 softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_intctl.c'))
 softmmu_ss.add(when: 'CONFIG_XILINX', if_true: files('xilinx_intc.c'))
@@ -33,25 +37,21 @@ if config_all_devices.has_key('CONFIG_APIC') or \
 softmmu_ss.add(files('kvm_irqcount.c'))
 endif
 
-specific_ss.add(when: 'CONFIG_ALLWINNER_A10_PIC', if_true: 
files('allwinner-a10-pic.c'))
 specific_ss.add(when: 'CONFIG_APIC', if_true: files('apic.c', 'apic_common.c'))
 specific_ss.add(when: 'CONFIG_ARM_GIC', if_true: 
files('arm_gicv3_cpuif_common.c'))
 specific_ss.add(when: 'CONFIG_ARM_GICV3_TCG', if_true: 
files('arm_gicv3_cpuif.c'))
 specific_ss.add(when: 'CONFIG_ARM_GIC_KVM', if_true: files('arm_gic_kvm.c'))
 specific_ss.add(when: ['CONFIG_ARM_GIC_KVM', 'TARGET_AARCH64'], if_true: 
files('arm_gicv3_kvm.c', 'arm_gicv3_its_kvm.c'))
 specific_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('armv7m_nvic.c'))
-specific_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_vic.c'))
 specific_ss.add(when: 'CONFIG_GRLIB', if_true: files('grlib_irqmp.c'))
 specific_ss.add(when: 'CONFIG_IOAPIC', if_true: files('ioapic.c'))
 specific_ss.add(when: 'CONFIG_LOONGSON_LIOINTC', if_true: 
files('loongson_liointc.c'))
 specific_ss.add(when: 'CONFIG_MIPS_CPS', if_true: files('mips_gic.c'))
-specific_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_intc.c'))
 specific_ss.add(when: 'CONFIG_OMPIC', if_true: files('ompic.c'))
 specific_ss.add(when: ['CONFIG_KVM', 'CONFIG_OPENPIC'],
if_true: files('openpic_kvm.c'))
 specific_ss.add(when: 'CONFIG_POWERNV', if_true: files('xics_pnv.c', 
'pnv_xive.c', 'pnv_xive2.c'))
 specific_ss.add(when: 'CONFIG_PPC_UIC', if_true: files('ppc-uic.c'))
-specific_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_ic.c', 
'bcm2836_control.c'))
 specific_ss.add(when: 'CONFIG_RX_ICU', if_true: files('rx_icu.c'))
 specific_ss.add(when: 'CONFIG_S390_FLIC', if_true: files('s390_flic.c'))
 specific_ss.add(when: 'CONFIG_S390_FLIC_KVM', if_true: 
files('s390_flic_kvm.c'))
-- 
2.38.1




[PULL 15/15] hw/ssi/sifive_spi.c: spelling: reigster

2023-01-17 Thread Laurent Vivier
From: Michael Tokarev 

Fixes: 0694dabe9763847f3010b54ab3ec7d367d2f0ff0
Signed-off-by: Michael Tokarev 
Reviewed-by: Alistair Francis 
Reviewed-by: Palmer Dabbelt 
Acked-by: Palmer Dabbelt 
Message-Id: <20221105115329.306527-1-...@msgid.tls.msk.ru>
Signed-off-by: Laurent Vivier 
---
 hw/ssi/sifive_spi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/ssi/sifive_spi.c b/hw/ssi/sifive_spi.c
index 03540cf5ca66..1b4a401ca18a 100644
--- a/hw/ssi/sifive_spi.c
+++ b/hw/ssi/sifive_spi.c
@@ -267,7 +267,7 @@ static void sifive_spi_write(void *opaque, hwaddr addr,
 case R_RXDATA:
 case R_IP:
 qemu_log_mask(LOG_GUEST_ERROR,
-  "%s: invalid write to read-only reigster 0x%"
+  "%s: invalid write to read-only register 0x%"
   HWADDR_PRIx " with 0x%x\n", __func__, addr << 2, value);
 break;
 
-- 
2.38.1




[PULL 14/15] hw/cxl/cxl-host: Fix an error message typo

2023-01-17 Thread Laurent Vivier
From: Hoa Nguyen 

Signed-off-by: Hoa Nguyen 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221127032220.2649-1-hoangu...@ucdavis.edu>
Signed-off-by: Laurent Vivier 
---
 hw/cxl/cxl-host.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/cxl/cxl-host.c b/hw/cxl/cxl-host.c
index 1adf61231ad5..3c1ec8732afd 100644
--- a/hw/cxl/cxl-host.c
+++ b/hw/cxl/cxl-host.c
@@ -47,7 +47,7 @@ static void cxl_fixed_memory_window_config(CXLState 
*cxl_state,
 
 if (object->size % (256 * MiB)) {
 error_setg(errp,
-   "Size of a CXL fixed memory window must my a multiple of 
256MiB");
+   "Size of a CXL fixed memory window must be a multiple of 
256MiB");
 return;
 }
 fw->size = object->size;
-- 
2.38.1




Re: [PATCH v2 04/11] hw/arm/aspeed: Use the IEC binary prefix definitions

2023-01-17 Thread Cédric Le Goater

On 1/18/23 07:53, Joel Stanley wrote:

On Fri, 30 Dec 2022 at 11:35, Philippe Mathieu-Daudé  wrote:


IEC binary prefixes ease code review: the unit is explicit.


I strongly prefer the existing code; it tells you the size without
having to do maths.


you mean that it matches better with the address space representation
in the code and the 'info mtree' output ? If so, I agree. We can keep
this patch out, it is not fundamental.

The hex representation of values has its advantages compared to the
macros because hex is generally what you get in debug outputs and
it is easier to compare and manipulate.  Some Linux dev feel the
same.

C.





Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Peter Delevoryas 
---
  hw/arm/aspeed_ast10x0.c | 3 ++-
  hw/arm/aspeed_ast2600.c | 3 ++-
  hw/arm/aspeed_soc.c | 4 ++--
  3 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/hw/arm/aspeed_ast10x0.c b/hw/arm/aspeed_ast10x0.c
index 122b3fd3f3..3500294df7 100644
--- a/hw/arm/aspeed_ast10x0.c
+++ b/hw/arm/aspeed_ast10x0.c
@@ -10,6 +10,7 @@
   */

  #include "qemu/osdep.h"
+#include "qemu/units.h"
  #include "qapi/error.h"
  #include "exec/address-spaces.h"
  #include "sysemu/sysemu.h"
@@ -348,7 +349,7 @@ static void aspeed_soc_ast1030_class_init(ObjectClass 
*klass, void *data)
  sc->name = "ast1030-a1";
  sc->cpu_type = ARM_CPU_TYPE_NAME("cortex-m4");
  sc->silicon_rev = AST1030_A1_SILICON_REV;
-sc->sram_size = 0xc;
+sc->sram_size = 768 * KiB;
  sc->spis_num = 2;
  sc->ehcis_num = 0;
  sc->wdts_num = 4;
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index a79e05ddbd..72df72a540 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -8,6 +8,7 @@
   */

  #include "qemu/osdep.h"
+#include "qemu/units.h"
  #include "qapi/error.h"
  #include "hw/misc/unimp.h"
  #include "hw/arm/aspeed_soc.h"
@@ -619,7 +620,7 @@ static void aspeed_soc_ast2600_class_init(ObjectClass *oc, 
void *data)
  sc->name = "ast2600-a3";
  sc->cpu_type = ARM_CPU_TYPE_NAME("cortex-a7");
  sc->silicon_rev  = AST2600_A3_SILICON_REV;
-sc->sram_size= 0x16400;
+sc->sram_size= 89 * KiB;
  sc->spis_num = 2;
  sc->ehcis_num= 2;
  sc->wdts_num = 4;
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index 2c0924d311..677342c9ed 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -517,7 +517,7 @@ static void aspeed_soc_ast2400_class_init(ObjectClass *oc, 
void *data)
  sc->name = "ast2400-a1";
  sc->cpu_type = ARM_CPU_TYPE_NAME("arm926");
  sc->silicon_rev  = AST2400_A1_SILICON_REV;
-sc->sram_size= 0x8000;
+sc->sram_size= 32 * KiB;
  sc->spis_num = 1;
  sc->ehcis_num= 1;
  sc->wdts_num = 2;
@@ -544,7 +544,7 @@ static void aspeed_soc_ast2500_class_init(ObjectClass *oc, 
void *data)
  sc->name = "ast2500-a1";
  sc->cpu_type = ARM_CPU_TYPE_NAME("arm1176");
  sc->silicon_rev  = AST2500_A1_SILICON_REV;
-sc->sram_size= 0x9000;
+sc->sram_size= 36 * KiB;
  sc->spis_num = 2;
  sc->ehcis_num= 2;
  sc->wdts_num = 3;
--
2.38.1






Re: mips, nvme/pci boot regression (commit 145e2198d749)

2023-01-17 Thread Klaus Jensen
On Jan 17 15:25, Philippe Mathieu-Daudé wrote:
> Hi Klaus,
> 
> On 17/1/23 13:30, Klaus Jensen wrote:
> > Hi Philippe,
> > 
> > Commit 145e2198d749 ("hw/mips/gt64xxx_pci: Endian-swap using
> > PCI_HOST_BRIDGE MemoryRegionOps") broke my mips64 nvme boot test
> > (little-endian host, mips64 and nvme boot device).
> > 
> > The pci device doesn't show up and the kernel panics.
> > 
> >qemu-system-mips64 \
> >  -nodefaults -nographic -snapshot -no-reboot \
> >  -M "malta" -cpu "I6400" -m 512M \
> >  -nic user,model=pcnet \
> >  -drive file=images/rootfs.ext2,format=raw,if=none,id=d0 \
> >  -device nvme,serial=default,drive=d0 \
> >  -kernel images/vmlinux \
> >  -append "root=/dev/nvme0n1 console=ttyS0,115200" \
> >  -serial stdio
> 
> How do I get this images/ folder, or how do you generate
> the kernel / rootfs images?

It's a buildroot with the qemu_mips64r6_malta_defconfig. However, the
kernel must be at least v6.2-rc3 and a potential fix for pin-based
interrupts[1] (other fixes are being discussed) must be applied. On
older kernels the device should show up, but it will be broken (issue on
big-endian with shadow doorbells and occasional timeouts due to the
kernel missing interrupts).

If you don't want to mess with that, I put the images on github[2] (the
kernel is v6.2-rc4 + my potential nvme driver fix). Just gunzip
rootfs.ext2.gz.

  [1]: https://lore.kernel.org/linux-nvme/Y8W+H6T9DOZ08SoF@cormorant.local/
  [2]: https://github.com/birkelund/qemu-nvme-boot


signature.asc
Description: PGP signature


Re: [PATCH] linux-user: fix strace build w/out munlockall

2023-01-17 Thread Philippe Mathieu-Daudé

On 18/1/23 00:30, Mike Frysinger wrote:

Signed-off-by: Mike Frysinger 
---
  linux-user/strace.c | 2 ++
  1 file changed, 2 insertions(+)

diff --git a/linux-user/strace.c b/linux-user/strace.c
index 9ae5a812cd71..f7912ad67f2b 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -1380,6 +1380,7 @@ UNUSED static struct flags termios_lflags[] = {
  FLAG_END,
  };
  
+#ifdef TARGET_NR_mlockall

  UNUSED static struct flags mlockall_flags[] = {


Removing the 'UNUSED' qualifier:

Reviewed-by: Philippe Mathieu-Daudé 


  FLAG_TARGET(MCL_CURRENT),
  FLAG_TARGET(MCL_FUTURE),
@@ -1388,6 +1389,7 @@ UNUSED static struct flags mlockall_flags[] = {
  #endif
  FLAG_END,
  };
+#endif
  
  /* IDs of the various system clocks */

  #define TARGET_CLOCK_REALTIME  0





Re: [PATCH 4/4] hw/misc/macio: Return bool from functions taking errp

2023-01-17 Thread Philippe Mathieu-Daudé

On 18/1/23 01:32, BALATON Zoltan wrote:

Use the convention to return bool from functions which take an error
pointer which allows for callers to pass through their error pointer
without needing a local.

Signed-off-by: BALATON Zoltan 
---
  hw/misc/macio/macio.c | 62 +--
  1 file changed, 25 insertions(+), 37 deletions(-)


Reviewed-by: Philippe Mathieu-Daudé 




Re: [PATCH 3/4] hw/misc/macio: Remove some single use local variables

2023-01-17 Thread Philippe Mathieu-Daudé

On 18/1/23 01:32, BALATON Zoltan wrote:

Drop some local variables that could just be substituted at the single
place they were used. This makes the code shorter and simpler.

Signed-off-by: BALATON Zoltan 
---
  hw/misc/macio/macio.c | 13 +
  1 file changed, 5 insertions(+), 8 deletions(-)


Reviewed-by: Philippe Mathieu-Daudé 




Re: [PATCH 2/4] hw/misc/macio: Rename sysbus_dev to sbd for consistency and brevity

2023-01-17 Thread Philippe Mathieu-Daudé

On 18/1/23 01:32, BALATON Zoltan wrote:

Some functions use sysbus_dev while others sbd name for local variable
storing a sysbus device pointer. Standardise on the shorter name to be
consistent and make the code easier to read as short name is less
distracting and needs less line breaks.

Signed-off-by: BALATON Zoltan 
---
  hw/misc/macio/macio.c | 78 +++
  1 file changed, 35 insertions(+), 43 deletions(-)


Reviewed-by: Philippe Mathieu-Daudé 




Re: [PATCH 1/4] hw/misc/macio: Avoid some QOM casts

2023-01-17 Thread Philippe Mathieu-Daudé

On 18/1/23 01:32, BALATON Zoltan wrote:

At several places we already have the object pointer with the right
type so we don't need to cast it back and forth. Avoiding these casts
improves readability.

Signed-off-by: BALATON Zoltan 
---
  hw/misc/macio/macio.c | 14 +++---
  1 file changed, 7 insertions(+), 7 deletions(-)


Reviewed-by: Philippe Mathieu-Daudé 




Re: reverse-{debugging,continue} not working on v7.2.0, i386 guest

2023-01-17 Thread Pavel Dovgalyuk

As replay works well, the reverse debugging should be ok too.
But for "going back" it needs a VM snapshot that can be used for reload.

Snapshots are saved on qcow2 images connected to QEMU.
Therefore you need to add an empty qcow2 to your command line with the 
following option: -drive file=empty.qcow2,if=none,id=rr


And you also need to add rrsnapshot to icount for creating the snapshot 
at the start of VM execution:

-icount shift=auto,rr=record,rrfile=$REPLAY_FILE,rrsnapshot=start


On 18.01.2023 09:14, Hyeonggon Yoo wrote:

Hello QEMU folks.
I was struggling to fix a recent heisenbug in the Linux kernel,
and fortunately the bug was reproducible with TCG and -smp 1.

I'm using qemu version 7.2.0, and guest architecture is i386.
I tried to inspect the bug using record/replay and reverse-debugging
feature in the QEMU.


recorded with:

qemu-system-i386 \
 -icount shift=auto,rr=record,rrfile=$REPLAY_FILE \
 -kernel arch/x86/boot/bzImage \
 -cpu SandyBridge \
 -initrd debian-i386.cgz \
 -smp 1 \
 -m 1024 \
 -nographic \
 -net none \
 -append "page_owner=on console=ttyS0"

and replayed with:

qemu-system-i386 \
 -icount shift=auto,rr=replay,rrfile=$REPLAY_FILE \
 -kernel arch/x86/boot/bzImage \
 -cpu SandyBridge \
 -initrd debian-i386.cgz \
 -smp 1 \
 -m 1024 \
 -nographic \
 -net none \
 -s \
 -append "page_owner=on console=ttyS0"

(I'm using a initrd image instead of a disk file.)

The record and replay works well. The bug is reliably reproduced
when relaying. but when I try to reverse-continue or reverse-stepi after
kernel panic, the gdb only says:

"remote failure reply 'E14'"

Is there something I'm missing, or record/replay do not work with
QEMU v7.2.0 or i386?

--
Best regards,
Hyeonggon





Re: [PATCH v2 04/11] hw/arm/aspeed: Use the IEC binary prefix definitions

2023-01-17 Thread Joel Stanley
On Fri, 30 Dec 2022 at 11:35, Philippe Mathieu-Daudé  wrote:
>
> IEC binary prefixes ease code review: the unit is explicit.

I strongly prefer the existing code; it tells you the size without
having to do maths.

>
> Signed-off-by: Philippe Mathieu-Daudé 
> Reviewed-by: Peter Delevoryas 
> ---
>  hw/arm/aspeed_ast10x0.c | 3 ++-
>  hw/arm/aspeed_ast2600.c | 3 ++-
>  hw/arm/aspeed_soc.c | 4 ++--
>  3 files changed, 6 insertions(+), 4 deletions(-)
>
> diff --git a/hw/arm/aspeed_ast10x0.c b/hw/arm/aspeed_ast10x0.c
> index 122b3fd3f3..3500294df7 100644
> --- a/hw/arm/aspeed_ast10x0.c
> +++ b/hw/arm/aspeed_ast10x0.c
> @@ -10,6 +10,7 @@
>   */
>
>  #include "qemu/osdep.h"
> +#include "qemu/units.h"
>  #include "qapi/error.h"
>  #include "exec/address-spaces.h"
>  #include "sysemu/sysemu.h"
> @@ -348,7 +349,7 @@ static void aspeed_soc_ast1030_class_init(ObjectClass 
> *klass, void *data)
>  sc->name = "ast1030-a1";
>  sc->cpu_type = ARM_CPU_TYPE_NAME("cortex-m4");
>  sc->silicon_rev = AST1030_A1_SILICON_REV;
> -sc->sram_size = 0xc;
> +sc->sram_size = 768 * KiB;
>  sc->spis_num = 2;
>  sc->ehcis_num = 0;
>  sc->wdts_num = 4;
> diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
> index a79e05ddbd..72df72a540 100644
> --- a/hw/arm/aspeed_ast2600.c
> +++ b/hw/arm/aspeed_ast2600.c
> @@ -8,6 +8,7 @@
>   */
>
>  #include "qemu/osdep.h"
> +#include "qemu/units.h"
>  #include "qapi/error.h"
>  #include "hw/misc/unimp.h"
>  #include "hw/arm/aspeed_soc.h"
> @@ -619,7 +620,7 @@ static void aspeed_soc_ast2600_class_init(ObjectClass 
> *oc, void *data)
>  sc->name = "ast2600-a3";
>  sc->cpu_type = ARM_CPU_TYPE_NAME("cortex-a7");
>  sc->silicon_rev  = AST2600_A3_SILICON_REV;
> -sc->sram_size= 0x16400;
> +sc->sram_size= 89 * KiB;
>  sc->spis_num = 2;
>  sc->ehcis_num= 2;
>  sc->wdts_num = 4;
> diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
> index 2c0924d311..677342c9ed 100644
> --- a/hw/arm/aspeed_soc.c
> +++ b/hw/arm/aspeed_soc.c
> @@ -517,7 +517,7 @@ static void aspeed_soc_ast2400_class_init(ObjectClass 
> *oc, void *data)
>  sc->name = "ast2400-a1";
>  sc->cpu_type = ARM_CPU_TYPE_NAME("arm926");
>  sc->silicon_rev  = AST2400_A1_SILICON_REV;
> -sc->sram_size= 0x8000;
> +sc->sram_size= 32 * KiB;
>  sc->spis_num = 1;
>  sc->ehcis_num= 1;
>  sc->wdts_num = 2;
> @@ -544,7 +544,7 @@ static void aspeed_soc_ast2500_class_init(ObjectClass 
> *oc, void *data)
>  sc->name = "ast2500-a1";
>  sc->cpu_type = ARM_CPU_TYPE_NAME("arm1176");
>  sc->silicon_rev  = AST2500_A1_SILICON_REV;
> -sc->sram_size= 0x9000;
> +sc->sram_size= 36 * KiB;
>  sc->spis_num = 2;
>  sc->ehcis_num= 2;
>  sc->wdts_num = 3;
> --
> 2.38.1
>



reverse-{debugging,continue} not working on v7.2.0, i386 guest

2023-01-17 Thread Hyeonggon Yoo
Hello QEMU folks.
I was struggling to fix a recent heisenbug in the Linux kernel,
and fortunately the bug was reproducible with TCG and -smp 1.

I'm using qemu version 7.2.0, and guest architecture is i386.
I tried to inspect the bug using record/replay and reverse-debugging
feature in the QEMU.


recorded with:

qemu-system-i386 \
-icount shift=auto,rr=record,rrfile=$REPLAY_FILE \
-kernel arch/x86/boot/bzImage \
-cpu SandyBridge \
-initrd debian-i386.cgz \
-smp 1 \
-m 1024 \
-nographic \
-net none \
-append "page_owner=on console=ttyS0"

and replayed with:

qemu-system-i386 \
-icount shift=auto,rr=replay,rrfile=$REPLAY_FILE \
-kernel arch/x86/boot/bzImage \
-cpu SandyBridge \
-initrd debian-i386.cgz \
-smp 1 \
-m 1024 \
-nographic \
-net none \
-s \
-append "page_owner=on console=ttyS0"

(I'm using a initrd image instead of a disk file.)

The record and replay works well. The bug is reliably reproduced
when relaying. but when I try to reverse-continue or reverse-stepi after
kernel panic, the gdb only says:

"remote failure reply 'E14'"

Is there something I'm missing, or record/replay do not work with
QEMU v7.2.0 or i386?

--
Best regards,
Hyeonggon



Re: [PATCH 0/5] migration: Modified 'migrate' QAPI command for migration

2023-01-17 Thread Het Gala



On 17/01/23 4:22 pm, Claudio Fontana wrote:

Hi,

On 12/26/22 06:33, Het Gala wrote:

Current QAPI 'migrate' command design (for initiating a migration
stream) contains information regarding different migrate transport mechanism
(tcp / unix / exec), dest-host IP address, and binding port number in form of
a string. Thus the design does seem to have some design issues. Some of the
issues, stated below are:

1. Use of string URIs is a data encoding scheme within a data encoding scheme.
QEMU code should directly be able to work with the results from QAPI,
without resorting to do a second level of parsing (eg. socket_parse()).
2. For features / parameters related to migration, the migration tunables needs
to be defined and updated upfront. For example, 'migrate-set-capability'
and 'migrate-set-parameter' is required to enable multifd capability and
multifd-number of channels respectively. Instead, 'Multifd-channels' can
directly be represented as a single additional parameter to 'migrate'
QAPI. 'migrate-set-capability' and 'migrate-set-parameter' commands could
be used for runtime tunables that need setting after migration has already
started.

Is efficient and parallel migration to file of large VMs in scope for this 
design?

Thanks,

Claudio


This patch's design right now mainly focuses on revamping the design for 
'migrate' command.


In the upcomig patchset series in future, it will try to accomodate 
multifd as a feature in the same QAPI command and try to build multiple 
interface support on top of multifd feature. Main aim is to increase 
network bandwidth for migration with help of multiple interface and multifd.


Regards,
Het Gala.



Re: [PATCH 1/5] migration: Updated QAPI format for 'migrate' qemu monitor command

2023-01-17 Thread Het Gala



On 17/01/23 4:17 pm, Dr. David Alan Gilbert wrote:

* Het Gala (het.g...@nutanix.com) wrote:

From: Author Het Gala 

Existing 'migrate' QAPI design enforces transport mechanism, ip address
of destination interface and corresponding port number in the form
of a unified string 'uri' parameter. This scheme does seem to have an issue
in it, i.e. double-level encoding of URIs.

The current patch maps existing QAPI design into a well-defined data
structure - 'MigrateChannel' only from the design perspective. Please note that
the existing 'uri' parameter is kept untouched for backward compatibility.

Suggested-by: Daniel P. Berrange 
Suggested-by: Manish Mishra 
Suggested-by: Aravind Retnakaran 
Signed-off-by: Het Gala 
---
  qapi/migration.json | 121 +++-
  1 file changed, 119 insertions(+), 2 deletions(-)

diff --git a/qapi/migration.json b/qapi/migration.json
index 88ecf86ac8..753e187ce2 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -1449,12 +1449,108 @@
  ##
  { 'command': 'migrate-continue', 'data': {'state': 'MigrationStatus'} }
  
+##

+# @MigrateTransport:
+#
+# The supported communication transport mechanisms for migration
+#
+# @socket: Supported communication type between two devices for migration.
+#  Socket is able to cover all of 'tcp', 'unix', 'vsock' and
+#  'fd' already
+#
+# @exec: Supported communication type to redirect migration stream into file.
+#
+# @rdma: Supported communication type to redirect rdma type migration stream.
+#
+# Since 8.0
+##
+{ 'enum': 'MigrateTransport',
+  'data': ['socket', 'exec', 'rdma'] }
+
+##
+# @MigrateSocketAddr:
+#
+# To support different type of socket.
+#
+# @socket-type: Different type of socket connections.
+#
+# Since 8.0
+##
+{ 'struct': 'MigrateSocketAddr',
+  'data': {'socket-type': 'SocketAddress' } }
+
+##
+# @MigrateExecAddr:
+ #
+ # Since 8.0
+ ##
+{ 'struct': 'MigrateExecAddr',
+   'data' : {'exec-str': 'str' } }
+
+##
+# @MigrateRdmaAddr:
+#
+# Since 8.0
+##
+{ 'struct': 'MigrateRdmaAddr',
+   'data' : {'rdma-str': 'str' } }
+
+##
+# @MigrateAddress:
+#
+# The options available for communication transport mechanisms for migration
+#
+# Since 8.0
+##
+{ 'union' : 'MigrateAddress',
+  'base' : { 'transport' : 'MigrateTransport'},
+  'discriminator' : 'transport',
+  'data' : {
+'socket' : 'MigrateSocketAddr',
+'exec' : 'MigrateExecAddr',
+'rdma': 'MigrateRdmaAddr' } }
+
+##
+# @MigrateChannelType:
+#
+# The supported options for migration channel type requests
+#
+# @main: Support request for main outbound migration control channel
+#
+# Since 8.0
+##
+{ 'enum': 'MigrateChannelType',
+  'data': [ 'main'] }
+
+##
+# @MigrateChannel:
+#
+# Information regarding migration Channel-type for transferring packets,
+# source and corresponding destination interface for socket connection
+# and number of multifd channels over the interface.
+#
+# @channeltype: Name of Channel type for transfering packet information
+#
+# @addr: SocketAddress of destination interface
+#
+# Since 8.0
+##
+{ 'struct': 'MigrateChannel',
+  'data' : {
+   'channeltype' : 'MigrateChannelType',
+   'addr' : 'MigrateAddress' } }
+

The presence of the channeltype field suggests you're going to try to
support multiple addresses; that's OK, but can you show an example of
how that might look in the migrate command below?

Dave


Yes Dave. Other options will be "data" (for multifd) and "post-copy" 
(for post-copy migration).


I am not very sure how will we represent "post-copy" part, but I will 
give you an example of how "main" and "data" Channels will be 
represented by an example below:


-> { "execute": "migrate",
   "arguments": {
    "channels": [ { 'channeltype': 'main',
      'addr': {'transport': 'socket',
 'socket-type': { 'type': 
'inet',

'host': '10.12.34.9', 'port': '1050'} }
                        { 'channeltype': 'data',
  'addr': {'transport': 'socket',
 'socket-type': { 'type': 
'inet',

'host': '10.12.34.92', 'port': '1234'},
  'multifd-count': 5 },
    { 'channeltype': 'data',
  'addr': { 'transport': 'socket',
  'socket-type': {'type': 
'inet',

'host': '0.0.0.4', 'port': '3000'},
      'multifd-count': 3 } ] } }
So, 'data' channels will be used for multi-fd conection while 'main' 
will be used for just normal migration connection.
This 'data' channel option has been planned with a whole different 
patchset series in future.

Let me know if you have any more doubts regarding this :)

  #
  # -> { "execute": "migrate", "arguments": { "uri": "tcp:0:4446" } }
  # <- { "return": {} }
  #
+# -> { "execute": "migrate",
+#  "arguments": {
+#  

Re: [PATCH 1/5] migration: Updated QAPI format for 'migrate' qemu monitor command

2023-01-17 Thread Het Gala



On 17/01/23 4:13 pm, Dr. David Alan Gilbert wrote:

* Daniel P. Berrangé (berra...@redhat.com) wrote:

On Mon, Dec 26, 2022 at 05:33:25AM +, Het Gala wrote:

From: Author Het Gala 

Existing 'migrate' QAPI design enforces transport mechanism, ip address
of destination interface and corresponding port number in the form
of a unified string 'uri' parameter. This scheme does seem to have an issue
in it, i.e. double-level encoding of URIs.

The current patch maps existing QAPI design into a well-defined data
structure - 'MigrateChannel' only from the design perspective. Please note that
the existing 'uri' parameter is kept untouched for backward compatibility.

Suggested-by: Daniel P. Berrange 
Suggested-by: Manish Mishra 
Suggested-by: Aravind Retnakaran 
Signed-off-by: Het Gala 

Currently for 'exec:cmdstr' the 'cmdstr' part is a shell command
that is passed

   const char *argv[] = { "/bin/sh", "-c", command, NULL };

I have a strong preference for making it possible to avoid use
of shell when spawning commands, since much of thue time it is
not required and has the potential to open up vulnerabilities.
It would be nice to be able to just take the full argv directly
IOW

  { 'struct': 'MigrateExecAddr',
 'data' : {'argv': ['str'] } }

If the caller wants to keep life safe and simple now they can
use
["/bin/nc", "-U", "/some/sock"]

but if they still want to send it via shell, they can also do
so

["/bin/sh", "-c", "...arbitrary shell script code"]


+
+##
+# @MigrateRdmaAddr:
+#
+# Since 8.0
+##
+{ 'struct': 'MigrateRdmaAddr',
+   'data' : {'rdma-str': 'str' } }

Loooking at the RDMA code it takes the str, and treats it
as an IPv4 address:


 addr = g_new(InetSocketAddress, 1);
 if (!inet_parse(addr, host_port, NULL)) {
 rdma->port = atoi(addr->port);
 rdma->host = g_strdup(addr->host);
 rdma->host_port = g_strdup(host_port);
 }

so we really ought to accept an InetSocketAddress struct
directly

  { 'struct': 'MigrateRdmaAddr',
 'data' : {'rdma-str': 'InetSocketAddress' } }

I think that's probably the right thing to do; there is a native RDMA
addressing scheme that people occasionally (once a decade or so)
ask about but I don't think we've ever supported it.

Dave
Yes Dave. I will be implementing Rdma in form of InetSocketAddress only 
in the upcoming patch.

+
+##
+# @MigrateAddress:
+#
+# The options available for communication transport mechanisms for migration
+#
+# Since 8.0
+##
+{ 'union' : 'MigrateAddress',
+  'base' : { 'transport' : 'MigrateTransport'},
+  'discriminator' : 'transport',
+  'data' : {
+'socket' : 'MigrateSocketAddr',
+'exec' : 'MigrateExecAddr',
+'rdma': 'MigrateRdmaAddr' } }
+

With regards,
Daniel
--
|: 
https://urldefense.proofpoint.com/v2/url?u=https-3A__berrange.com=DwIDAw=s883GpUCOChKOHiocYtGcg=-qwZZzrw4EKSsq0BK7MBd3wW1WEpXmJeng3ZUT5uBCg=p8peRp4ioaDxoipqUtW15yQdVtCPnDBQv-1wk3r3y41SXWuI5JUUPMATMyMNDI4q=hukETUEPKU_01AyhkaMiQFWSRE1kUv84DdpSGvVjr1Q=
   -o-
https://urldefense.proofpoint.com/v2/url?u=https-3A__www.flickr.com_photos_dberrange=DwIDAw=s883GpUCOChKOHiocYtGcg=-qwZZzrw4EKSsq0BK7MBd3wW1WEpXmJeng3ZUT5uBCg=p8peRp4ioaDxoipqUtW15yQdVtCPnDBQv-


Regards,
Het Gala



Re: [PATCH v8] xen/pt: reserve PCI slot 2 for Intel igd-passthru

2023-01-17 Thread Alex Williamson
On Tue, 17 Jan 2023 19:15:57 -0500
Chuck Zmudzinski  wrote:

> On 1/17/2023 6:04 AM, Igor Mammedov wrote:
> > On Mon, 16 Jan 2023 13:00:53 -0500
> > Chuck Zmudzinski  wrote:
> >  
> > > On 1/16/23 10:33, Igor Mammedov wrote:  
> > > > On Fri, 13 Jan 2023 16:31:26 -0500
> > > > Chuck Zmudzinski  wrote:
> > > > 
> > > >> On 1/13/23 4:33 AM, Igor Mammedov wrote:
> > > >> > On Thu, 12 Jan 2023 23:14:26 -0500
> > > >> > Chuck Zmudzinski  wrote:
> > > >> >   
> > > >> >> On 1/12/23 6:03 PM, Michael S. Tsirkin wrote:  
> > > >> >> > On Thu, Jan 12, 2023 at 10:55:25PM +, Bernhard Beschow wrote: 
> > > >> >> >
> > > >> >> >> I think the change Michael suggests is very minimalistic: Move 
> > > >> >> >> the if
> > > >> >> >> condition around xen_igd_reserve_slot() into the function itself 
> > > >> >> >> and
> > > >> >> >> always call it there unconditionally -- basically turning three 
> > > >> >> >> lines
> > > >> >> >> into one. Since xen_igd_reserve_slot() seems very problem 
> > > >> >> >> specific,
> > > >> >> >> Michael further suggests to rename it to something more general. 
> > > >> >> >> All
> > > >> >> >> in all no big changes required.
> > > >> >> > 
> > > >> >> > yes, exactly.
> > > >> >> > 
> > > >> >> 
> > > >> >> OK, got it. I can do that along with the other suggestions.  
> > > >> > 
> > > >> > have you considered instead of reservation, putting a slot check in 
> > > >> > device model
> > > >> > and if it's intel igd being passed through, fail at realize time  if 
> > > >> > it can't take
> > > >> > required slot (with a error directing user to fix command line)? 
> > > >> >  
> > > >> 
> > > >> Yes, but the core pci code currently already fails at realize time
> > > >> with a useful error message if the user tries to use slot 2 for the
> > > >> igd, because of the xen platform device which has slot 2. The user
> > > >> can fix this without patching qemu, but having the user fix it on
> > > >> the command line is not the best way to solve the problem, primarily
> > > >> because the user would need to hotplug the xen platform device via a
> > > >> command line option instead of having the xen platform device added by
> > > >> pc_xen_hvm_init functions almost immediately after creating the pci
> > > >> bus, and that delay in adding the xen platform device degrades
> > > >> startup performance of the guest.
> > > >> 
> > > >> > That could be less complicated than dealing with slot reservations 
> > > >> > at the cost of
> > > >> > being less convenient.  
> > > >> 
> > > >> And also a cost of reduced startup performance
> > > > 
> > > > Could you clarify how it affects performance (and how much).
> > > > (as I see, setup done at board_init time is roughly the same
> > > > as with '-device foo' CLI options, modulo time needed to parse
> > > > options which should be negligible. and both ways are done before
> > > > guest runs)
> > > 
> > > I preface my answer by saying there is a v9, but you don't
> > > need to look at that. I will answer all your questions here.
> > > 
> > > I am going by what I observe on the main HDMI display with the
> > > different approaches. With the approach of not patching Qemu
> > > to fix this, which requires adding the Xen platform device a
> > > little later, the length of time it takes to fully load the
> > > guest is increased. I also noticed with Linux guests that use
> > > the grub bootoader, the grub vga driver cannot display the
> > > grub boot menu at the native resolution of the display, which
> > > in the tested case is 1920x1080, when the Xen platform device
> > > is added via a command line option instead of by the
> > > pc_xen_hvm_init_pci fucntion in pc_piix.c, but with this patch
> > > to Qemu, the grub menu is displayed at the full, 1920x1080
> > > native resolution of the display. Once the guest fully loads,
> > > there is no noticeable difference in performance. It is mainly
> > > a degradation in startup performance, not performance once
> > > the guest OS is fully loaded.  
> >
> > Looking at igd-assign.txt, it recommends to add IGD using '-device' CLI
> > option, and actually drop at least graphics defaults explicitly.
> > So it is expected to work fine even when IGD is constructed with
> > '-device'.
> >
> > Could you provide full CLI current xen starts QEMU with and then
> > a CLI you used (with explicit -device for IGD) that leads
> > to reduced performance?
> >
> > CCing vfio folks who might have an idea what could be wrong based
> > on vfio experience.  
> 
> Actually, the igd is not added with an explicit -device option using Xen:
> 
>    1573 ?    Ssl    0:42 /usr/bin/qemu-system-i386 -xen-domid 1 
> -no-shutdown -chardev 
> socket,id=libxl-cmd,path=/var/run/xen/qmp-libxl-1,server,nowait -mon 
> chardev=libxl-cmd,mode=control -chardev 
> socket,id=libxenstat-cmd,path=/var/run/xen/qmp-libxenstat-1,server,nowait 
> -mon chardev=libxenstat-cmd,mode=control -nodefaults 

Re: completion timeouts with pin-based interrupts in QEMU hw/nvme

2023-01-17 Thread Keith Busch
On Thu, Jan 12, 2023 at 02:10:51PM +0100, Klaus Jensen wrote:
> Hi all (linux-nvme, qemu-devel, maintainers),
> 
> On QEMU riscv64, which does not use MSI/MSI-X and thus relies on
> pin-based interrupts, I'm seeing occasional completion timeouts, i.e.
> 
>   nvme nvme0: I/O 333 QID 1 timeout, completion polled

I finally got a riscv setup recreating this, and I am not sure how
you're getting a "completion polled" here. I find that the polling from
here progresses the request state to IDLE, so the timeout handler moves
on to aborting because it's expecting COMPLETED. The driver should not
be doing that, so I'll fix that up while also investigating why the
interrupt isn't retriggering as expected.



[PATCH v4 2/5] hw/arm/aspeed: Replace aspeed_eeprom_init with at24c_eeprom_init

2023-01-17 Thread Peter Delevoryas
aspeed_eeprom_init is an exact copy of at24c_eeprom_init, not needed.

Signed-off-by: Peter Delevoryas 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Joel Stanley 
---
 hw/arm/aspeed.c | 95 ++---
 1 file changed, 43 insertions(+), 52 deletions(-)

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 1f9799d4321e..c929c61d582a 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -660,15 +660,6 @@ static void g220a_bmc_i2c_init(AspeedMachineState *bmc)
   eeprom_buf);
 }
 
-static void aspeed_eeprom_init(I2CBus *bus, uint8_t addr, uint32_t rsize)
-{
-I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
-DeviceState *dev = DEVICE(i2c_dev);
-
-qdev_prop_set_uint32(dev, "rom-size", rsize);
-i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
-}
-
 static void fp5280g2_bmc_i2c_init(AspeedMachineState *bmc)
 {
 AspeedSoCState *soc = >soc;
@@ -701,7 +692,7 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
 AspeedSoCState *soc = >soc;
 I2CSlave *i2c_mux;
 
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 0), 0x51, 32 * KiB);
+at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 0), 0x51, 32 * KiB);
 
 create_pca9552(soc, 3, 0x61);
 
@@ -714,9 +705,9 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
  0x4a);
 i2c_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 4),
   "pca9546", 0x70);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x52, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x52, 64 * KiB);
 create_pca9552(soc, 4, 0x60);
 
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 5), TYPE_TMP105,
@@ -727,8 +718,8 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
 create_pca9552(soc, 5, 0x61);
 i2c_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 5),
   "pca9546", 0x70);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
 
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 6), TYPE_TMP105,
  0x48);
@@ -738,10 +729,10 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
  0x4b);
 i2c_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 6),
   "pca9546", 0x70);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x50, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 3), 0x51, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x50, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 3), 0x51, 64 * KiB);
 
 create_pca9552(soc, 7, 0x30);
 create_pca9552(soc, 7, 0x31);
@@ -754,15 +745,15 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 7), TYPE_TMP105,
  0x48);
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 7), "max31785", 
0x52);
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 7), 0x50, 64 * KiB);
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 7), 0x51, 64 * KiB);
+at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 7), 0x50, 64 * KiB);
+at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 7), 0x51, 64 * KiB);
 
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 8), TYPE_TMP105,
  0x48);
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 8), TYPE_TMP105,
  0x4a);
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 8), 0x50, 64 * KiB);
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 8), 0x51, 64 * KiB);
+at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 8), 0x50, 64 * KiB);
+at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 8), 0x51, 64 * KiB);
 create_pca9552(soc, 8, 0x60);
 create_pca9552(soc, 8, 0x61);
 /* Bus 8: ucd90320@11 */
@@ -771,11 +762,11 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
 
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 9), "tmp423", 0x4c);
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 9), "tmp423", 0x4d);
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 9), 

[PATCH v4 1/5] hw/arm: Extract at24c_eeprom_init helper from Aspeed and Nuvoton boards

2023-01-17 Thread Peter Delevoryas
This helper is useful in board initialization because lets users initialize and
realize an EEPROM on an I2C bus with a single function call.

Signed-off-by: Peter Delevoryas 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Joel Stanley 
---
 hw/arm/aspeed.c | 10 +-
 hw/arm/npcm7xx_boards.c | 20 +---
 hw/nvram/eeprom_at24c.c | 12 
 include/hw/nvram/eeprom_at24c.h | 23 +++
 4 files changed, 41 insertions(+), 24 deletions(-)
 create mode 100644 include/hw/nvram/eeprom_at24c.h

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 55f114ef729f..1f9799d4321e 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -17,6 +17,7 @@
 #include "hw/i2c/i2c_mux_pca954x.h"
 #include "hw/i2c/smbus_eeprom.h"
 #include "hw/misc/pca9552.h"
+#include "hw/nvram/eeprom_at24c.h"
 #include "hw/sensor/tmp105.h"
 #include "hw/misc/led.h"
 #include "hw/qdev-properties.h"
@@ -429,15 +430,6 @@ static void aspeed_machine_init(MachineState *machine)
 arm_load_kernel(ARM_CPU(first_cpu), machine, _board_binfo);
 }
 
-static void at24c_eeprom_init(I2CBus *bus, uint8_t addr, uint32_t rsize)
-{
-I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
-DeviceState *dev = DEVICE(i2c_dev);
-
-qdev_prop_set_uint32(dev, "rom-size", rsize);
-i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
-}
-
 static void palmetto_bmc_i2c_init(AspeedMachineState *bmc)
 {
 AspeedSoCState *soc = >soc;
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
index 6bc6f5d2fe29..9b31207a06e9 100644
--- a/hw/arm/npcm7xx_boards.c
+++ b/hw/arm/npcm7xx_boards.c
@@ -21,6 +21,7 @@
 #include "hw/i2c/i2c_mux_pca954x.h"
 #include "hw/i2c/smbus_eeprom.h"
 #include "hw/loader.h"
+#include "hw/nvram/eeprom_at24c.h"
 #include "hw/qdev-core.h"
 #include "hw/qdev-properties.h"
 #include "qapi/error.h"
@@ -140,17 +141,6 @@ static I2CBus *npcm7xx_i2c_get_bus(NPCM7xxState *soc, 
uint32_t num)
 return I2C_BUS(qdev_get_child_bus(DEVICE(>smbus[num]), "i2c-bus"));
 }
 
-static void at24c_eeprom_init(NPCM7xxState *soc, int bus, uint8_t addr,
-  uint32_t rsize)
-{
-I2CBus *i2c_bus = npcm7xx_i2c_get_bus(soc, bus);
-I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
-DeviceState *dev = DEVICE(i2c_dev);
-
-qdev_prop_set_uint32(dev, "rom-size", rsize);
-i2c_slave_realize_and_unref(i2c_dev, i2c_bus, _abort);
-}
-
 static void npcm7xx_init_pwm_splitter(NPCM7xxMachine *machine,
   NPCM7xxState *soc, const int *fan_counts)
 {
@@ -253,8 +243,8 @@ static void quanta_gsj_i2c_init(NPCM7xxState *soc)
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 3), "tmp105", 0x5c);
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 4), "tmp105", 0x5c);
 
-at24c_eeprom_init(soc, 9, 0x55, 8192);
-at24c_eeprom_init(soc, 10, 0x55, 8192);
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 9), 0x55, 8192);
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 10), 0x55, 8192);
 
 /*
  * i2c-11:
@@ -360,7 +350,7 @@ static void kudo_bmc_i2c_init(NPCM7xxState *soc)
 
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 4), TYPE_PCA9548, 0x77);
 
-at24c_eeprom_init(soc, 4, 0x50, 8192); /* mbfru */
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 4), 0x50, 8192); /* mbfru */
 
 i2c_mux = i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 13),
   TYPE_PCA9548, 0x77);
@@ -371,7 +361,7 @@ static void kudo_bmc_i2c_init(NPCM7xxState *soc)
 i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 4), "tmp105", 0x48);
 i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 5), "tmp105", 0x49);
 
-at24c_eeprom_init(soc, 14, 0x55, 8192); /* bmcfru */
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 14), 0x55, 8192); /* bmcfru */
 
 /* TODO: Add remaining i2c devices. */
 }
diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
index 2d4d8b952f38..98857e3626b9 100644
--- a/hw/nvram/eeprom_at24c.c
+++ b/hw/nvram/eeprom_at24c.c
@@ -12,6 +12,7 @@
 #include "qapi/error.h"
 #include "qemu/module.h"
 #include "hw/i2c/i2c.h"
+#include "hw/nvram/eeprom_at24c.h"
 #include "hw/qdev-properties.h"
 #include "hw/qdev-properties-system.h"
 #include "sysemu/block-backend.h"
@@ -128,6 +129,17 @@ int at24c_eeprom_send(I2CSlave *s, uint8_t data)
 return 0;
 }
 
+I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t rom_size)
+{
+I2CSlave *i2c_dev = i2c_slave_new(TYPE_AT24C_EE, address);
+DeviceState *dev = DEVICE(i2c_dev);
+
+qdev_prop_set_uint32(dev, "rom-size", rom_size);
+i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
+
+return i2c_dev;
+}
+
 static void at24c_eeprom_realize(DeviceState *dev, Error **errp)
 {
 EEPROMState *ee = AT24C_EE(dev);
diff --git a/include/hw/nvram/eeprom_at24c.h b/include/hw/nvram/eeprom_at24c.h
new file mode 100644
index ..196db309d451
--- /dev/null
+++ b/include/hw/nvram/eeprom_at24c.h
@@ 

[PATCH v4 3/5] hw/nvram/eeprom_at24c: Add init_rom field and at24c_eeprom_init_rom helper

2023-01-17 Thread Peter Delevoryas
Allows users to specify binary data to initialize an EEPROM, allowing users to
emulate data programmed at manufacturing time.

- Added init_rom and init_rom_size attributes to TYPE_AT24C_EE
- Added at24c_eeprom_init_rom helper function to initialize attributes
- If -drive property is provided, it overrides init_rom data

Signed-off-by: Peter Delevoryas 
Reviewed-by: Joel Stanley 
---
 hw/nvram/eeprom_at24c.c | 37 -
 include/hw/nvram/eeprom_at24c.h | 16 ++
 2 files changed, 48 insertions(+), 5 deletions(-)

diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
index 98857e3626b9..f8d751fa278d 100644
--- a/hw/nvram/eeprom_at24c.c
+++ b/hw/nvram/eeprom_at24c.c
@@ -50,6 +50,9 @@ struct EEPROMState {
 uint8_t *mem;
 
 BlockBackend *blk;
+
+const uint8_t *init_rom;
+uint32_t init_rom_size;
 };
 
 static
@@ -131,19 +134,38 @@ int at24c_eeprom_send(I2CSlave *s, uint8_t data)
 
 I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t rom_size)
 {
-I2CSlave *i2c_dev = i2c_slave_new(TYPE_AT24C_EE, address);
-DeviceState *dev = DEVICE(i2c_dev);
+return at24c_eeprom_init_rom(bus, address, rom_size, NULL, 0);
+}
+
+I2CSlave *at24c_eeprom_init_rom(I2CBus *bus, uint8_t address, uint32_t 
rom_size,
+const uint8_t *init_rom, uint32_t 
init_rom_size)
+{
+EEPROMState *s;
+
+s = AT24C_EE(qdev_new(TYPE_AT24C_EE));
+
+qdev_prop_set_uint8(DEVICE(s), "address", address);
+qdev_prop_set_uint32(DEVICE(s), "rom-size", rom_size);
 
-qdev_prop_set_uint32(dev, "rom-size", rom_size);
-i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
+/* TODO: Model init_rom with QOM properties. */
+s->init_rom = init_rom;
+s->init_rom_size = init_rom_size;
 
-return i2c_dev;
+i2c_slave_realize_and_unref(I2C_SLAVE(s), bus, _abort);
+
+return I2C_SLAVE(s);
 }
 
 static void at24c_eeprom_realize(DeviceState *dev, Error **errp)
 {
 EEPROMState *ee = AT24C_EE(dev);
 
+if (ee->init_rom_size > ee->rsize) {
+error_setg(errp, "%s: init rom is larger than rom: %u > %u",
+   TYPE_AT24C_EE, ee->init_rom_size, ee->rsize);
+return;
+}
+
 if (ee->blk) {
 int64_t len = blk_getlength(ee->blk);
 
@@ -163,6 +185,7 @@ static void at24c_eeprom_realize(DeviceState *dev, Error 
**errp)
 }
 
 ee->mem = g_malloc0(ee->rsize);
+
 }
 
 static
@@ -176,6 +199,10 @@ void at24c_eeprom_reset(DeviceState *state)
 
 memset(ee->mem, 0, ee->rsize);
 
+if (ee->init_rom) {
+memcpy(ee->mem, ee->init_rom, MIN(ee->init_rom_size, ee->rsize));
+}
+
 if (ee->blk) {
 int ret = blk_pread(ee->blk, 0, ee->rsize, ee->mem, 0);
 
diff --git a/include/hw/nvram/eeprom_at24c.h b/include/hw/nvram/eeprom_at24c.h
index 196db309d451..acb9857b2add 100644
--- a/include/hw/nvram/eeprom_at24c.h
+++ b/include/hw/nvram/eeprom_at24c.h
@@ -20,4 +20,20 @@
  */
 I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t rom_size);
 
+
+/*
+ * Create and realize an AT24C EEPROM device on the heap with initial data.
+ * @bus: I2C bus to put it on
+ * @address: I2C address of the EEPROM slave when put on a bus
+ * @rom_size: size of the EEPROM
+ * @init_rom: Array of bytes to initialize EEPROM memory with
+ * @init_rom_size: Size of @init_rom, must be less than or equal to @rom_size
+ *
+ * Create the device state structure, initialize it, put it on the specified
+ * @bus, and drop the reference to it (the device is realized). Copies the data
+ * from @init_rom to the beginning of the EEPROM memory buffer.
+ */
+I2CSlave *at24c_eeprom_init_rom(I2CBus *bus, uint8_t address, uint32_t 
rom_size,
+const uint8_t *init_rom, uint32_t 
init_rom_size);
+
 #endif
-- 
2.39.0




[PATCH v4 5/5] hw/nvram/eeprom_at24c: Make reset behavior more like hardware

2023-01-17 Thread Peter Delevoryas
EEPROM's are a form of non-volatile memory. After power-cycling an EEPROM,
I would expect the I2C state machine to be reset to default values, but I
wouldn't really expect the memory to change at all.

The current implementation of the at24c EEPROM resets its internal memory on
reset. This matches the specification in docs/devel/reset.rst:

  Cold reset is supported by every resettable object. In QEMU, it means we reset
  to the initial state corresponding to the start of QEMU; this might differ
  from what is a real hardware cold reset. It differs from other resets (like
  warm or bus resets) which may keep certain parts untouched.

But differs from my intuition. For example, if someone writes some information
to an EEPROM, then AC power cycles their board, they would expect the EEPROM to
retain that information. It's very useful to be able to test things like this
in QEMU as well, to verify software instrumentation like determining the cause
of a reboot.

Fixes: 5d8424dbd3e8 ("nvram: add AT24Cx i2c eeprom")
Signed-off-by: Peter Delevoryas 
Reviewed-by: Joel Stanley 
---
 hw/nvram/eeprom_at24c.c | 22 ++
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
index f8d751fa278d..5074776bff04 100644
--- a/hw/nvram/eeprom_at24c.c
+++ b/hw/nvram/eeprom_at24c.c
@@ -185,18 +185,6 @@ static void at24c_eeprom_realize(DeviceState *dev, Error 
**errp)
 }
 
 ee->mem = g_malloc0(ee->rsize);
-
-}
-
-static
-void at24c_eeprom_reset(DeviceState *state)
-{
-EEPROMState *ee = AT24C_EE(state);
-
-ee->changed = false;
-ee->cur = 0;
-ee->haveaddr = 0;
-
 memset(ee->mem, 0, ee->rsize);
 
 if (ee->init_rom) {
@@ -214,6 +202,16 @@ void at24c_eeprom_reset(DeviceState *state)
 }
 }
 
+static
+void at24c_eeprom_reset(DeviceState *state)
+{
+EEPROMState *ee = AT24C_EE(state);
+
+ee->changed = false;
+ee->cur = 0;
+ee->haveaddr = 0;
+}
+
 static Property at24c_eeprom_props[] = {
 DEFINE_PROP_UINT32("rom-size", EEPROMState, rsize, 0),
 DEFINE_PROP_BOOL("writable", EEPROMState, writable, true),
-- 
2.39.0




[PATCH v4 4/5] hw/arm/aspeed: Add aspeed_eeprom.c

2023-01-17 Thread Peter Delevoryas
- Create aspeed_eeprom.c and aspeed_eeprom.h
- Include aspeed_eeprom.c in CONFIG_ASPEED meson source files
- Include aspeed_eeprom.h in aspeed.c
- Add fby35_bmc_fruid data
- Use new at24c_eeprom_init_rom helper to initialize BMC FRUID EEPROM with data
  from aspeed_eeprom.c

wget 
https://github.com/facebook/openbmc/releases/download/openbmc-e2294ff5d31d/fby35.mtd
qemu-system-aarch64 -machine fby35-bmc -nographic -mtdblock fby35.mtd
...
user: root
pass: 0penBmc
...
root@bmc-oob:~# fruid-util bb

FRU Information   : Baseboard
---   : --
Chassis Type  : Rack Mount Chassis
Chassis Part Number   : N/A
Chassis Serial Number : N/A
Board Mfg Date: Fri Jan  7 10:30:00 2022
Board Mfg : XX
Board Product : Management Board wBMC
Board Serial  : X
Board Part Number : XX
Board FRU ID  : 1.0
Board Custom Data 1   : X
Board Custom Data 2   : XX
Product Manufacturer  : XX
Product Name  : Yosemite V3.5 EVT2
Product Part Number   : XX
Product Version   : EVT2
Product Serial: X
Product Asset Tag : XXX
Product FRU ID: 1.0
Product Custom Data 1 : X
Product Custom Data 2 : N/A
root@bmc-oob:~# fruid-util bmc

FRU Information   : BMC
---   : --
Board Mfg Date: Mon Jan 10 21:42:00 2022
Board Mfg : XX
Board Product : BMC Storage Module
Board Serial  : X
Board Part Number : XX
Board FRU ID  : 1.0
Board Custom Data 1   : X
Board Custom Data 2   : XX
Product Manufacturer  : XX
Product Name  : Yosemite V3.5 EVT2
Product Part Number   : XX
Product Version   : EVT2
Product Serial: X
Product Asset Tag : XXX
Product FRU ID: 1.0
Product Custom Data 1 : X
Product Custom Data 2 : Config A
root@bmc-oob:~# fruid-util nic

FRU Information   : NIC
---   : --
Board Mfg Date: Tue Nov  2 08:51:00 2021
Board Mfg : 
Board Product : Mellanox ConnectX-6 DX OCP3.0
Board Serial  : 
Board Part Number : X
Board FRU ID  : FRU Ver 0.02
Product Manufacturer  : 
Product Name  : Mellanox ConnectX-6 DX OCP3.0
Product Part Number   : X
Product Version   : A9
Product Serial: 
Product Custom Data 3 : ConnectX-6 DX

Signed-off-by: Peter Delevoryas 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Joel Stanley 
---
 hw/arm/aspeed.c| 10 --
 hw/arm/aspeed_eeprom.c | 78 ++
 hw/arm/aspeed_eeprom.h | 16 +
 hw/arm/meson.build |  1 +
 4 files changed, 102 insertions(+), 3 deletions(-)
 create mode 100644 hw/arm/aspeed_eeprom.c
 create mode 100644 hw/arm/aspeed_eeprom.h

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index c929c61d582a..382965f82c38 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -14,6 +14,7 @@
 #include "hw/arm/boot.h"
 #include "hw/arm/aspeed.h"
 #include "hw/arm/aspeed_soc.h"
+#include "hw/arm/aspeed_eeprom.h"
 #include "hw/i2c/i2c_mux_pca954x.h"
 #include "hw/i2c/smbus_eeprom.h"
 #include "hw/misc/pca9552.h"
@@ -940,9 +941,12 @@ static void fby35_i2c_init(AspeedMachineState *bmc)
 
 at24c_eeprom_init(i2c[4], 0x51, 128 * KiB);
 at24c_eeprom_init(i2c[6], 0x51, 128 * KiB);
-at24c_eeprom_init(i2c[8], 0x50, 32 * KiB);
-at24c_eeprom_init(i2c[11], 0x51, 128 * KiB);
-at24c_eeprom_init(i2c[11], 0x54, 128 * KiB);
+at24c_eeprom_init_rom(i2c[8], 0x50, 32 * KiB, fby35_nic_fruid,
+  sizeof(fby35_nic_fruid));
+at24c_eeprom_init_rom(i2c[11], 0x51, 128 * KiB, fby35_bb_fruid,
+  sizeof(fby35_bb_fruid));
+at24c_eeprom_init_rom(i2c[11], 0x54, 128 * KiB, fby35_bmc_fruid,
+  sizeof(fby35_bmc_fruid));
 
 /*
  * TODO: There is a multi-master i2c connection to an AST1030 MiniBMC on
diff --git a/hw/arm/aspeed_eeprom.c b/hw/arm/aspeed_eeprom.c
new file mode 100644
index ..9d0700d4b709
--- /dev/null
+++ b/hw/arm/aspeed_eeprom.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ */
+
+#include "aspeed_eeprom.h"
+
+const uint8_t fby35_nic_fruid[] = {
+0x01, 0x00, 0x00, 0x01, 0x0f, 0x20, 0x00, 0xcf, 0x01, 0x0e, 0x19, 0xd7,
+0x5e, 0xcf, 0xc8, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xdd,
+0x4d, 0x65, 0x6c, 0x6c, 0x61, 0x6e, 0x6f, 0x78, 0x20, 0x43, 0x6f, 0x6e,
+0x6e, 

[PATCH v4 0/5] hw/nvram/eeprom_at24c: Cleanup + FRUID EEPROM init example

2023-01-17 Thread Peter Delevoryas
v1: https://lore.kernel.org/qemu-devel/20230114170151.87833-1-pe...@pjd.dev/
v2:
- Squashed 3 commits from original series into extract helper commit
- Dropped last 2 commits from original series
- Changed at24c_eeprom_init to return the I2CSlave object
- Added commit to introduce at24c-eeprom "init_rom" attribute
- Added aspeed_eeprom.c and fby35-bmc BMC FRUID EEPROM initialization
- Added commit to change reset behavior for at24c-eeprom (optional)
v3:
- Added doc comments to function headers
- Added fby35 NIC and baseboard EEPROM's (to illustrate 2+ EEPROM's)
- Replaced "extern uint32 fby35_bmc_fruid_size" by adding explicit array
  sizes, e.g. "extern uint8_t fby35_bmc_fruid[200]".
- Fixed Meta Platforms licenses by adding SPDX-License-Identifier for GPL2.
- Moved ee->init_rom initialization code before ee->blk, so that -drive
  property overrides init_rom initialization. This gives more flexibility
  (people can override contents of an AT24C EEPROM using a file for
  debugging/prototyping) while still allowing the init_rom data to be
  specified for a board for default behavior.
v4:
- Moved at24c_eeprom_init_rom doc comment to the patch introducing the
  function (moved from patch 4/5 to patch 3/5).
- Added review tags from Joel

Thanks,
Peter

Peter Delevoryas (5):
  hw/arm: Extract at24c_eeprom_init helper from Aspeed and Nuvoton
boards
  hw/arm/aspeed: Replace aspeed_eeprom_init with at24c_eeprom_init
  hw/nvram/eeprom_at24c: Add init_rom field and at24c_eeprom_init_rom
helper
  hw/arm/aspeed: Add aspeed_eeprom.c
  hw/nvram/eeprom_at24c: Make reset behavior more like hardware

 hw/arm/aspeed.c | 109 ++--
 hw/arm/aspeed_eeprom.c  |  78 +++
 hw/arm/aspeed_eeprom.h  |  16 +
 hw/arm/meson.build  |   1 +
 hw/arm/npcm7xx_boards.c |  20 ++
 hw/nvram/eeprom_at24c.c |  59 +
 include/hw/nvram/eeprom_at24c.h |  39 
 7 files changed, 235 insertions(+), 87 deletions(-)
 create mode 100644 hw/arm/aspeed_eeprom.c
 create mode 100644 hw/arm/aspeed_eeprom.h
 create mode 100644 include/hw/nvram/eeprom_at24c.h

-- 
2.39.0




Re: [PATCH RESEND v3 08/10] migration: Implement dirty-limit convergence algo

2023-01-17 Thread Hyman Huang




在 2023/1/11 22:11, Markus Armbruster 写道:

huang...@chinatelecom.cn writes:


From: Hyman Huang(黄勇) 

Implement dirty-limit convergence algo for live migration,
which is kind of like auto-converge algo but using dirty-limit
instead of cpu throttle to make migration convergent.

Enable dirty page limit if dirty_rate_high_cnt greater than 2
when dirty-limit capability enabled, disable dirty-limit if
migration be cancled.

Note that "set_vcpu_dirty_limit", "cancel_vcpu_dirty_limit"
commands are not allowed during dirty-limit live migration.


Only during live migration, or also during migration of a stopped guest?
If the latter, the easy fix is to scratch "live".


Signed-off-by: Hyman Huang(黄勇) 
---
  migration/migration.c  |  3 +++
  migration/ram.c| 63 ++
  migration/trace-events |  1 +
  softmmu/dirtylimit.c   | 22 ++
  4 files changed, 74 insertions(+), 15 deletions(-)

diff --git a/migration/migration.c b/migration/migration.c
index 702e7f4..127d0fe 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -240,6 +240,9 @@ void migration_cancel(const Error *error)
  if (error) {
  migrate_set_error(current_migration, error);
  }
+if (migrate_dirty_limit()) {
+qmp_cancel_vcpu_dirty_limit(false, -1, NULL);
+}
  migrate_fd_cancel(current_migration);
  }
  
diff --git a/migration/ram.c b/migration/ram.c

index 5e66652..78b9167 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -45,6 +45,7 @@
  #include "qapi/error.h"
  #include "qapi/qapi-types-migration.h"
  #include "qapi/qapi-events-migration.h"
+#include "qapi/qapi-commands-migration.h"
  #include "qapi/qmp/qerror.h"
  #include "trace.h"
  #include "exec/ram_addr.h"
@@ -57,6 +58,8 @@
  #include "qemu/iov.h"
  #include "multifd.h"
  #include "sysemu/runstate.h"
+#include "sysemu/dirtylimit.h"
+#include "sysemu/kvm.h"
  
  #include "hw/boards.h" /* for machine_dump_guest_core() */
  
@@ -1139,6 +1142,30 @@ static void migration_update_rates(RAMState *rs, int64_t end_time)

  }
  }
  
+/*

+ * Enable dirty-limit to throttle down the guest
+ */
+static void migration_dirty_limit_guest(void)
+{
+static int64_t quota_dirtyrate;
+MigrationState *s = migrate_get_current();
+
+/*
+ * If dirty limit already enabled and migration parameter
+ * vcpu-dirty-limit untouched.
+ */
+if (dirtylimit_in_service() &&
+quota_dirtyrate == s->parameters.vcpu_dirty_limit) {
+return;
+}
+
+quota_dirtyrate = s->parameters.vcpu_dirty_limit;
+
+/* Set or update quota dirty limit */
+qmp_set_vcpu_dirty_limit(false, -1, quota_dirtyrate, NULL);
+trace_migration_dirty_limit_guest(quota_dirtyrate);
+}
+
  static void migration_trigger_throttle(RAMState *rs)
  {
  MigrationState *s = migrate_get_current();
@@ -1148,26 +1175,32 @@ static void migration_trigger_throttle(RAMState *rs)
  uint64_t bytes_dirty_period = rs->num_dirty_pages_period * 
TARGET_PAGE_SIZE;
  uint64_t bytes_dirty_threshold = bytes_xfer_period * threshold / 100;
  
-/* During block migration the auto-converge logic incorrectly detects

- * that ram migration makes no progress. Avoid this by disabling the
- * throttling logic during the bulk phase of block migration. */
-if (blk_mig_bulk_active()) {
-return;
-}
+/*
+ * The following detection logic can be refined later. For now:
+ * Check to see if the ratio between dirtied bytes and the approx.
+ * amount of bytes that just got transferred since the last time
+ * we were in this routine reaches the threshold. If that happens
+ * twice, start or increase throttling.
+ */
  
-if (migrate_auto_converge()) {

-/* The following detection logic can be refined later. For now:
-   Check to see if the ratio between dirtied bytes and the approx.
-   amount of bytes that just got transferred since the last time
-   we were in this routine reaches the threshold. If that happens
-   twice, start or increase throttling. */
+if ((bytes_dirty_period > bytes_dirty_threshold) &&
+(++rs->dirty_rate_high_cnt >= 2)) {
+rs->dirty_rate_high_cnt = 0;
+/*
+ * During block migration the auto-converge logic incorrectly detects
+ * that ram migration makes no progress. Avoid this by disabling the
+ * throttling logic during the bulk phase of block migration
+ */
+if (blk_mig_bulk_active()) {
+return;
+}
  
-if ((bytes_dirty_period > bytes_dirty_threshold) &&

-(++rs->dirty_rate_high_cnt >= 2)) {
+if (migrate_auto_converge()) {
  trace_migration_throttle();
-rs->dirty_rate_high_cnt = 0;
  mig_throttle_guest_down(bytes_dirty_period,
  bytes_dirty_threshold);
+} else if (migrate_dirty_limit()) {
+

Re: [PATCH RESEND v3 09/10] migration: Export dirty-limit time info for observation

2023-01-17 Thread Hyman Huang




在 2023/1/11 22:38, Markus Armbruster 写道:

huang...@chinatelecom.cn writes:


From: Hyman Huang(黄勇) 

Export dirty limit throttle time and estimated ring full
time, through which we can observe if dirty limit take
effect during live migration.


Suggest something like "Extend query-migrate to provide ..." both here
and in subject.


Signed-off-by: Hyman Huang(黄勇) 
---
  include/sysemu/dirtylimit.h |  2 ++
  migration/migration.c   | 10 ++
  monitor/hmp-cmds.c  | 10 ++
  qapi/migration.json | 15 ++-
  softmmu/dirtylimit.c| 39 +++
  5 files changed, 75 insertions(+), 1 deletion(-)

diff --git a/include/sysemu/dirtylimit.h b/include/sysemu/dirtylimit.h
index 8d2c1f3..f15e01d 100644
--- a/include/sysemu/dirtylimit.h
+++ b/include/sysemu/dirtylimit.h
@@ -34,4 +34,6 @@ void dirtylimit_set_vcpu(int cpu_index,
  void dirtylimit_set_all(uint64_t quota,
  bool enable);
  void dirtylimit_vcpu_execute(CPUState *cpu);
+int64_t dirtylimit_throttle_time_per_full(void);
+int64_t dirtylimit_ring_full_time(void);
  #endif
diff --git a/migration/migration.c b/migration/migration.c
index 127d0fe..3f92389 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -62,6 +62,7 @@
  #include "yank_functions.h"
  #include "sysemu/qtest.h"
  #include "sysemu/kvm.h"
+#include "sysemu/dirtylimit.h"
  
  #define MAX_THROTTLE  (128 << 20)  /* Migration transfer speed throttling */
  
@@ -1114,6 +1115,15 @@ static void populate_ram_info(MigrationInfo *info, MigrationState *s)

  info->ram->remaining = ram_bytes_remaining();
  info->ram->dirty_pages_rate = ram_counters.dirty_pages_rate;
  }
+
+if (migrate_dirty_limit() && dirtylimit_in_service()) {
+info->has_dirty_limit_throttle_time_per_full = true;
+info->dirty_limit_throttle_time_per_full =
+dirtylimit_throttle_time_per_full();
+
+info->has_dirty_limit_ring_full_time = true;
+info->dirty_limit_ring_full_time = dirtylimit_us_ring_full();
+}
  }
  
  static void populate_disk_info(MigrationInfo *info)

diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index 9ad6ee5..c3aaba3 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -339,6 +339,16 @@ void hmp_info_migrate(Monitor *mon, const QDict *qdict)
 info->cpu_throttle_percentage);
  }
  
+if (info->has_dirty_limit_throttle_time_per_full) {

+monitor_printf(mon, "dirty-limit throttle time: %" PRIi64 " us\n",
+   info->dirty_limit_throttle_time_per_full);
+}
+
+if (info->has_dirty_limit_ring_full_time) {
+monitor_printf(mon, "dirty-limit ring full time: %" PRIi64 " us\n",
+   info->dirty_limit_ring_full_time);
+}


I discuss naming below.  If we change the names, we probably want to
change the string literals here, too.


+
  if (info->has_postcopy_blocktime) {
  monitor_printf(mon, "postcopy blocktime: %u\n",
 info->postcopy_blocktime);
diff --git a/qapi/migration.json b/qapi/migration.json
index 6055fdc..ae7d22d 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -242,6 +242,17 @@
  #   Present and non-empty when migration is blocked.
  #   (since 6.0)
  #
+# @dirty-limit-throttle-time-per-full: Maximum throttle time (in microseconds) 
of virtual
+#  CPUs each dirty ring full round, used 
to observe


What's a dirty "ring full round"?  Is it a migration round?  Something
else?

No, not migration round.

When dirty ring is full and return to userspace due to the exception 
"KVM_EXIT_DIRTY_RING_FULL"。 The "dirty-limit" logic would make vcpu 
sleep some time, which is adjusted dynamically every exception, and 
which is represented by the "dirty-limit-throttle-time-per-full".


As to "dirty ring full round" (sorry about that i failed to make it 
clear), It represents one round that dirty ring of vCPU is full.



+#  if dirty-limit take effect during live 
migration.


takes effect

I think "if dirty-limit takes effect" isn't quite right.  We can use
this to observe how MigrationCapability dirty-limit affects the guest.
What about "shows how MigrationCapability dirty-limit affects the
guest"?

It's better than what i described.



Even though dirty-limit-throttle-time-per-full is quite long, it still
feels abbreviated.  Full what?  What about
dirty-limit-throttle-time-per-round?  Naming is hard.

It's ok




+#  (since 7.3)
+#
+# @dirty-limit-ring-full-time: Estimated average dirty ring full time (in 
microseconds)
+#  each dirty ring full round, note that the value 
equals
+#  dirty ring memory size divided by average dirty 
page rate
+#  of virtual 

Re: [PATCH v3 3/5] hw/nvram/eeprom_at24c: Add init_rom field and at24c_eeprom_init_rom helper

2023-01-17 Thread Peter Delevoryas
On Wed, Jan 18, 2023 at 02:22:01AM +, Joel Stanley wrote:
> On Tue, 17 Jan 2023 at 23:24, Peter Delevoryas  wrote:
> >
> > Allows users to specify binary data to initialize an EEPROM, allowing users 
> > to
> > emulate data programmed at manufacturing time.
> 
> I like it. Is there somewhere sensible to add a description to the
> code base? Perhaps as a comment to your new function?

Actually yes, I added the comment to the wrong patch in this series. I'll
submit a v4 really quick to correct that, and include the notes you mentioned
(like the fact that we'll only copy up-to rom-size bytes from the init_rom
data).

> 
> >
> > - Added init_rom and init_rom_size attributes to TYPE_AT24C_EE
> > - Added at24c_eeprom_init_rom helper function to initialize attributes
> > - If -drive property is provided, it overrides init_rom data
> >
> > Signed-off-by: Peter Delevoryas 
> 
> Reviewed-by: Joel Stanley 

Thanks for the reviews!

> 
> > ---
> >  hw/nvram/eeprom_at24c.c | 37 -
> >  include/hw/nvram/eeprom_at24c.h |  2 ++
> >  2 files changed, 34 insertions(+), 5 deletions(-)
> >
> > diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
> > index 98857e3626b9..f8d751fa278d 100644
> > --- a/hw/nvram/eeprom_at24c.c
> > +++ b/hw/nvram/eeprom_at24c.c
> > @@ -50,6 +50,9 @@ struct EEPROMState {
> >  uint8_t *mem;
> >
> >  BlockBackend *blk;
> > +
> > +const uint8_t *init_rom;
> > +uint32_t init_rom_size;
> >  };
> >
> >  static
> > @@ -131,19 +134,38 @@ int at24c_eeprom_send(I2CSlave *s, uint8_t data)
> >
> >  I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t 
> > rom_size)
> >  {
> > -I2CSlave *i2c_dev = i2c_slave_new(TYPE_AT24C_EE, address);
> > -DeviceState *dev = DEVICE(i2c_dev);
> > +return at24c_eeprom_init_rom(bus, address, rom_size, NULL, 0);
> > +}
> > +
> > +I2CSlave *at24c_eeprom_init_rom(I2CBus *bus, uint8_t address, uint32_t 
> > rom_size,
> > +const uint8_t *init_rom, uint32_t 
> > init_rom_size)
> > +{
> > +EEPROMState *s;
> > +
> > +s = AT24C_EE(qdev_new(TYPE_AT24C_EE));
> > +
> > +qdev_prop_set_uint8(DEVICE(s), "address", address);
> > +qdev_prop_set_uint32(DEVICE(s), "rom-size", rom_size);
> >
> > -qdev_prop_set_uint32(dev, "rom-size", rom_size);
> > -i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
> > +/* TODO: Model init_rom with QOM properties. */
> > +s->init_rom = init_rom;
> > +s->init_rom_size = init_rom_size;
> >
> > -return i2c_dev;
> > +i2c_slave_realize_and_unref(I2C_SLAVE(s), bus, _abort);
> > +
> > +return I2C_SLAVE(s);
> >  }
> >
> >  static void at24c_eeprom_realize(DeviceState *dev, Error **errp)
> >  {
> >  EEPROMState *ee = AT24C_EE(dev);
> >
> > +if (ee->init_rom_size > ee->rsize) {
> > +error_setg(errp, "%s: init rom is larger than rom: %u > %u",
> > +   TYPE_AT24C_EE, ee->init_rom_size, ee->rsize);
> > +return;
> > +}
> > +
> >  if (ee->blk) {
> >  int64_t len = blk_getlength(ee->blk);
> >
> > @@ -163,6 +185,7 @@ static void at24c_eeprom_realize(DeviceState *dev, 
> > Error **errp)
> >  }
> >
> >  ee->mem = g_malloc0(ee->rsize);
> > +
> >  }
> >
> >  static
> > @@ -176,6 +199,10 @@ void at24c_eeprom_reset(DeviceState *state)
> >
> >  memset(ee->mem, 0, ee->rsize);
> >
> > +if (ee->init_rom) {
> > +memcpy(ee->mem, ee->init_rom, MIN(ee->init_rom_size, ee->rsize));
> 
> I like the MIN here; good usability feature. It's worth documenting too.
> 
> > +}
> > +
> >  if (ee->blk) {
> >  int ret = blk_pread(ee->blk, 0, ee->rsize, ee->mem, 0);
> >
> > diff --git a/include/hw/nvram/eeprom_at24c.h 
> > b/include/hw/nvram/eeprom_at24c.h
> > index 196db309d451..5c9149331144 100644
> > --- a/include/hw/nvram/eeprom_at24c.h
> > +++ b/include/hw/nvram/eeprom_at24c.h
> > @@ -19,5 +19,7 @@
> >   * @bus, and drop the reference to it (the device is realized).
> >   */
> >  I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t 
> > rom_size);
> > +I2CSlave *at24c_eeprom_init_rom(I2CBus *bus, uint8_t address, uint32_t 
> > rom_size,
> > +const uint8_t *init_rom, uint32_t 
> > init_rom_size);
> >
> >  #endif
> > --
> > 2.39.0
> >



Re: [PATCH v3 5/5] hw/nvram/eeprom_at24c: Make reset behavior more like hardware

2023-01-17 Thread Joel Stanley
On Tue, 17 Jan 2023 at 23:24, Peter Delevoryas  wrote:
>
> EEPROM's are a form of non-volatile memory. After power-cycling an EEPROM,
> I would expect the I2C state machine to be reset to default values, but I
> wouldn't really expect the memory to change at all.
>
> The current implementation of the at24c EEPROM resets its internal memory on
> reset. This matches the specification in docs/devel/reset.rst:
>
>   Cold reset is supported by every resettable object. In QEMU, it means we 
> reset
>   to the initial state corresponding to the start of QEMU; this might differ
>   from what is a real hardware cold reset. It differs from other resets (like
>   warm or bus resets) which may keep certain parts untouched.
>
> But differs from my intuition. For example, if someone writes some information
> to an EEPROM, then AC power cycles their board, they would expect the EEPROM 
> to
> retain that information. It's very useful to be able to test things like this
> in QEMU as well, to verify software instrumentation like determining the cause
> of a reboot.
>
> Fixes: 5d8424dbd3e8 ("nvram: add AT24Cx i2c eeprom")
> Signed-off-by: Peter Delevoryas 

Reviewed-by: Joel Stanley 

> ---
>  hw/nvram/eeprom_at24c.c | 22 ++
>  1 file changed, 10 insertions(+), 12 deletions(-)
>
> diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
> index f8d751fa278d..5074776bff04 100644
> --- a/hw/nvram/eeprom_at24c.c
> +++ b/hw/nvram/eeprom_at24c.c
> @@ -185,18 +185,6 @@ static void at24c_eeprom_realize(DeviceState *dev, Error 
> **errp)
>  }
>
>  ee->mem = g_malloc0(ee->rsize);
> -
> -}
> -
> -static
> -void at24c_eeprom_reset(DeviceState *state)
> -{
> -EEPROMState *ee = AT24C_EE(state);
> -
> -ee->changed = false;
> -ee->cur = 0;
> -ee->haveaddr = 0;
> -
>  memset(ee->mem, 0, ee->rsize);
>
>  if (ee->init_rom) {
> @@ -214,6 +202,16 @@ void at24c_eeprom_reset(DeviceState *state)
>  }
>  }
>
> +static
> +void at24c_eeprom_reset(DeviceState *state)
> +{
> +EEPROMState *ee = AT24C_EE(state);
> +
> +ee->changed = false;
> +ee->cur = 0;
> +ee->haveaddr = 0;
> +}
> +
>  static Property at24c_eeprom_props[] = {
>  DEFINE_PROP_UINT32("rom-size", EEPROMState, rsize, 0),
>  DEFINE_PROP_BOOL("writable", EEPROMState, writable, true),
> --
> 2.39.0
>



Re: [PATCH v3 4/5] hw/arm/aspeed: Add aspeed_eeprom.c

2023-01-17 Thread Joel Stanley
On Tue, 17 Jan 2023 at 23:24, Peter Delevoryas  wrote:
>
> - Create aspeed_eeprom.c and aspeed_eeprom.h
> - Include aspeed_eeprom.c in CONFIG_ASPEED meson source files
> - Include aspeed_eeprom.h in aspeed.c
> - Add fby35_bmc_fruid data
> - Use new at24c_eeprom_init_rom helper to initialize BMC FRUID EEPROM with 
> data
>   from aspeed_eeprom.c
>
> wget 
> https://github.com/facebook/openbmc/releases/download/openbmc-e2294ff5d31d/fby35.mtd
> qemu-system-aarch64 -machine fby35-bmc -nographic -mtdblock fby35.mtd
> ...
> user: root
> pass: 0penBmc
> ...
> root@bmc-oob:~# fruid-util bb
>
> FRU Information   : Baseboard
> ---   : --
> Chassis Type  : Rack Mount Chassis
> Chassis Part Number   : N/A
> Chassis Serial Number : N/A
> Board Mfg Date: Fri Jan  7 10:30:00 2022
> Board Mfg : XX
> Board Product : Management Board wBMC
> Board Serial  : X
> Board Part Number : XX
> Board FRU ID  : 1.0
> Board Custom Data 1   : X
> Board Custom Data 2   : XX
> Product Manufacturer  : XX
> Product Name  : Yosemite V3.5 EVT2
> Product Part Number   : XX
> Product Version   : EVT2
> Product Serial: X
> Product Asset Tag : XXX
> Product FRU ID: 1.0
> Product Custom Data 1 : X
> Product Custom Data 2 : N/A
> root@bmc-oob:~# fruid-util bmc
>
> FRU Information   : BMC
> ---   : --
> Board Mfg Date: Mon Jan 10 21:42:00 2022
> Board Mfg : XX
> Board Product : BMC Storage Module
> Board Serial  : X
> Board Part Number : XX
> Board FRU ID  : 1.0
> Board Custom Data 1   : X
> Board Custom Data 2   : XX
> Product Manufacturer  : XX
> Product Name  : Yosemite V3.5 EVT2
> Product Part Number   : XX
> Product Version   : EVT2
> Product Serial: X
> Product Asset Tag : XXX
> Product FRU ID: 1.0
> Product Custom Data 1 : X
> Product Custom Data 2 : Config A
> root@bmc-oob:~# fruid-util nic
>
> FRU Information   : NIC
> ---   : --
> Board Mfg Date: Tue Nov  2 08:51:00 2021
> Board Mfg : 
> Board Product : Mellanox ConnectX-6 DX OCP3.0
> Board Serial  : 
> Board Part Number : X
> Board FRU ID  : FRU Ver 0.02
> Product Manufacturer  : 
> Product Name  : Mellanox ConnectX-6 DX OCP3.0
> Product Part Number   : X
> Product Version   : A9
> Product Serial: 
> Product Custom Data 3 : ConnectX-6 DX
>
> Signed-off-by: Peter Delevoryas 
> Reviewed-by: Cédric Le Goater 

Reviewed-by: Joel Stanley 

> ---
>  hw/arm/aspeed.c | 10 +++--
>  hw/arm/aspeed_eeprom.c  | 78 +
>  hw/arm/aspeed_eeprom.h  | 16 +++
>  hw/arm/meson.build  |  1 +
>  include/hw/nvram/eeprom_at24c.h | 14 ++
>  5 files changed, 116 insertions(+), 3 deletions(-)
>  create mode 100644 hw/arm/aspeed_eeprom.c
>  create mode 100644 hw/arm/aspeed_eeprom.h
>
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> index c929c61d582a..382965f82c38 100644
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -14,6 +14,7 @@
>  #include "hw/arm/boot.h"
>  #include "hw/arm/aspeed.h"
>  #include "hw/arm/aspeed_soc.h"
> +#include "hw/arm/aspeed_eeprom.h"
>  #include "hw/i2c/i2c_mux_pca954x.h"
>  #include "hw/i2c/smbus_eeprom.h"
>  #include "hw/misc/pca9552.h"
> @@ -940,9 +941,12 @@ static void fby35_i2c_init(AspeedMachineState *bmc)
>
>  at24c_eeprom_init(i2c[4], 0x51, 128 * KiB);
>  at24c_eeprom_init(i2c[6], 0x51, 128 * KiB);
> -at24c_eeprom_init(i2c[8], 0x50, 32 * KiB);
> -at24c_eeprom_init(i2c[11], 0x51, 128 * KiB);
> -at24c_eeprom_init(i2c[11], 0x54, 128 * KiB);
> +at24c_eeprom_init_rom(i2c[8], 0x50, 32 * KiB, fby35_nic_fruid,
> +  sizeof(fby35_nic_fruid));
> +at24c_eeprom_init_rom(i2c[11], 0x51, 128 * KiB, fby35_bb_fruid,
> +  sizeof(fby35_bb_fruid));
> +at24c_eeprom_init_rom(i2c[11], 0x54, 128 * KiB, fby35_bmc_fruid,
> +  sizeof(fby35_bmc_fruid));
>
>  /*
>   * TODO: There is a multi-master i2c connection to an AST1030 MiniBMC on
> diff --git a/hw/arm/aspeed_eeprom.c b/hw/arm/aspeed_eeprom.c
> new file mode 100644
> index ..9d0700d4b709
> --- /dev/null
> +++ b/hw/arm/aspeed_eeprom.c
> @@ -0,0 +1,78 @@
> +/*
> + * Copyright (c) Meta Platforms, Inc. and 

Re: [PATCH v3 3/5] hw/nvram/eeprom_at24c: Add init_rom field and at24c_eeprom_init_rom helper

2023-01-17 Thread Joel Stanley
On Tue, 17 Jan 2023 at 23:24, Peter Delevoryas  wrote:
>
> Allows users to specify binary data to initialize an EEPROM, allowing users to
> emulate data programmed at manufacturing time.

I like it. Is there somewhere sensible to add a description to the
code base? Perhaps as a comment to your new function?

>
> - Added init_rom and init_rom_size attributes to TYPE_AT24C_EE
> - Added at24c_eeprom_init_rom helper function to initialize attributes
> - If -drive property is provided, it overrides init_rom data
>
> Signed-off-by: Peter Delevoryas 

Reviewed-by: Joel Stanley 

> ---
>  hw/nvram/eeprom_at24c.c | 37 -
>  include/hw/nvram/eeprom_at24c.h |  2 ++
>  2 files changed, 34 insertions(+), 5 deletions(-)
>
> diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
> index 98857e3626b9..f8d751fa278d 100644
> --- a/hw/nvram/eeprom_at24c.c
> +++ b/hw/nvram/eeprom_at24c.c
> @@ -50,6 +50,9 @@ struct EEPROMState {
>  uint8_t *mem;
>
>  BlockBackend *blk;
> +
> +const uint8_t *init_rom;
> +uint32_t init_rom_size;
>  };
>
>  static
> @@ -131,19 +134,38 @@ int at24c_eeprom_send(I2CSlave *s, uint8_t data)
>
>  I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t rom_size)
>  {
> -I2CSlave *i2c_dev = i2c_slave_new(TYPE_AT24C_EE, address);
> -DeviceState *dev = DEVICE(i2c_dev);
> +return at24c_eeprom_init_rom(bus, address, rom_size, NULL, 0);
> +}
> +
> +I2CSlave *at24c_eeprom_init_rom(I2CBus *bus, uint8_t address, uint32_t 
> rom_size,
> +const uint8_t *init_rom, uint32_t 
> init_rom_size)
> +{
> +EEPROMState *s;
> +
> +s = AT24C_EE(qdev_new(TYPE_AT24C_EE));
> +
> +qdev_prop_set_uint8(DEVICE(s), "address", address);
> +qdev_prop_set_uint32(DEVICE(s), "rom-size", rom_size);
>
> -qdev_prop_set_uint32(dev, "rom-size", rom_size);
> -i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
> +/* TODO: Model init_rom with QOM properties. */
> +s->init_rom = init_rom;
> +s->init_rom_size = init_rom_size;
>
> -return i2c_dev;
> +i2c_slave_realize_and_unref(I2C_SLAVE(s), bus, _abort);
> +
> +return I2C_SLAVE(s);
>  }
>
>  static void at24c_eeprom_realize(DeviceState *dev, Error **errp)
>  {
>  EEPROMState *ee = AT24C_EE(dev);
>
> +if (ee->init_rom_size > ee->rsize) {
> +error_setg(errp, "%s: init rom is larger than rom: %u > %u",
> +   TYPE_AT24C_EE, ee->init_rom_size, ee->rsize);
> +return;
> +}
> +
>  if (ee->blk) {
>  int64_t len = blk_getlength(ee->blk);
>
> @@ -163,6 +185,7 @@ static void at24c_eeprom_realize(DeviceState *dev, Error 
> **errp)
>  }
>
>  ee->mem = g_malloc0(ee->rsize);
> +
>  }
>
>  static
> @@ -176,6 +199,10 @@ void at24c_eeprom_reset(DeviceState *state)
>
>  memset(ee->mem, 0, ee->rsize);
>
> +if (ee->init_rom) {
> +memcpy(ee->mem, ee->init_rom, MIN(ee->init_rom_size, ee->rsize));

I like the MIN here; good usability feature. It's worth documenting too.

> +}
> +
>  if (ee->blk) {
>  int ret = blk_pread(ee->blk, 0, ee->rsize, ee->mem, 0);
>
> diff --git a/include/hw/nvram/eeprom_at24c.h b/include/hw/nvram/eeprom_at24c.h
> index 196db309d451..5c9149331144 100644
> --- a/include/hw/nvram/eeprom_at24c.h
> +++ b/include/hw/nvram/eeprom_at24c.h
> @@ -19,5 +19,7 @@
>   * @bus, and drop the reference to it (the device is realized).
>   */
>  I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t rom_size);
> +I2CSlave *at24c_eeprom_init_rom(I2CBus *bus, uint8_t address, uint32_t 
> rom_size,
> +const uint8_t *init_rom, uint32_t 
> init_rom_size);
>
>  #endif
> --
> 2.39.0
>



Re: [PATCH v3 0/6] qemu/bswap: Use compiler __builtin_bswap()

2023-01-17 Thread Richard Henderson

On 1/16/23 22:24, Philippe Mathieu-Daudé wrote:

On 13/1/23 08:05, Philippe Mathieu-Daudé wrote:

On 13/1/23 02:05, Richard Henderson wrote:

On 1/11/23 08:31, Philippe Mathieu-Daudé wrote:

Implement Richard's suggestion to use __builtin_bswap().

Convert to __builtin_bswap() one patch per OS to simplify
maintainers review.

Since v2:
- Rebased adapting ./configure changes to meson

Since v1:
- Remove the Haiku/BSD ifdef'ry (Peter)
- Include the Haiku VM image from Alexander

Philippe Mathieu-Daudé (6):
   qemu/bswap: Replace bswapXX() by compiler __builtin_bswap()
   qemu/bswap: Replace bswapXXs() by compiler __builtin_bswap()
   qemu/bswap: Remove  dependency
   qemu/bswap: Use compiler __builtin_bswap() on Haiku
   qemu/bswap: Use compiler __builtin_bswap() on FreeBSD
   qemu/bswap: Use compiler __builtin_bswap() on NetBSD


If this passes on all the odd OS's, great.
Failure on some oddball is what blocked my patch set years ago.


OK I'll double-check.


Tested successfully on:

- QEMU GitLab CI
- Darwin 22.2
- FreeBSD 12.4
- NetBSD 9.3
- OpenBSD 7.2
- Haiku r1beta4


Great.  Just in case I missed an individual patch, series:
Reviewed-by: Richard Henderson 


r~



Re: [PATCH v3 1/5] hw/arm: Extract at24c_eeprom_init helper from Aspeed and Nuvoton boards

2023-01-17 Thread Joel Stanley
On Tue, 17 Jan 2023 at 23:24, Peter Delevoryas  wrote:
>
> This helper is useful in board initialization because lets users initialize 
> and
> realize an EEPROM on an I2C bus with a single function call.
>
> Signed-off-by: Peter Delevoryas 
> Reviewed-by: Cédric Le Goater 

Reviewed-by: Joel Stanley 

> ---
>  hw/arm/aspeed.c | 10 +-
>  hw/arm/npcm7xx_boards.c | 20 +---
>  hw/nvram/eeprom_at24c.c | 12 
>  include/hw/nvram/eeprom_at24c.h | 23 +++
>  4 files changed, 41 insertions(+), 24 deletions(-)
>  create mode 100644 include/hw/nvram/eeprom_at24c.h
>
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> index 55f114ef729f..1f9799d4321e 100644
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -17,6 +17,7 @@
>  #include "hw/i2c/i2c_mux_pca954x.h"
>  #include "hw/i2c/smbus_eeprom.h"
>  #include "hw/misc/pca9552.h"
> +#include "hw/nvram/eeprom_at24c.h"
>  #include "hw/sensor/tmp105.h"
>  #include "hw/misc/led.h"
>  #include "hw/qdev-properties.h"
> @@ -429,15 +430,6 @@ static void aspeed_machine_init(MachineState *machine)
>  arm_load_kernel(ARM_CPU(first_cpu), machine, _board_binfo);
>  }
>
> -static void at24c_eeprom_init(I2CBus *bus, uint8_t addr, uint32_t rsize)
> -{
> -I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
> -DeviceState *dev = DEVICE(i2c_dev);
> -
> -qdev_prop_set_uint32(dev, "rom-size", rsize);
> -i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
> -}
> -
>  static void palmetto_bmc_i2c_init(AspeedMachineState *bmc)
>  {
>  AspeedSoCState *soc = >soc;
> diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
> index 6bc6f5d2fe29..9b31207a06e9 100644
> --- a/hw/arm/npcm7xx_boards.c
> +++ b/hw/arm/npcm7xx_boards.c
> @@ -21,6 +21,7 @@
>  #include "hw/i2c/i2c_mux_pca954x.h"
>  #include "hw/i2c/smbus_eeprom.h"
>  #include "hw/loader.h"
> +#include "hw/nvram/eeprom_at24c.h"
>  #include "hw/qdev-core.h"
>  #include "hw/qdev-properties.h"
>  #include "qapi/error.h"
> @@ -140,17 +141,6 @@ static I2CBus *npcm7xx_i2c_get_bus(NPCM7xxState *soc, 
> uint32_t num)
>  return I2C_BUS(qdev_get_child_bus(DEVICE(>smbus[num]), "i2c-bus"));
>  }
>
> -static void at24c_eeprom_init(NPCM7xxState *soc, int bus, uint8_t addr,
> -  uint32_t rsize)
> -{
> -I2CBus *i2c_bus = npcm7xx_i2c_get_bus(soc, bus);
> -I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
> -DeviceState *dev = DEVICE(i2c_dev);
> -
> -qdev_prop_set_uint32(dev, "rom-size", rsize);
> -i2c_slave_realize_and_unref(i2c_dev, i2c_bus, _abort);
> -}
> -
>  static void npcm7xx_init_pwm_splitter(NPCM7xxMachine *machine,
>NPCM7xxState *soc, const int 
> *fan_counts)
>  {
> @@ -253,8 +243,8 @@ static void quanta_gsj_i2c_init(NPCM7xxState *soc)
>  i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 3), "tmp105", 0x5c);
>  i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 4), "tmp105", 0x5c);
>
> -at24c_eeprom_init(soc, 9, 0x55, 8192);
> -at24c_eeprom_init(soc, 10, 0x55, 8192);
> +at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 9), 0x55, 8192);
> +at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 10), 0x55, 8192);
>
>  /*
>   * i2c-11:
> @@ -360,7 +350,7 @@ static void kudo_bmc_i2c_init(NPCM7xxState *soc)
>
>  i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 4), TYPE_PCA9548, 0x77);
>
> -at24c_eeprom_init(soc, 4, 0x50, 8192); /* mbfru */
> +at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 4), 0x50, 8192); /* mbfru */
>
>  i2c_mux = i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 13),
>TYPE_PCA9548, 0x77);
> @@ -371,7 +361,7 @@ static void kudo_bmc_i2c_init(NPCM7xxState *soc)
>  i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 4), "tmp105", 0x48);
>  i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 5), "tmp105", 0x49);
>
> -at24c_eeprom_init(soc, 14, 0x55, 8192); /* bmcfru */
> +at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 14), 0x55, 8192); /* bmcfru */
>
>  /* TODO: Add remaining i2c devices. */
>  }
> diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
> index 2d4d8b952f38..98857e3626b9 100644
> --- a/hw/nvram/eeprom_at24c.c
> +++ b/hw/nvram/eeprom_at24c.c
> @@ -12,6 +12,7 @@
>  #include "qapi/error.h"
>  #include "qemu/module.h"
>  #include "hw/i2c/i2c.h"
> +#include "hw/nvram/eeprom_at24c.h"
>  #include "hw/qdev-properties.h"
>  #include "hw/qdev-properties-system.h"
>  #include "sysemu/block-backend.h"
> @@ -128,6 +129,17 @@ int at24c_eeprom_send(I2CSlave *s, uint8_t data)
>  return 0;
>  }
>
> +I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t rom_size)
> +{
> +I2CSlave *i2c_dev = i2c_slave_new(TYPE_AT24C_EE, address);
> +DeviceState *dev = DEVICE(i2c_dev);
> +
> +qdev_prop_set_uint32(dev, "rom-size", rom_size);
> +i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
> +
> +return i2c_dev;
> +}

Re: [PATCH v3 2/5] hw/arm/aspeed: Replace aspeed_eeprom_init with at24c_eeprom_init

2023-01-17 Thread Joel Stanley
On Tue, 17 Jan 2023 at 23:24, Peter Delevoryas  wrote:
>
> aspeed_eeprom_init is an exact copy of at24c_eeprom_init, not needed.
>
> Signed-off-by: Peter Delevoryas 
> Reviewed-by: Cédric Le Goater 
> Reviewed-by: Philippe Mathieu-Daudé 

Reviewed-by: Joel Stanley 

> ---
>  hw/arm/aspeed.c | 95 ++---
>  1 file changed, 43 insertions(+), 52 deletions(-)
>
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> index 1f9799d4321e..c929c61d582a 100644
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -660,15 +660,6 @@ static void g220a_bmc_i2c_init(AspeedMachineState *bmc)
>eeprom_buf);
>  }
>
> -static void aspeed_eeprom_init(I2CBus *bus, uint8_t addr, uint32_t rsize)
> -{
> -I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
> -DeviceState *dev = DEVICE(i2c_dev);
> -
> -qdev_prop_set_uint32(dev, "rom-size", rsize);
> -i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
> -}
> -
>  static void fp5280g2_bmc_i2c_init(AspeedMachineState *bmc)
>  {
>  AspeedSoCState *soc = >soc;
> @@ -701,7 +692,7 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
>  AspeedSoCState *soc = >soc;
>  I2CSlave *i2c_mux;
>
> -aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 0), 0x51, 32 * KiB);
> +at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 0), 0x51, 32 * KiB);
>
>  create_pca9552(soc, 3, 0x61);
>
> @@ -714,9 +705,9 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
>   0x4a);
>  i2c_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 4),
>"pca9546", 0x70);
> -aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
> -aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
> -aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x52, 64 * KiB);
> +at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
> +at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
> +at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x52, 64 * KiB);
>  create_pca9552(soc, 4, 0x60);
>
>  i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 5), TYPE_TMP105,
> @@ -727,8 +718,8 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
>  create_pca9552(soc, 5, 0x61);
>  i2c_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 5),
>"pca9546", 0x70);
> -aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
> -aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
> +at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
> +at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
>
>  i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 6), TYPE_TMP105,
>   0x48);
> @@ -738,10 +729,10 @@ static void rainier_bmc_i2c_init(AspeedMachineState 
> *bmc)
>   0x4b);
>  i2c_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 6),
>"pca9546", 0x70);
> -aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
> -aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
> -aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x50, 64 * KiB);
> -aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 3), 0x51, 64 * KiB);
> +at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
> +at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
> +at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x50, 64 * KiB);
> +at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 3), 0x51, 64 * KiB);
>
>  create_pca9552(soc, 7, 0x30);
>  create_pca9552(soc, 7, 0x31);
> @@ -754,15 +745,15 @@ static void rainier_bmc_i2c_init(AspeedMachineState 
> *bmc)
>  i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 7), TYPE_TMP105,
>   0x48);
>  i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 7), "max31785", 
> 0x52);
> -aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 7), 0x50, 64 * KiB);
> -aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 7), 0x51, 64 * KiB);
> +at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 7), 0x50, 64 * KiB);
> +at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 7), 0x51, 64 * KiB);
>
>  i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 8), TYPE_TMP105,
>   0x48);
>  i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 8), TYPE_TMP105,
>   0x4a);
> -aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 8), 0x50, 64 * KiB);
> -aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 8), 0x51, 64 * KiB);
> +at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 8), 0x50, 64 * KiB);
> +at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 8), 0x51, 64 * KiB);
>  create_pca9552(soc, 8, 0x60);
>  create_pca9552(soc, 8, 0x61);
>  /* Bus 8: ucd90320@11 */
> @@ -771,11 +762,11 @@ static void 

[PATCH v2 06/10] tcg/loongarch64: Introduce tcg_out_addi

2023-01-17 Thread Richard Henderson
Adjust the constraints to allow any int32_t for immediate
addition.  Split immediate adds into addu16i + addi, which
covers quite a lot of the immediate space.  For the hole in
the middle, load the constant into TMP0 instead.

Signed-off-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target-con-set.h |  4 +-
 tcg/loongarch64/tcg-target-con-str.h |  2 +-
 tcg/loongarch64/tcg-target.c.inc | 57 
 3 files changed, 53 insertions(+), 10 deletions(-)

diff --git a/tcg/loongarch64/tcg-target-con-set.h 
b/tcg/loongarch64/tcg-target-con-set.h
index 349c672687..7b5a7a3f5d 100644
--- a/tcg/loongarch64/tcg-target-con-set.h
+++ b/tcg/loongarch64/tcg-target-con-set.h
@@ -23,9 +23,11 @@ C_O1_I1(r, L)
 C_O1_I2(r, r, rC)
 C_O1_I2(r, r, ri)
 C_O1_I2(r, r, rI)
+C_O1_I2(r, r, rJ)
 C_O1_I2(r, r, rU)
 C_O1_I2(r, r, rW)
 C_O1_I2(r, r, rZ)
 C_O1_I2(r, 0, rZ)
-C_O1_I2(r, rZ, rN)
+C_O1_I2(r, rZ, ri)
+C_O1_I2(r, rZ, rJ)
 C_O1_I2(r, rZ, rZ)
diff --git a/tcg/loongarch64/tcg-target-con-str.h 
b/tcg/loongarch64/tcg-target-con-str.h
index c3986a4fd4..541ff47fa9 100644
--- a/tcg/loongarch64/tcg-target-con-str.h
+++ b/tcg/loongarch64/tcg-target-con-str.h
@@ -21,7 +21,7 @@ REGS('L', ALL_GENERAL_REGS & ~SOFTMMU_RESERVE_REGS)
  * CONST(letter, TCG_CT_CONST_* bit set)
  */
 CONST('I', TCG_CT_CONST_S12)
-CONST('N', TCG_CT_CONST_N12)
+CONST('J', TCG_CT_CONST_S32)
 CONST('U', TCG_CT_CONST_U12)
 CONST('Z', TCG_CT_CONST_ZERO)
 CONST('C', TCG_CT_CONST_C12)
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 428f3abd71..8cc6c5eec2 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -126,7 +126,7 @@ static const int tcg_target_call_oarg_regs[] = {
 
 #define TCG_CT_CONST_ZERO  0x100
 #define TCG_CT_CONST_S12   0x200
-#define TCG_CT_CONST_N12   0x400
+#define TCG_CT_CONST_S32   0x400
 #define TCG_CT_CONST_U12   0x800
 #define TCG_CT_CONST_C12   0x1000
 #define TCG_CT_CONST_WSZ   0x2000
@@ -161,7 +161,7 @@ static bool tcg_target_const_match(int64_t val, TCGType 
type, int ct)
 if ((ct & TCG_CT_CONST_S12) && val == sextreg(val, 0, 12)) {
 return true;
 }
-if ((ct & TCG_CT_CONST_N12) && -val == sextreg(-val, 0, 12)) {
+if ((ct & TCG_CT_CONST_S32) && val == (int32_t)val) {
 return true;
 }
 if ((ct & TCG_CT_CONST_U12) && val >= 0 && val <= 0xfff) {
@@ -378,6 +378,45 @@ static void tcg_out_movi(TCGContext *s, TCGType type, 
TCGReg rd,
 }
 }
 
+static void tcg_out_addi(TCGContext *s, TCGType type, TCGReg rd,
+ TCGReg rs, tcg_target_long imm)
+{
+tcg_target_long lo12 = sextreg(imm, 0, 12);
+tcg_target_long hi16 = sextreg(imm - lo12, 16, 16);
+
+/*
+ * Note that there's a hole in between hi16 and lo12:
+ *
+ *   3   2   1   0
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * ...+---+---+---+
+ *| hi16  |   |  lo12 |
+ * ...+---+---+---+
+ *
+ * For bits within that hole, it's more efficient to use LU12I and ADD.
+ */
+if (imm == (hi16 << 16) + lo12) {
+if (hi16) {
+tcg_out_opc_addu16i_d(s, rd, rs, hi16);
+rs = rd;
+}
+if (type == TCG_TYPE_I32) {
+tcg_out_opc_addi_w(s, rd, rs, lo12);
+} else if (lo12) {
+tcg_out_opc_addi_d(s, rd, rs, lo12);
+} else {
+tcg_out_mov(s, type, rd, rs);
+}
+} else {
+tcg_out_movi(s, type, TCG_REG_TMP0, imm);
+if (type == TCG_TYPE_I32) {
+tcg_out_opc_add_w(s, rd, rs, TCG_REG_TMP0);
+} else {
+tcg_out_opc_add_d(s, rd, rs, TCG_REG_TMP0);
+}
+}
+}
+
 static void tcg_out_ext8u(TCGContext *s, TCGReg ret, TCGReg arg)
 {
 tcg_out_opc_andi(s, ret, arg, 0xff);
@@ -1350,14 +1389,14 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 
 case INDEX_op_add_i32:
 if (c2) {
-tcg_out_opc_addi_w(s, a0, a1, a2);
+tcg_out_addi(s, TCG_TYPE_I32, a0, a1, a2);
 } else {
 tcg_out_opc_add_w(s, a0, a1, a2);
 }
 break;
 case INDEX_op_add_i64:
 if (c2) {
-tcg_out_opc_addi_d(s, a0, a1, a2);
+tcg_out_addi(s, TCG_TYPE_I64, a0, a1, a2);
 } else {
 tcg_out_opc_add_d(s, a0, a1, a2);
 }
@@ -1365,14 +1404,14 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 
 case INDEX_op_sub_i32:
 if (c2) {
-tcg_out_opc_addi_w(s, a0, a1, -a2);
+tcg_out_addi(s, TCG_TYPE_I32, a0, a1, -a2);
 } else {
 tcg_out_opc_sub_w(s, a0, a1, a2);
 }
 break;
 case INDEX_op_sub_i64:
 if (c2) {
-tcg_out_opc_addi_d(s, a0, a1, -a2);
+   

[PATCH v2 02/10] target/loongarch: Disassemble jirl properly

2023-01-17 Thread Richard Henderson
While jirl shares the same instruction format as bne etc,
it is not assembled the same.  In particular, rd is printed
first not second and the immediate is not pc-relative.

Decode into the arg_rr_i structure, which prints correctly.
This changes the "offs" member to "imm", to update translate.

Signed-off-by: Richard Henderson 
---
 target/loongarch/disas.c   | 2 +-
 target/loongarch/insn_trans/trans_branch.c.inc | 2 +-
 target/loongarch/insns.decode  | 3 ++-
 3 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index 858dfcc53a..7cffd853ec 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -628,7 +628,7 @@ INSN(beqz, r_offs)
 INSN(bnez, r_offs)
 INSN(bceqz,c_offs)
 INSN(bcnez,c_offs)
-INSN(jirl, rr_offs)
+INSN(jirl, rr_i)
 INSN(b,offs)
 INSN(bl,   offs)
 INSN(beq,  rr_offs)
diff --git a/target/loongarch/insn_trans/trans_branch.c.inc 
b/target/loongarch/insn_trans/trans_branch.c.inc
index 65dbdff41e..a860f7e733 100644
--- a/target/loongarch/insn_trans/trans_branch.c.inc
+++ b/target/loongarch/insn_trans/trans_branch.c.inc
@@ -23,7 +23,7 @@ static bool trans_jirl(DisasContext *ctx, arg_jirl *a)
 TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
 TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
 
-tcg_gen_addi_tl(cpu_pc, src1, a->offs);
+tcg_gen_addi_tl(cpu_pc, src1, a->imm);
 tcg_gen_movi_tl(dest, ctx->base.pc_next + 4);
 gen_set_gpr(a->rd, dest, EXT_NONE);
 tcg_gen_lookup_and_goto_ptr();
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index 3fdc6e148c..de7b8f0f3c 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -67,6 +67,7 @@
 @rr_ui12  .. imm:12 rj:5 rd:5_i
 @rr_i14s2    .. rj:5 rd:5_i imm=%i14s2
 @rr_i16  .. imm:s16 rj:5 rd:5_i
+@rr_i16s2  ..   rj:5 rd:5_i imm=%offs16
 @hint_r_i12    .. imm:s12 rj:5 hint:5_r_i
 @rrr_sa2p1  ... .. rk:5 rj:5 rd:5_sa  sa=%sa2p1
 @rrr_sa2  ... sa:2 rk:5 rj:5 rd:5_sa
@@ -444,7 +445,7 @@ beqz0100 00  . . 
@r_offs21
 bnez0100 01  . . @r_offs21
 bceqz   0100 10  00 ... .@c_offs21
 bcnez   0100 10  01 ... .@c_offs21
-jirl0100 11  . . @rr_offs16
+jirl0100 11  . . @rr_i16s2
 b   0101 00 ..   @offs26
 bl  0101 01 ..   @offs26
 beq 0101 10  . . @rr_offs16
-- 
2.34.1




[PATCH v2 03/10] target/loongarch: Disassemble pcadd* addresses

2023-01-17 Thread Richard Henderson
Print both the raw field and the resolved pc-relative
address, as we do for branches.

Signed-off-by: Richard Henderson 
---
 target/loongarch/disas.c | 37 +
 1 file changed, 33 insertions(+), 4 deletions(-)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index 7cffd853ec..2e93e77e0d 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -519,10 +519,6 @@ INSN(fsel, fffc)
 INSN(addu16i_d,rr_i)
 INSN(lu12i_w,  r_i)
 INSN(lu32i_d,  r_i)
-INSN(pcaddi,   r_i)
-INSN(pcalau12i,r_i)
-INSN(pcaddu12i,r_i)
-INSN(pcaddu18i,r_i)
 INSN(ll_w, rr_i)
 INSN(sc_w, rr_i)
 INSN(ll_d, rr_i)
@@ -755,3 +751,36 @@ static bool trans_fcmp_cond_##suffix(DisasContext *ctx, \
 
 FCMP_INSN(s)
 FCMP_INSN(d)
+
+#define PCADD_INSN(name)\
+static bool trans_##name(DisasContext *ctx, arg_##name *a)  \
+{   \
+output(ctx, #name, "r%d, %d # 0x%" PRIx64,  \
+   a->rd, a->imm, gen_##name(ctx->pc, a->imm)); \
+return true;\
+}
+
+static uint64_t gen_pcaddi(uint64_t pc, int imm)
+{
+return pc + (imm << 2);
+}
+
+static uint64_t gen_pcalau12i(uint64_t pc, int imm)
+{
+return (pc + (imm << 12)) & ~0xfff;
+}
+
+static uint64_t gen_pcaddu12i(uint64_t pc, int imm)
+{
+return pc + (imm << 12);
+}
+
+static uint64_t gen_pcaddu18i(uint64_t pc, int imm)
+{
+return pc + ((uint64_t)(imm) << 18);
+}
+
+PCADD_INSN(pcaddi)
+PCADD_INSN(pcalau12i)
+PCADD_INSN(pcaddu12i)
+PCADD_INSN(pcaddu18i)
-- 
2.34.1




[PATCH v2 07/10] tcg/loongarch64: Improve setcond expansion

2023-01-17 Thread Richard Henderson
Split out a helper function, tcg_out_setcond_int, which
does not always produce the complete boolean result, but
returns a set of flags to do so.

Accept all int32_t as constant input, so that LE/GT can
adjust the constant to LT.

Signed-off-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target.c.inc | 165 +--
 1 file changed, 115 insertions(+), 50 deletions(-)

diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 8cc6c5eec2..ccc1c0f392 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -469,64 +469,131 @@ static void tcg_out_clzctz(TCGContext *s, LoongArchInsn 
opc,
 tcg_out_opc_or(s, a0, TCG_REG_TMP0, a0);
 }
 
-static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
-TCGReg arg1, TCGReg arg2, bool c2)
-{
-TCGReg tmp;
+#define SETCOND_INVTCG_TARGET_NB_REGS
+#define SETCOND_NEZ(SETCOND_INV << 1)
+#define SETCOND_FLAGS  (SETCOND_INV | SETCOND_NEZ)
 
-if (c2) {
-tcg_debug_assert(arg2 == 0);
+static int tcg_out_setcond_int(TCGContext *s, TCGCond cond, TCGReg ret,
+   TCGReg arg1, tcg_target_long arg2, bool c2)
+{
+int flags = 0;
+
+switch (cond) {
+case TCG_COND_EQ:/* -> NE  */
+case TCG_COND_GE:/* -> LT  */
+case TCG_COND_GEU:   /* -> LTU */
+case TCG_COND_GT:/* -> LE  */
+case TCG_COND_GTU:   /* -> LEU */
+cond = tcg_invert_cond(cond);
+flags ^= SETCOND_INV;
+break;
+default:
+break;
 }
 
 switch (cond) {
-case TCG_COND_EQ:
-if (c2) {
-tmp = arg1;
-} else {
-tcg_out_opc_sub_d(s, ret, arg1, arg2);
-tmp = ret;
-}
-tcg_out_opc_sltui(s, ret, tmp, 1);
-break;
-case TCG_COND_NE:
-if (c2) {
-tmp = arg1;
-} else {
-tcg_out_opc_sub_d(s, ret, arg1, arg2);
-tmp = ret;
-}
-tcg_out_opc_sltu(s, ret, TCG_REG_ZERO, tmp);
-break;
-case TCG_COND_LT:
-tcg_out_opc_slt(s, ret, arg1, arg2);
-break;
-case TCG_COND_GE:
-tcg_out_opc_slt(s, ret, arg1, arg2);
-tcg_out_opc_xori(s, ret, ret, 1);
-break;
 case TCG_COND_LE:
-tcg_out_setcond(s, TCG_COND_GE, ret, arg2, arg1, false);
-break;
-case TCG_COND_GT:
-tcg_out_setcond(s, TCG_COND_LT, ret, arg2, arg1, false);
-break;
-case TCG_COND_LTU:
-tcg_out_opc_sltu(s, ret, arg1, arg2);
-break;
-case TCG_COND_GEU:
-tcg_out_opc_sltu(s, ret, arg1, arg2);
-tcg_out_opc_xori(s, ret, ret, 1);
-break;
 case TCG_COND_LEU:
-tcg_out_setcond(s, TCG_COND_GEU, ret, arg2, arg1, false);
+/*
+ * If we have a constant input, the most efficient way to implement
+ * LE is by adding 1 and using LT.  Watch out for wrap around for LEU.
+ * We don't need to care for this for LE because the constant input
+ * is still constrained to int32_t, and INT32_MAX+1 is representable
+ * in the 64-bit temporary register.
+ */
+if (c2) {
+if (cond == TCG_COND_LEU) {
+/* unsigned <= -1 is true */
+if (arg2 == -1) {
+tcg_out_movi(s, TCG_TYPE_REG, ret, !(flags & SETCOND_INV));
+return ret;
+}
+cond = TCG_COND_LTU;
+} else {
+cond = TCG_COND_LT;
+}
+arg2 += 1;
+} else {
+TCGReg tmp = arg2;
+arg2 = arg1;
+arg1 = tmp;
+cond = tcg_swap_cond(cond);/* LE -> GE */
+cond = tcg_invert_cond(cond);  /* GE -> LT */
+flags ^= SETCOND_INV;
+}
 break;
-case TCG_COND_GTU:
-tcg_out_setcond(s, TCG_COND_LTU, ret, arg2, arg1, false);
+default:
 break;
+}
+
+switch (cond) {
+case TCG_COND_NE:
+flags |= SETCOND_NEZ;
+if (!c2) {
+tcg_out_opc_xor(s, ret, arg1, arg2);
+} else if (arg2 == 0) {
+ret = arg1;
+} else if (arg2 >= 0 && arg2 <= 0xfff) {
+tcg_out_opc_xori(s, ret, arg1, arg2);
+} else {
+tcg_out_addi(s, TCG_TYPE_REG, ret, arg1, -arg2);
+}
+break;
+
+case TCG_COND_LT:
+case TCG_COND_LTU:
+if (c2) {
+if (arg2 >= -0x800 && arg2 <= 0x7ff) {
+if (cond == TCG_COND_LT) {
+tcg_out_opc_slti(s, ret, arg1, arg2);
+} else {
+tcg_out_opc_sltui(s, ret, arg1, arg2);
+}
+break;
+}
+tcg_out_movi(s, TCG_TYPE_REG, TCG_REG_TMP0, arg2);
+arg2 = TCG_REG_TMP0;
+}
+if (cond == TCG_COND_LT) {
+tcg_out_opc_slt(s, ret, arg1, arg2);
+

[PATCH v2 09/10] tcg/loongarch64: Use tcg_pcrel_diff in tcg_out_ldst

2023-01-17 Thread Richard Henderson
Take the w^x split into account when computing the
pc-relative distance to an absolute pointer.

Signed-off-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target.c.inc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 29d75c80eb..d6926bdb83 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -702,7 +702,7 @@ static void tcg_out_ldst(TCGContext *s, LoongArchInsn opc, 
TCGReg data,
 intptr_t imm12 = sextreg(offset, 0, 12);
 
 if (offset != imm12) {
-intptr_t diff = offset - (uintptr_t)s->code_ptr;
+intptr_t diff = tcg_pcrel_diff(s, (void *)offset);
 
 if (addr == TCG_REG_ZERO && diff == (int32_t)diff) {
 imm12 = sextreg(diff, 0, 12);
-- 
2.34.1




[PATCH v2 00/10] tcg/loongarch64: Reorg goto_tb and cleanups

2023-01-17 Thread Richard Henderson
Based-on: 20230117231051.35-1-richard.hender...@linaro.org
("[PULL 00/22] tcg patch queue")

Includes:
  * Disassembler from target/loongarch/.
  * Improvements to movi by Rui Wang, with minor tweaks.
  * Improvements to setcond.
  * Implement movcond.
  * Fix the same goto_tb bug that affected some others.


r~


Richard Henderson (9):
  target/loongarch: Enable the disassembler for host tcg
  target/loongarch: Disassemble jirl properly
  target/loongarch: Disassemble pcadd* addresses
  tcg/loongarch64: Update tcg-insn-defs.c.inc
  tcg/loongarch64: Introduce tcg_out_addi
  tcg/loongarch64: Improve setcond expansion
  tcg/loongarch64: Implement movcond
  tcg/loongarch64: Use tcg_pcrel_diff in tcg_out_ldst
  tcg/loongarch64: Reorg goto_tb implementation

Rui Wang (1):
  tcg/loongarch64: Optimize immediate loading

 tcg/loongarch64/tcg-target-con-set.h  |   5 +-
 tcg/loongarch64/tcg-target-con-str.h  |   2 +-
 tcg/loongarch64/tcg-target.h  |  11 +-
 disas.c   |   2 +
 target/loongarch/disas.c  |  39 +-
 .../loongarch/insn_trans/trans_branch.c.inc   |   2 +-
 target/loongarch/insns.decode |   3 +-
 target/loongarch/meson.build  |   3 +-
 tcg/loongarch64/tcg-insn-defs.c.inc   |  10 +-
 tcg/loongarch64/tcg-target.c.inc  | 364 --
 10 files changed, 300 insertions(+), 141 deletions(-)
 mode change 100644 => 100755 tcg/loongarch64/tcg-insn-defs.c.inc

-- 
2.34.1




[PATCH v2 08/10] tcg/loongarch64: Implement movcond

2023-01-17 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target-con-set.h |  1 +
 tcg/loongarch64/tcg-target.h |  4 ++--
 tcg/loongarch64/tcg-target.c.inc | 33 
 3 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/tcg/loongarch64/tcg-target-con-set.h 
b/tcg/loongarch64/tcg-target-con-set.h
index 7b5a7a3f5d..172c107289 100644
--- a/tcg/loongarch64/tcg-target-con-set.h
+++ b/tcg/loongarch64/tcg-target-con-set.h
@@ -31,3 +31,4 @@ C_O1_I2(r, 0, rZ)
 C_O1_I2(r, rZ, ri)
 C_O1_I2(r, rZ, rJ)
 C_O1_I2(r, rZ, rZ)
+C_O1_I4(r, rZ, rJ, rZ, rZ)
diff --git a/tcg/loongarch64/tcg-target.h b/tcg/loongarch64/tcg-target.h
index 1c3e48d662..533a539ce9 100644
--- a/tcg/loongarch64/tcg-target.h
+++ b/tcg/loongarch64/tcg-target.h
@@ -97,7 +97,7 @@ typedef enum {
 #define TCG_TARGET_CALL_ARG_I64 TCG_CALL_ARG_NORMAL
 
 /* optional instructions */
-#define TCG_TARGET_HAS_movcond_i32  0
+#define TCG_TARGET_HAS_movcond_i32  1
 #define TCG_TARGET_HAS_div_i32  1
 #define TCG_TARGET_HAS_rem_i32  1
 #define TCG_TARGET_HAS_div2_i32 0
@@ -133,7 +133,7 @@ typedef enum {
 #define TCG_TARGET_HAS_qemu_st8_i32 0
 
 /* 64-bit operations */
-#define TCG_TARGET_HAS_movcond_i64  0
+#define TCG_TARGET_HAS_movcond_i64  1
 #define TCG_TARGET_HAS_div_i64  1
 #define TCG_TARGET_HAS_rem_i64  1
 #define TCG_TARGET_HAS_div2_i64 0
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index ccc1c0f392..29d75c80eb 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -596,6 +596,30 @@ static void tcg_out_setcond(TCGContext *s, TCGCond cond, 
TCGReg ret,
 }
 }
 
+static void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGReg ret,
+TCGReg c1, tcg_target_long c2, bool const2,
+TCGReg v1, TCGReg v2)
+{
+int tmpflags = tcg_out_setcond_int(s, cond, TCG_REG_TMP0, c1, c2, const2);
+TCGReg t;
+
+/* Standardize the test below to t != 0. */
+if (tmpflags & SETCOND_INV) {
+t = v1, v1 = v2, v2 = t;
+}
+
+t = tmpflags & ~SETCOND_FLAGS;
+if (v1 == TCG_REG_ZERO) {
+tcg_out_opc_masknez(s, ret, v2, t);
+} else if (v2 == TCG_REG_ZERO) {
+tcg_out_opc_maskeqz(s, ret, v1, t);
+} else {
+tcg_out_opc_masknez(s, TCG_REG_TMP2, v2, t); /* t ? 0 : v2 */
+tcg_out_opc_maskeqz(s, TCG_REG_TMP1, v1, t); /* t ? v1 : 0 */
+tcg_out_opc_or(s, ret, TCG_REG_TMP1, TCG_REG_TMP2);
+}
+}
+
 /*
  * Branch helpers
  */
@@ -1538,6 +1562,11 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 tcg_out_setcond(s, args[3], a0, a1, a2, c2);
 break;
 
+case INDEX_op_movcond_i32:
+case INDEX_op_movcond_i64:
+tcg_out_movcond(s, args[5], a0, a1, a2, c2, args[3], args[4]);
+break;
+
 case INDEX_op_ld8s_i32:
 case INDEX_op_ld8s_i64:
 tcg_out_ldst(s, OPC_LD_B, a0, a1, a2);
@@ -1741,6 +1770,10 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode 
op)
 case INDEX_op_remu_i64:
 return C_O1_I2(r, rZ, rZ);
 
+case INDEX_op_movcond_i32:
+case INDEX_op_movcond_i64:
+return C_O1_I4(r, rZ, rJ, rZ, rZ);
+
 default:
 g_assert_not_reached();
 }
-- 
2.34.1




[PATCH v2 05/10] tcg/loongarch64: Update tcg-insn-defs.c.inc

2023-01-17 Thread Richard Henderson
Regenerate with ADDU16I included:

   $ cd loongarch-opcodes/scripts/go
   $ go run ./genqemutcgdefs > $QEMU/tcg/loongarch64/tcg-insn-defs.c.inc

Signed-off-by: Richard Henderson 
---
 tcg/loongarch64/tcg-insn-defs.c.inc | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)
 mode change 100644 => 100755 tcg/loongarch64/tcg-insn-defs.c.inc

diff --git a/tcg/loongarch64/tcg-insn-defs.c.inc 
b/tcg/loongarch64/tcg-insn-defs.c.inc
old mode 100644
new mode 100755
index d162571856..b5bb0c5e73
--- a/tcg/loongarch64/tcg-insn-defs.c.inc
+++ b/tcg/loongarch64/tcg-insn-defs.c.inc
@@ -4,7 +4,7 @@
  *
  * This file is auto-generated by genqemutcgdefs from
  * https://github.com/loongson-community/loongarch-opcodes,
- * from commit 961f0c60f5b63e574d785995600c71ad5413fdc4.
+ * from commit 25ca7effe9d88101c1cf96c4005423643386d81f.
  * DO NOT EDIT.
  */
 
@@ -74,6 +74,7 @@ typedef enum {
 OPC_ANDI = 0x0340,
 OPC_ORI = 0x0380,
 OPC_XORI = 0x03c0,
+OPC_ADDU16I_D = 0x1000,
 OPC_LU12I_W = 0x1400,
 OPC_CU32I_D = 0x1600,
 OPC_PCADDU2I = 0x1800,
@@ -710,6 +711,13 @@ tcg_out_opc_xori(TCGContext *s, TCGReg d, TCGReg j, 
uint32_t uk12)
 tcg_out32(s, encode_djuk12_insn(OPC_XORI, d, j, uk12));
 }
 
+/* Emits the `addu16i.d d, j, sk16` instruction.  */
+static void __attribute__((unused))
+tcg_out_opc_addu16i_d(TCGContext *s, TCGReg d, TCGReg j, int32_t sk16)
+{
+tcg_out32(s, encode_djsk16_insn(OPC_ADDU16I_D, d, j, sk16));
+}
+
 /* Emits the `lu12i.w d, sj20` instruction.  */
 static void __attribute__((unused))
 tcg_out_opc_lu12i_w(TCGContext *s, TCGReg d, int32_t sj20)
-- 
2.34.1




[PATCH v2 10/10] tcg/loongarch64: Reorg goto_tb implementation

2023-01-17 Thread Richard Henderson
The old implementation replaces two insns, swapping between

b   
nop
and
pcaddu18i tmp, 
jirl  zero, tmp,  & 0x

There is a race condition in which a thread could be stopped at
the jirl, i.e. with the top of the address loaded, and when
restarted we have re-linked to a different TB, so that the top
half no longer matches the bottom half.

Note that while we never directly re-link to a different TB, we
can link, unlink, and link again all while the stopped thread
remains stopped.

The new implementation replaces only one insn, swapping between

b   
and
pcadd   tmp, 

falling through to load the address from tmp, and branch.

Signed-off-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target.h |  7 +---
 tcg/loongarch64/tcg-target.c.inc | 72 ++--
 2 files changed, 33 insertions(+), 46 deletions(-)

diff --git a/tcg/loongarch64/tcg-target.h b/tcg/loongarch64/tcg-target.h
index 533a539ce9..8b151e7f6f 100644
--- a/tcg/loongarch64/tcg-target.h
+++ b/tcg/loongarch64/tcg-target.h
@@ -42,11 +42,8 @@
 
 #define TCG_TARGET_INSN_UNIT_SIZE 4
 #define TCG_TARGET_NB_REGS 32
-/*
- * PCADDU18I + JIRL sequence can give 20 + 16 + 2 = 38 bits
- * signed offset, which is +/- 128 GiB.
- */
-#define MAX_CODE_GEN_BUFFER_SIZE  (128 * GiB)
+
+#define MAX_CODE_GEN_BUFFER_SIZE  ((size_t)-1)
 
 typedef enum {
 TCG_REG_ZERO,
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index d6926bdb83..ce4a153887 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -1151,37 +1151,6 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg 
*args)
 #endif
 }
 
-/* LoongArch uses `andi zero, zero, 0` as NOP.  */
-#define NOP OPC_ANDI
-static void tcg_out_nop(TCGContext *s)
-{
-tcg_out32(s, NOP);
-}
-
-void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
-  uintptr_t jmp_rx, uintptr_t jmp_rw)
-{
-tcg_insn_unit i1, i2;
-ptrdiff_t upper, lower;
-uintptr_t addr = tb->jmp_target_addr[n];
-ptrdiff_t offset = (ptrdiff_t)(addr - jmp_rx) >> 2;
-
-if (offset == sextreg(offset, 0, 26)) {
-i1 = encode_sd10k16_insn(OPC_B, offset);
-i2 = NOP;
-} else {
-tcg_debug_assert(offset == sextreg(offset, 0, 36));
-lower = (int16_t)offset;
-upper = (offset - lower) >> 16;
-
-i1 = encode_dsj20_insn(OPC_PCADDU18I, TCG_REG_TMP0, upper);
-i2 = encode_djsk16_insn(OPC_JIRL, TCG_REG_ZERO, TCG_REG_TMP0, lower);
-}
-uint64_t pair = ((uint64_t)i2 << 32) | i1;
-qatomic_set((uint64_t *)jmp_rw, pair);
-flush_idcache_range(jmp_rx, jmp_rw, 8);
-}
-
 /*
  * Entry-points
  */
@@ -1202,22 +1171,43 @@ static void tcg_out_exit_tb(TCGContext *s, uintptr_t a0)
 static void tcg_out_goto_tb(TCGContext *s, int which)
 {
 /*
- * Ensure that patch area is 8-byte aligned so that an
- * atomic write can be used to patch the target address.
+ * Direct branch, or load indirect address, to be patched
+ * by tb_target_set_jmp_target.  Check indirect load offset
+ * in range early, regardless of direct branch distance,
+ * via assert within tcg_out_opc_pcaddu2i.
  */
-if ((uintptr_t)s->code_ptr & 7) {
-tcg_out_nop(s);
-}
+uintptr_t i_addr = get_jmp_target_addr(s, which);
+intptr_t i_disp = tcg_pcrel_diff(s, (void *)i_addr);
+
 set_jmp_insn_offset(s, which);
-/*
- * actual branch destination will be patched by
- * tb_target_set_jmp_target later
- */
-tcg_out_opc_pcaddu18i(s, TCG_REG_TMP0, 0);
+tcg_out_opc_pcaddu2i(s, TCG_REG_TMP0, i_disp >> 2);
+
+/* Finish the load and indirect branch. */
+tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP0, TCG_REG_TMP0, 0);
 tcg_out_opc_jirl(s, TCG_REG_ZERO, TCG_REG_TMP0, 0);
 set_jmp_reset_offset(s, which);
 }
 
+void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
+  uintptr_t jmp_rx, uintptr_t jmp_rw)
+{
+uintptr_t d_addr = tb->jmp_target_addr[n];
+ptrdiff_t d_disp = (ptrdiff_t)(d_addr - jmp_rx) >> 2;
+tcg_insn_unit insn;
+
+/* Either directly branch, or load slot address for indirect branch. */
+if (d_disp == sextreg(d_disp, 0, 26)) {
+insn = encode_sd10k16_insn(OPC_B, d_disp);
+} else {
+uintptr_t i_addr = (uintptr_t)>jmp_target_addr[n];
+intptr_t i_disp = i_addr - jmp_rx;
+insn = encode_dsj20_insn(OPC_PCADDU2I, TCG_REG_TMP0, i_disp >> 2);
+}
+
+qatomic_set((tcg_insn_unit *)jmp_rw, insn);
+flush_idcache_range(jmp_rx, jmp_rw, 4);
+}
+
 static void tcg_out_op(TCGContext *s, TCGOpcode opc,
const TCGArg args[TCG_MAX_OP_ARGS],
const int const_args[TCG_MAX_OP_ARGS])
-- 
2.34.1




[PATCH v2 04/10] tcg/loongarch64: Optimize immediate loading

2023-01-17 Thread Richard Henderson
From: Rui Wang 

diff:
  Imm Before  After
  addi.w  rd, zero, 0 addi.w  rd, zero, 0
  lu52i.d rd, zero, 0
  f800lu12i.w rd, -1  addi.w  rd, zero, -2048
  ori rd, rd, 2048lu32i.d rd, 0
  lu32i.d rd, 0
  ...

Signed-off-by: Rui Wang 
Message-Id: <20221107144713.845550-1-wang...@loongson.cn>
Signed-off-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target.c.inc | 35 +++-
 1 file changed, 12 insertions(+), 23 deletions(-)

diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 3174557ce3..428f3abd71 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -274,16 +274,6 @@ static bool tcg_out_mov(TCGContext *s, TCGType type, 
TCGReg ret, TCGReg arg)
 return true;
 }
 
-static bool imm_part_needs_loading(bool high_bits_are_ones,
-   tcg_target_long part)
-{
-if (high_bits_are_ones) {
-return part != -1;
-} else {
-return part != 0;
-}
-}
-
 /* Loads a 32-bit immediate into rd, sign-extended.  */
 static void tcg_out_movi_i32(TCGContext *s, TCGReg rd, int32_t val)
 {
@@ -291,16 +281,16 @@ static void tcg_out_movi_i32(TCGContext *s, TCGReg rd, 
int32_t val)
 tcg_target_long hi12 = sextreg(val, 12, 20);
 
 /* Single-instruction cases.  */
-if (lo == val) {
-/* val fits in simm12: addi.w rd, zero, val */
-tcg_out_opc_addi_w(s, rd, TCG_REG_ZERO, val);
-return;
-}
-if (0x800 <= val && val <= 0xfff) {
+if (hi12 == 0) {
 /* val fits in uimm12: ori rd, zero, val */
 tcg_out_opc_ori(s, rd, TCG_REG_ZERO, val);
 return;
 }
+if (hi12 == sextreg(lo, 12, 20)) {
+/* val fits in simm12: addi.w rd, zero, val */
+tcg_out_opc_addi_w(s, rd, TCG_REG_ZERO, val);
+return;
+}
 
 /* High bits must be set; load with lu12i.w + optional ori.  */
 tcg_out_opc_lu12i_w(s, rd, hi12);
@@ -334,8 +324,7 @@ static void tcg_out_movi(TCGContext *s, TCGType type, 
TCGReg rd,
 
 intptr_t pc_offset;
 tcg_target_long val_lo, val_hi, pc_hi, offset_hi;
-tcg_target_long hi32, hi52;
-bool rd_high_bits_are_ones;
+tcg_target_long hi12, hi32, hi52;
 
 /* Value fits in signed i32.  */
 if (type == TCG_TYPE_I32 || val == (int32_t)val) {
@@ -366,25 +355,25 @@ static void tcg_out_movi(TCGContext *s, TCGType type, 
TCGReg rd,
 return;
 }
 
+hi12 = sextreg(val, 12, 20);
 hi32 = sextreg(val, 32, 20);
 hi52 = sextreg(val, 52, 12);
 
 /* Single cu52i.d case.  */
-if (ctz64(val) >= 52) {
+if ((hi52 != 0) && (ctz64(val) >= 52)) {
 tcg_out_opc_cu52i_d(s, rd, TCG_REG_ZERO, hi52);
 return;
 }
 
 /* Slow path.  Initialize the low 32 bits, then concat high bits.  */
 tcg_out_movi_i32(s, rd, val);
-rd_high_bits_are_ones = (int32_t)val < 0;
 
-if (imm_part_needs_loading(rd_high_bits_are_ones, hi32)) {
+/* Load hi32 and hi52 explicitly when they are unexpected values. */
+if (hi32 != sextreg(hi12, 20, 20)) {
 tcg_out_opc_cu32i_d(s, rd, hi32);
-rd_high_bits_are_ones = hi32 < 0;
 }
 
-if (imm_part_needs_loading(rd_high_bits_are_ones, hi52)) {
+if (hi52 != sextreg(hi32, 20, 12)) {
 tcg_out_opc_cu52i_d(s, rd, rd, hi52);
 }
 }
-- 
2.34.1




[PATCH v2 01/10] target/loongarch: Enable the disassembler for host tcg

2023-01-17 Thread Richard Henderson
Reuse the decodetree based disassembler from
target/loongarch/ for tcg/loongarch64/.

The generation of decode-insns.c.inc into ./libcommon.fa.p/ could
eventually result in conflict, if any other host requires the same
trick, but this is good enough for now.

Signed-off-by: Richard Henderson 
---
 disas.c  | 2 ++
 target/loongarch/meson.build | 3 ++-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/disas.c b/disas.c
index 3b31315f40..c9fa38e6d7 100644
--- a/disas.c
+++ b/disas.c
@@ -198,6 +198,8 @@ static void initialize_debug_host(CPUDebug *s)
 s->info.cap_insn_split = 6;
 #elif defined(__hppa__)
 s->info.print_insn = print_insn_hppa;
+#elif defined(__loongarch64)
+s->info.print_insn = print_insn_loongarch;
 #endif
 }
 
diff --git a/target/loongarch/meson.build b/target/loongarch/meson.build
index 6376f9e84b..690633969f 100644
--- a/target/loongarch/meson.build
+++ b/target/loongarch/meson.build
@@ -3,7 +3,6 @@ gen = decodetree.process('insns.decode')
 loongarch_ss = ss.source_set()
 loongarch_ss.add(files(
   'cpu.c',
-  'disas.c',
 ))
 loongarch_tcg_ss = ss.source_set()
 loongarch_tcg_ss.add(gen)
@@ -24,6 +23,8 @@ loongarch_softmmu_ss.add(files(
   'iocsr_helper.c',
 ))
 
+common_ss.add(when: 'CONFIG_LOONGARCH_DIS', if_true: [files('disas.c'), gen])
+
 loongarch_ss.add_all(when: 'CONFIG_TCG', if_true: [loongarch_tcg_ss])
 
 target_arch += {'loongarch': loongarch_ss}
-- 
2.34.1




[PATCH 2/4] hw/misc/macio: Rename sysbus_dev to sbd for consistency and brevity

2023-01-17 Thread BALATON Zoltan
Some functions use sysbus_dev while others sbd name for local variable
storing a sysbus device pointer. Standardise on the shorter name to be
consistent and make the code easier to read as short name is less
distracting and needs less line breaks.

Signed-off-by: BALATON Zoltan 
---
 hw/misc/macio/macio.c | 78 +++
 1 file changed, 35 insertions(+), 43 deletions(-)

diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c
index 0dfe372965..4d7223cc85 100644
--- a/hw/misc/macio/macio.c
+++ b/hw/misc/macio/macio.c
@@ -96,14 +96,14 @@ static void macio_bar_setup(MacIOState *s)
 static void macio_common_realize(PCIDevice *d, Error **errp)
 {
 MacIOState *s = MACIO(d);
-SysBusDevice *sysbus_dev;
+SysBusDevice *sbd;
 
 if (!qdev_realize(DEVICE(>dbdma), BUS(>macio_bus), errp)) {
 return;
 }
-sysbus_dev = SYS_BUS_DEVICE(>dbdma);
+sbd = SYS_BUS_DEVICE(>dbdma);
 memory_region_add_subregion(>bar, 0x08000,
-sysbus_mmio_get_region(sysbus_dev, 0));
+sysbus_mmio_get_region(sbd, 0));
 
 qdev_prop_set_uint32(DEVICE(>escc), "disabled", 0);
 qdev_prop_set_uint32(DEVICE(>escc), "frequency", ESCC_CLOCK);
@@ -122,11 +122,10 @@ static void macio_realize_ide(MacIOState *s, 
MACIOIDEState *ide,
   qemu_irq irq0, qemu_irq irq1, int dmaid,
   Error **errp)
 {
-SysBusDevice *sysbus_dev;
+SysBusDevice *sbd = SYS_BUS_DEVICE(ide);
 
-sysbus_dev = SYS_BUS_DEVICE(ide);
-sysbus_connect_irq(sysbus_dev, 0, irq0);
-sysbus_connect_irq(sysbus_dev, 1, irq1);
+sysbus_connect_irq(sbd, 0, irq0);
+sysbus_connect_irq(sbd, 1, irq1);
 qdev_prop_set_uint32(DEVICE(ide), "channel", dmaid);
 object_property_set_link(OBJECT(ide), "dbdma", OBJECT(>dbdma),
  _abort);
@@ -141,7 +140,7 @@ static void macio_oldworld_realize(PCIDevice *d, Error 
**errp)
 OldWorldMacIOState *os = OLDWORLD_MACIO(d);
 DeviceState *pic_dev = DEVICE(>pic);
 Error *err = NULL;
-SysBusDevice *sysbus_dev;
+SysBusDevice *sbd;
 
 macio_common_realize(d, );
 if (err) {
@@ -153,33 +152,30 @@ static void macio_oldworld_realize(PCIDevice *d, Error 
**errp)
 if (!qdev_realize(DEVICE(>pic), BUS(>macio_bus), errp)) {
 return;
 }
-sysbus_dev = SYS_BUS_DEVICE(>pic);
+sbd = SYS_BUS_DEVICE(>pic);
 memory_region_add_subregion(>bar, 0x0,
-sysbus_mmio_get_region(sysbus_dev, 0));
+sysbus_mmio_get_region(sbd, 0));
 
 qdev_prop_set_uint64(DEVICE(>cuda), "timebase-frequency",
  s->frequency);
 if (!qdev_realize(DEVICE(>cuda), BUS(>macio_bus), errp)) {
 return;
 }
-sysbus_dev = SYS_BUS_DEVICE(>cuda);
+sbd = SYS_BUS_DEVICE(>cuda);
 memory_region_add_subregion(>bar, 0x16000,
-sysbus_mmio_get_region(sysbus_dev, 0));
-sysbus_connect_irq(sysbus_dev, 0, qdev_get_gpio_in(pic_dev,
-   OLDWORLD_CUDA_IRQ));
+sysbus_mmio_get_region(sbd, 0));
+sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(pic_dev, OLDWORLD_CUDA_IRQ));
 
-sysbus_dev = SYS_BUS_DEVICE(>escc);
-sysbus_connect_irq(sysbus_dev, 0, qdev_get_gpio_in(pic_dev,
-   OLDWORLD_ESCCB_IRQ));
-sysbus_connect_irq(sysbus_dev, 1, qdev_get_gpio_in(pic_dev,
-   OLDWORLD_ESCCA_IRQ));
+sbd = SYS_BUS_DEVICE(>escc);
+sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(pic_dev, OLDWORLD_ESCCB_IRQ));
+sysbus_connect_irq(sbd, 1, qdev_get_gpio_in(pic_dev, OLDWORLD_ESCCA_IRQ));
 
 if (!qdev_realize(DEVICE(>nvram), BUS(>macio_bus), errp)) {
 return;
 }
-sysbus_dev = SYS_BUS_DEVICE(>nvram);
+sbd = SYS_BUS_DEVICE(>nvram);
 memory_region_add_subregion(>bar, 0x6,
-sysbus_mmio_get_region(sysbus_dev, 0));
+sysbus_mmio_get_region(sbd, 0));
 pmac_format_nvram_partition(>nvram, os->nvram.size);
 
 /* IDE buses */
@@ -274,7 +270,7 @@ static void macio_newworld_realize(PCIDevice *d, Error 
**errp)
 NewWorldMacIOState *ns = NEWWORLD_MACIO(d);
 DeviceState *pic_dev = DEVICE(>pic);
 Error *err = NULL;
-SysBusDevice *sysbus_dev;
+SysBusDevice *sbd;
 MemoryRegion *timer_memory = NULL;
 
 macio_common_realize(d, );
@@ -285,16 +281,14 @@ static void macio_newworld_realize(PCIDevice *d, Error 
**errp)
 
 /* OpenPIC */
 qdev_prop_set_uint32(pic_dev, "model", OPENPIC_MODEL_KEYLARGO);
-sysbus_dev = SYS_BUS_DEVICE(>pic);
-sysbus_realize_and_unref(sysbus_dev, _fatal);
+sbd = SYS_BUS_DEVICE(>pic);
+sysbus_realize_and_unref(sbd, _fatal);
 memory_region_add_subregion(>bar, 

[PATCH 3/4] hw/misc/macio: Remove some single use local variables

2023-01-17 Thread BALATON Zoltan
Drop some local variables that could just be substituted at the single
place they were used. This makes the code shorter and simpler.

Signed-off-by: BALATON Zoltan 
---
 hw/misc/macio/macio.c | 13 +
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c
index 4d7223cc85..ae2a9a960d 100644
--- a/hw/misc/macio/macio.c
+++ b/hw/misc/macio/macio.c
@@ -53,10 +53,8 @@
  */
 static void macio_escc_legacy_setup(MacIOState *s)
 {
-ESCCState *escc = ESCC(>escc);
-SysBusDevice *sbd = SYS_BUS_DEVICE(escc);
+SysBusDevice *sbd = SYS_BUS_DEVICE(>escc);
 MemoryRegion *escc_legacy = g_new(MemoryRegion, 1);
-MemoryRegion *bar = >bar;
 int i;
 static const int maps[] = {
 0x00, 0x00, /* Command B */
@@ -80,16 +78,15 @@ static void macio_escc_legacy_setup(MacIOState *s)
 memory_region_add_subregion(escc_legacy, maps[i], port);
 }
 
-memory_region_add_subregion(bar, 0x12000, escc_legacy);
+memory_region_add_subregion(>bar, 0x12000, escc_legacy);
 }
 
 static void macio_bar_setup(MacIOState *s)
 {
-ESCCState *escc = ESCC(>escc);
-SysBusDevice *sbd = SYS_BUS_DEVICE(escc);
-MemoryRegion *bar = >bar;
+SysBusDevice *sbd = SYS_BUS_DEVICE(>escc);
+MemoryRegion *bar = sysbus_mmio_get_region(sbd, 0);
 
-memory_region_add_subregion(bar, 0x13000, sysbus_mmio_get_region(sbd, 0));
+memory_region_add_subregion(>bar, 0x13000, bar);
 macio_escc_legacy_setup(s);
 }
 
-- 
2.30.6




[PATCH 0/4] Misc macio clean ups

2023-01-17 Thread BALATON Zoltan
Just some small trivial clean ups that I've found while looking at
hw/misc/macio/macio.c

Regards,
BALATON Zoltan

BALATON Zoltan (4):
  hw/misc/macio: Avoid some QOM casts
  hw/misc/macio: Rename sysbus_dev to sbd for consistency and brevity
  hw/misc/macio: Remove some single use local variables
  hw/misc/macio: Return bool from functions taking errp

 hw/misc/macio/macio.c | 167 ++
 1 file changed, 72 insertions(+), 95 deletions(-)

-- 
2.30.6




[PATCH 1/4] hw/misc/macio: Avoid some QOM casts

2023-01-17 Thread BALATON Zoltan
At several places we already have the object pointer with the right
type so we don't need to cast it back and forth. Avoiding these casts
improves readability.

Signed-off-by: BALATON Zoltan 
---
 hw/misc/macio/macio.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c
index 08dbdd7fc0..0dfe372965 100644
--- a/hw/misc/macio/macio.c
+++ b/hw/misc/macio/macio.c
@@ -220,11 +220,11 @@ static void macio_oldworld_init(Object *obj)
 DeviceState *dev;
 int i;
 
-object_initialize_child(OBJECT(s), "pic", >pic, TYPE_HEATHROW);
+object_initialize_child(obj, "pic", >pic, TYPE_HEATHROW);
 
-object_initialize_child(OBJECT(s), "cuda", >cuda, TYPE_CUDA);
+object_initialize_child(obj, "cuda", >cuda, TYPE_CUDA);
 
-object_initialize_child(OBJECT(s), "nvram", >nvram, TYPE_MACIO_NVRAM);
+object_initialize_child(obj, "nvram", >nvram, TYPE_MACIO_NVRAM);
 dev = DEVICE(>nvram);
 qdev_prop_set_uint32(dev, "size", MACIO_NVRAM_SIZE);
 qdev_prop_set_uint32(dev, "it_shift", 4);
@@ -372,9 +372,9 @@ static void macio_newworld_init(Object *obj)
 NewWorldMacIOState *ns = NEWWORLD_MACIO(obj);
 int i;
 
-object_initialize_child(OBJECT(s), "pic", >pic, TYPE_OPENPIC);
+object_initialize_child(obj, "pic", >pic, TYPE_OPENPIC);
 
-object_initialize_child(OBJECT(s), "gpio", >gpio, TYPE_MACIO_GPIO);
+object_initialize_child(obj, "gpio", >gpio, TYPE_MACIO_GPIO);
 
 for (i = 0; i < 2; i++) {
 macio_init_ide(s, >ide[i], i);
@@ -390,9 +390,9 @@ static void macio_instance_init(Object *obj)
 qbus_init(>macio_bus, sizeof(s->macio_bus), TYPE_MACIO_BUS,
   DEVICE(obj), "macio.0");
 
-object_initialize_child(OBJECT(s), "dbdma", >dbdma, TYPE_MAC_DBDMA);
+object_initialize_child(obj, "dbdma", >dbdma, TYPE_MAC_DBDMA);
 
-object_initialize_child(OBJECT(s), "escc", >escc, TYPE_ESCC);
+object_initialize_child(obj, "escc", >escc, TYPE_ESCC);
 }
 
 static const VMStateDescription vmstate_macio_oldworld = {
-- 
2.30.6




[PATCH 4/4] hw/misc/macio: Return bool from functions taking errp

2023-01-17 Thread BALATON Zoltan
Use the convention to return bool from functions which take an error
pointer which allows for callers to pass through their error pointer
without needing a local.

Signed-off-by: BALATON Zoltan 
---
 hw/misc/macio/macio.c | 62 +--
 1 file changed, 25 insertions(+), 37 deletions(-)

diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c
index ae2a9a960d..265c0bbd8d 100644
--- a/hw/misc/macio/macio.c
+++ b/hw/misc/macio/macio.c
@@ -90,13 +90,13 @@ static void macio_bar_setup(MacIOState *s)
 macio_escc_legacy_setup(s);
 }
 
-static void macio_common_realize(PCIDevice *d, Error **errp)
+static bool macio_common_realize(PCIDevice *d, Error **errp)
 {
 MacIOState *s = MACIO(d);
 SysBusDevice *sbd;
 
 if (!qdev_realize(DEVICE(>dbdma), BUS(>macio_bus), errp)) {
-return;
+return false;
 }
 sbd = SYS_BUS_DEVICE(>dbdma);
 memory_region_add_subregion(>bar, 0x08000,
@@ -108,14 +108,16 @@ static void macio_common_realize(PCIDevice *d, Error 
**errp)
 qdev_prop_set_uint32(DEVICE(>escc), "chnBtype", escc_serial);
 qdev_prop_set_uint32(DEVICE(>escc), "chnAtype", escc_serial);
 if (!qdev_realize(DEVICE(>escc), BUS(>macio_bus), errp)) {
-return;
+return false;
 }
 
 macio_bar_setup(s);
 pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, >bar);
+
+return true;
 }
 
-static void macio_realize_ide(MacIOState *s, MACIOIDEState *ide,
+static bool macio_realize_ide(MacIOState *s, MACIOIDEState *ide,
   qemu_irq irq0, qemu_irq irq1, int dmaid,
   Error **errp)
 {
@@ -128,7 +130,7 @@ static void macio_realize_ide(MacIOState *s, MACIOIDEState 
*ide,
  _abort);
 macio_ide_register_dma(ide);
 
-qdev_realize(DEVICE(ide), BUS(>macio_bus), errp);
+return qdev_realize(DEVICE(ide), BUS(>macio_bus), errp);
 }
 
 static void macio_oldworld_realize(PCIDevice *d, Error **errp)
@@ -136,12 +138,9 @@ static void macio_oldworld_realize(PCIDevice *d, Error 
**errp)
 MacIOState *s = MACIO(d);
 OldWorldMacIOState *os = OLDWORLD_MACIO(d);
 DeviceState *pic_dev = DEVICE(>pic);
-Error *err = NULL;
 SysBusDevice *sbd;
 
-macio_common_realize(d, );
-if (err) {
-error_propagate(errp, err);
+if (!macio_common_realize(d, errp)) {
 return;
 }
 
@@ -176,21 +175,17 @@ static void macio_oldworld_realize(PCIDevice *d, Error 
**errp)
 pmac_format_nvram_partition(>nvram, os->nvram.size);
 
 /* IDE buses */
-macio_realize_ide(s, >ide[0],
-  qdev_get_gpio_in(pic_dev, OLDWORLD_IDE0_IRQ),
-  qdev_get_gpio_in(pic_dev, OLDWORLD_IDE0_DMA_IRQ),
-  0x16, );
-if (err) {
-error_propagate(errp, err);
+if (!macio_realize_ide(s, >ide[0],
+   qdev_get_gpio_in(pic_dev, OLDWORLD_IDE0_IRQ),
+   qdev_get_gpio_in(pic_dev, OLDWORLD_IDE0_DMA_IRQ),
+   0x16, errp)) {
 return;
 }
 
-macio_realize_ide(s, >ide[1],
-  qdev_get_gpio_in(pic_dev, OLDWORLD_IDE1_IRQ),
-  qdev_get_gpio_in(pic_dev, OLDWORLD_IDE1_DMA_IRQ),
-  0x1a, );
-if (err) {
-error_propagate(errp, err);
+if (!macio_realize_ide(s, >ide[1],
+   qdev_get_gpio_in(pic_dev, OLDWORLD_IDE1_IRQ),
+   qdev_get_gpio_in(pic_dev, OLDWORLD_IDE1_DMA_IRQ),
+   0x1a, errp)) {
 return;
 }
 }
@@ -266,13 +261,10 @@ static void macio_newworld_realize(PCIDevice *d, Error 
**errp)
 MacIOState *s = MACIO(d);
 NewWorldMacIOState *ns = NEWWORLD_MACIO(d);
 DeviceState *pic_dev = DEVICE(>pic);
-Error *err = NULL;
 SysBusDevice *sbd;
 MemoryRegion *timer_memory = NULL;
 
-macio_common_realize(d, );
-if (err) {
-error_propagate(errp, err);
+if (!macio_common_realize(d, errp)) {
 return;
 }
 
@@ -288,21 +280,17 @@ static void macio_newworld_realize(PCIDevice *d, Error 
**errp)
 sysbus_connect_irq(sbd, 1, qdev_get_gpio_in(pic_dev, NEWWORLD_ESCCA_IRQ));
 
 /* IDE buses */
-macio_realize_ide(s, >ide[0],
-  qdev_get_gpio_in(pic_dev, NEWWORLD_IDE0_IRQ),
-  qdev_get_gpio_in(pic_dev, NEWWORLD_IDE0_DMA_IRQ),
-  0x16, );
-if (err) {
-error_propagate(errp, err);
+if (!macio_realize_ide(s, >ide[0],
+   qdev_get_gpio_in(pic_dev, NEWWORLD_IDE0_IRQ),
+   qdev_get_gpio_in(pic_dev, NEWWORLD_IDE0_DMA_IRQ),
+   0x16, errp)) {
 return;
 }
 
-macio_realize_ide(s, >ide[1],
-  qdev_get_gpio_in(pic_dev, NEWWORLD_IDE1_IRQ),
-  qdev_get_gpio_in(pic_dev, NEWWORLD_IDE1_DMA_IRQ),
-  0x1a, );

Re: [PATCH v5 2/2] riscv: Allow user to set the satp mode

2023-01-17 Thread Alistair Francis
On Wed, Jan 18, 2023 at 2:32 AM Andrew Jones  wrote:
>
> On Fri, Jan 13, 2023 at 11:34:53AM +0100, Alexandre Ghiti wrote:
> > RISC-V specifies multiple sizes for addressable memory and Linux probes for
> > the machine's support at startup via the satp CSR register (done in
> > csr.c:validate_vm).
> >
> > As per the specification, sv64 must support sv57, which in turn must
> > support sv48...etc. So we can restrict machine support by simply setting the
> > "highest" supported mode and the bare mode is always supported.
> >
> > You can set the satp mode using the new properties "sv32", "sv39", "sv48",
> > "sv57" and "sv64" as follows:
> > -cpu rv64,sv57=on  # Linux will boot using sv57 scheme
> > -cpu rv64,sv39=on  # Linux will boot using sv39 scheme
> > -cpu rv64,sv57=off # Linux will boot using sv48 scheme
> > -cpu rv64  # Linux will boot using sv57 scheme by default
> >
> > We take the highest level set by the user:
> > -cpu rv64,sv48=on,sv57=on # Linux will boot using sv57 scheme
> >
> > We make sure that invalid configurations are rejected:
> > -cpu rv64,sv32=on # Can't enable 32-bit satp mode in 64-bit
> > -cpu rv64,sv39=off,sv48=on # sv39 must be supported if higher modes are
> ># enabled
> >
> > We accept "redundant" configurations:
> > -cpu rv64,sv48=on,sv57=off # Linux will boot using sv48 scheme
> > -cpu rv64,sv32=on,sv32=off # Linux will boot using sv57 scheme (the default)
> >
> > In addition, we now correctly set the device-tree entry 'mmu-type' using
> > those new properties.
> >
> > Co-Developed-by: Ludovic Henry 
> > Signed-off-by: Ludovic Henry 
> > Signed-off-by: Alexandre Ghiti 
> > ---
> >  hw/riscv/virt.c|  19 ++--
> >  target/riscv/cpu.c | 221 +
> >  target/riscv/cpu.h |  19 
> >  target/riscv/csr.c |  17 +++-
> >  4 files changed, 262 insertions(+), 14 deletions(-)
> >
> > diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> > index 94ff2a1584..48d034a5f7 100644
> > --- a/hw/riscv/virt.c
> > +++ b/hw/riscv/virt.c
> > @@ -228,7 +228,8 @@ static void create_fdt_socket_cpus(RISCVVirtState *s, 
> > int socket,
> >  int cpu;
> >  uint32_t cpu_phandle;
> >  MachineState *mc = MACHINE(s);
> > -char *name, *cpu_name, *core_name, *intc_name;
> > +uint8_t satp_mode_max;
> > +char *name, *cpu_name, *core_name, *intc_name, *sv_name;
> >
> >  for (cpu = s->soc[socket].num_harts - 1; cpu >= 0; cpu--) {
> >  cpu_phandle = (*phandle)++;
> > @@ -236,14 +237,14 @@ static void create_fdt_socket_cpus(RISCVVirtState *s, 
> > int socket,
> >  cpu_name = g_strdup_printf("/cpus/cpu@%d",
> >  s->soc[socket].hartid_base + cpu);
> >  qemu_fdt_add_subnode(mc->fdt, cpu_name);
> > -if (riscv_feature(>soc[socket].harts[cpu].env,
> > -  RISCV_FEATURE_MMU)) {
> > -qemu_fdt_setprop_string(mc->fdt, cpu_name, "mmu-type",
> > -(is_32_bit) ? "riscv,sv32" : 
> > "riscv,sv48");
>
> I just noticed that for the virt machine type, when the user doesn't
> provide a satp mode cpu property on the command line, and hence gets
> the default mode, they'll be silently changed from sv48 to sv57. That
> default change should be a separate patch which comes after this one.
> BTW, why sv57 and not sv48 or sv64?
>
> > -} else {
> > -qemu_fdt_setprop_string(mc->fdt, cpu_name, "mmu-type",
> > -"riscv,none");
> > -}
> > +
> > +satp_mode_max = satp_mode_max_from_map(
> > +s->soc[socket].harts[cpu].cfg.satp_mode.map);
> > +sv_name = g_strdup_printf("riscv,%s",
> > +  satp_mode_str(satp_mode_max, is_32_bit));
> > +qemu_fdt_setprop_string(mc->fdt, cpu_name, "mmu-type", sv_name);
> > +g_free(sv_name);
> > +
> >  name = riscv_isa_string(>soc[socket].harts[cpu]);
> >  qemu_fdt_setprop_string(mc->fdt, cpu_name, "riscv,isa", name);
> >  g_free(name);
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index 7181b34f86..1f0d040a80 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -27,6 +27,7 @@
> >  #include "time_helper.h"
> >  #include "exec/exec-all.h"
> >  #include "qapi/error.h"
> > +#include "qapi/visitor.h"
> >  #include "qemu/error-report.h"
> >  #include "hw/qdev-properties.h"
> >  #include "migration/vmstate.h"
> > @@ -229,6 +230,85 @@ static void set_vext_version(CPURISCVState *env, int 
> > vext_ver)
> >  env->vext_ver = vext_ver;
> >  }
> >
> > +static uint8_t satp_mode_from_str(const char *satp_mode_str)
> > +{
> > +if (!strncmp(satp_mode_str, "sv32", 4)) {
> > +return VM_1_10_SV32;
> > +}
> > +
> > +if (!strncmp(satp_mode_str, "sv39", 4)) {
> > +return VM_1_10_SV39;
> > +}
> > +
> > +if (!strncmp(satp_mode_str, "sv48", 4)) {
> > +return VM_1_10_SV48;
> > +   

Re: [PATCH] tcg/riscv: Use tcg_pcrel_diff in tcg_out_ldst

2023-01-17 Thread Alistair Francis
On Wed, Jan 18, 2023 at 9:05 AM Richard Henderson
 wrote:
>
> We failed to update this with the w^x split, so misses the fact
> that true pc-relative offsets are usually small.
>
> Signed-off-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  tcg/riscv/tcg-target.c.inc | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
> index fc0edd811f..01cb67ef7b 100644
> --- a/tcg/riscv/tcg-target.c.inc
> +++ b/tcg/riscv/tcg-target.c.inc
> @@ -599,7 +599,7 @@ static void tcg_out_ldst(TCGContext *s, RISCVInsn opc, 
> TCGReg data,
>  intptr_t imm12 = sextreg(offset, 0, 12);
>
>  if (offset != imm12) {
> -intptr_t diff = offset - (uintptr_t)s->code_ptr;
> +intptr_t diff = tcg_pcrel_diff(s, (void *)offset);
>
>  if (addr == TCG_REG_ZERO && diff == (int32_t)diff) {
>  imm12 = sextreg(diff, 0, 12);
> --
> 2.34.1
>
>



Re: [PATCH v8] xen/pt: reserve PCI slot 2 for Intel igd-passthru

2023-01-17 Thread Chuck Zmudzinski
On 1/17/2023 6:04 AM, Igor Mammedov wrote:
> On Mon, 16 Jan 2023 13:00:53 -0500
> Chuck Zmudzinski  wrote:
>
> > On 1/16/23 10:33, Igor Mammedov wrote:
> > > On Fri, 13 Jan 2023 16:31:26 -0500
> > > Chuck Zmudzinski  wrote:
> > >   
> > >> On 1/13/23 4:33 AM, Igor Mammedov wrote:  
> > >> > On Thu, 12 Jan 2023 23:14:26 -0500
> > >> > Chuck Zmudzinski  wrote:
> > >> > 
> > >> >> On 1/12/23 6:03 PM, Michael S. Tsirkin wrote:
> > >> >> > On Thu, Jan 12, 2023 at 10:55:25PM +, Bernhard Beschow wrote:   
> > >> >> >
> > >> >> >> I think the change Michael suggests is very minimalistic: Move the 
> > >> >> >> if
> > >> >> >> condition around xen_igd_reserve_slot() into the function itself 
> > >> >> >> and
> > >> >> >> always call it there unconditionally -- basically turning three 
> > >> >> >> lines
> > >> >> >> into one. Since xen_igd_reserve_slot() seems very problem specific,
> > >> >> >> Michael further suggests to rename it to something more general. 
> > >> >> >> All
> > >> >> >> in all no big changes required.  
> > >> >> > 
> > >> >> > yes, exactly.
> > >> >> >   
> > >> >> 
> > >> >> OK, got it. I can do that along with the other suggestions.
> > >> > 
> > >> > have you considered instead of reservation, putting a slot check in 
> > >> > device model
> > >> > and if it's intel igd being passed through, fail at realize time  if 
> > >> > it can't take
> > >> > required slot (with a error directing user to fix command line)?
> > >> 
> > >> Yes, but the core pci code currently already fails at realize time
> > >> with a useful error message if the user tries to use slot 2 for the
> > >> igd, because of the xen platform device which has slot 2. The user
> > >> can fix this without patching qemu, but having the user fix it on
> > >> the command line is not the best way to solve the problem, primarily
> > >> because the user would need to hotplug the xen platform device via a
> > >> command line option instead of having the xen platform device added by
> > >> pc_xen_hvm_init functions almost immediately after creating the pci
> > >> bus, and that delay in adding the xen platform device degrades
> > >> startup performance of the guest.
> > >>   
> > >> > That could be less complicated than dealing with slot reservations at 
> > >> > the cost of
> > >> > being less convenient.
> > >> 
> > >> And also a cost of reduced startup performance  
> > > 
> > > Could you clarify how it affects performance (and how much).
> > > (as I see, setup done at board_init time is roughly the same
> > > as with '-device foo' CLI options, modulo time needed to parse
> > > options which should be negligible. and both ways are done before
> > > guest runs)  
> > 
> > I preface my answer by saying there is a v9, but you don't
> > need to look at that. I will answer all your questions here.
> > 
> > I am going by what I observe on the main HDMI display with the
> > different approaches. With the approach of not patching Qemu
> > to fix this, which requires adding the Xen platform device a
> > little later, the length of time it takes to fully load the
> > guest is increased. I also noticed with Linux guests that use
> > the grub bootoader, the grub vga driver cannot display the
> > grub boot menu at the native resolution of the display, which
> > in the tested case is 1920x1080, when the Xen platform device
> > is added via a command line option instead of by the
> > pc_xen_hvm_init_pci fucntion in pc_piix.c, but with this patch
> > to Qemu, the grub menu is displayed at the full, 1920x1080
> > native resolution of the display. Once the guest fully loads,
> > there is no noticeable difference in performance. It is mainly
> > a degradation in startup performance, not performance once
> > the guest OS is fully loaded.
>
> Looking at igd-assign.txt, it recommends to add IGD using '-device' CLI
> option, and actually drop at least graphics defaults explicitly.
> So it is expected to work fine even when IGD is constructed with
> '-device'.
>
> Could you provide full CLI current xen starts QEMU with and then
> a CLI you used (with explicit -device for IGD) that leads
> to reduced performance?
>
> CCing vfio folks who might have an idea what could be wrong based
> on vfio experience.

Actually, the igd is not added with an explicit -device option using Xen:

   1573 ?    Ssl    0:42 /usr/bin/qemu-system-i386 -xen-domid 1 
-no-shutdown -chardev 
socket,id=libxl-cmd,path=/var/run/xen/qmp-libxl-1,server,nowait -mon 
chardev=libxl-cmd,mode=control -chardev 
socket,id=libxenstat-cmd,path=/var/run/xen/qmp-libxenstat-1,server,nowait -mon 
chardev=libxenstat-cmd,mode=control -nodefaults -no-user-config -name windows 
-vnc none -display none -serial pty -boot order=c -smp 4,maxcpus=4 -net none 
-machine xenfv,max-ram-below-4g=3758096384,igd-passthru=on -m 6144 -drive 
file=/dev/loop0,if=ide,index=0,media=disk,format=raw,cache=writeback -drive 

[PATCH] configure: do not quote $PKG_CONFIG

2023-01-17 Thread Mike Frysinger
We should not quote the PKG_CONFIG setting as this deviates from the
canonical upstream behavior that gets integrated with all other build
systems, and deviates from how we treat all other toolchain variables
that we get from the environment.

Ultimately, the point is that it breaks passing custom flags directly
to pkg-config via the env var where this normally works elsewhere,
and it used to work in the past.

Signed-off-by: Mike Frysinger 
---
 configure | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/configure b/configure
index 9e407ce2e3a9..b5a19d1319a5 100755
--- a/configure
+++ b/configure
@@ -369,7 +369,7 @@ windres="${WINDRES-${cross_prefix}windres}"
 windmc="${WINDMC-${cross_prefix}windmc}"
 pkg_config_exe="${PKG_CONFIG-${cross_prefix}pkg-config}"
 query_pkg_config() {
-"${pkg_config_exe}" ${QEMU_PKG_CONFIG_FLAGS} "$@"
+${pkg_config_exe} ${QEMU_PKG_CONFIG_FLAGS} "$@"
 }
 pkg_config=query_pkg_config
 sdl2_config="${SDL2_CONFIG-${cross_prefix}sdl2-config}"
@@ -1430,7 +1430,7 @@ fi
 ##
 # pkg-config probe
 
-if ! has "$pkg_config_exe"; then
+if ! has $pkg_config_exe; then
   error_exit "pkg-config binary '$pkg_config_exe' not found"
 fi
 
-- 
2.39.0




[PATCH] linux-user: fix strace build w/out munlockall

2023-01-17 Thread Mike Frysinger
Signed-off-by: Mike Frysinger 
---
 linux-user/strace.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/linux-user/strace.c b/linux-user/strace.c
index 9ae5a812cd71..f7912ad67f2b 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -1380,6 +1380,7 @@ UNUSED static struct flags termios_lflags[] = {
 FLAG_END,
 };
 
+#ifdef TARGET_NR_mlockall
 UNUSED static struct flags mlockall_flags[] = {
 FLAG_TARGET(MCL_CURRENT),
 FLAG_TARGET(MCL_FUTURE),
@@ -1388,6 +1389,7 @@ UNUSED static struct flags mlockall_flags[] = {
 #endif
 FLAG_END,
 };
+#endif
 
 /* IDs of the various system clocks */
 #define TARGET_CLOCK_REALTIME  0
-- 
2.39.0




[PATCH v3 2/5] hw/arm/aspeed: Replace aspeed_eeprom_init with at24c_eeprom_init

2023-01-17 Thread Peter Delevoryas
aspeed_eeprom_init is an exact copy of at24c_eeprom_init, not needed.

Signed-off-by: Peter Delevoryas 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/arm/aspeed.c | 95 ++---
 1 file changed, 43 insertions(+), 52 deletions(-)

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 1f9799d4321e..c929c61d582a 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -660,15 +660,6 @@ static void g220a_bmc_i2c_init(AspeedMachineState *bmc)
   eeprom_buf);
 }
 
-static void aspeed_eeprom_init(I2CBus *bus, uint8_t addr, uint32_t rsize)
-{
-I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
-DeviceState *dev = DEVICE(i2c_dev);
-
-qdev_prop_set_uint32(dev, "rom-size", rsize);
-i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
-}
-
 static void fp5280g2_bmc_i2c_init(AspeedMachineState *bmc)
 {
 AspeedSoCState *soc = >soc;
@@ -701,7 +692,7 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
 AspeedSoCState *soc = >soc;
 I2CSlave *i2c_mux;
 
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 0), 0x51, 32 * KiB);
+at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 0), 0x51, 32 * KiB);
 
 create_pca9552(soc, 3, 0x61);
 
@@ -714,9 +705,9 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
  0x4a);
 i2c_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 4),
   "pca9546", 0x70);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x52, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x52, 64 * KiB);
 create_pca9552(soc, 4, 0x60);
 
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 5), TYPE_TMP105,
@@ -727,8 +718,8 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
 create_pca9552(soc, 5, 0x61);
 i2c_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 5),
   "pca9546", 0x70);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
 
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 6), TYPE_TMP105,
  0x48);
@@ -738,10 +729,10 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
  0x4b);
 i2c_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 6),
   "pca9546", 0x70);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x50, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 3), 0x51, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x50, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 3), 0x51, 64 * KiB);
 
 create_pca9552(soc, 7, 0x30);
 create_pca9552(soc, 7, 0x31);
@@ -754,15 +745,15 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 7), TYPE_TMP105,
  0x48);
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 7), "max31785", 
0x52);
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 7), 0x50, 64 * KiB);
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 7), 0x51, 64 * KiB);
+at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 7), 0x50, 64 * KiB);
+at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 7), 0x51, 64 * KiB);
 
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 8), TYPE_TMP105,
  0x48);
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 8), TYPE_TMP105,
  0x4a);
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 8), 0x50, 64 * KiB);
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 8), 0x51, 64 * KiB);
+at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 8), 0x50, 64 * KiB);
+at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 8), 0x51, 64 * KiB);
 create_pca9552(soc, 8, 0x60);
 create_pca9552(soc, 8, 0x61);
 /* Bus 8: ucd90320@11 */
@@ -771,11 +762,11 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
 
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 9), "tmp423", 0x4c);
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 9), "tmp423", 0x4d);
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 9), 0x50, 128 * KiB);
+

[PATCH v3 4/5] hw/arm/aspeed: Add aspeed_eeprom.c

2023-01-17 Thread Peter Delevoryas
- Create aspeed_eeprom.c and aspeed_eeprom.h
- Include aspeed_eeprom.c in CONFIG_ASPEED meson source files
- Include aspeed_eeprom.h in aspeed.c
- Add fby35_bmc_fruid data
- Use new at24c_eeprom_init_rom helper to initialize BMC FRUID EEPROM with data
  from aspeed_eeprom.c

wget 
https://github.com/facebook/openbmc/releases/download/openbmc-e2294ff5d31d/fby35.mtd
qemu-system-aarch64 -machine fby35-bmc -nographic -mtdblock fby35.mtd
...
user: root
pass: 0penBmc
...
root@bmc-oob:~# fruid-util bb

FRU Information   : Baseboard
---   : --
Chassis Type  : Rack Mount Chassis
Chassis Part Number   : N/A
Chassis Serial Number : N/A
Board Mfg Date: Fri Jan  7 10:30:00 2022
Board Mfg : XX
Board Product : Management Board wBMC
Board Serial  : X
Board Part Number : XX
Board FRU ID  : 1.0
Board Custom Data 1   : X
Board Custom Data 2   : XX
Product Manufacturer  : XX
Product Name  : Yosemite V3.5 EVT2
Product Part Number   : XX
Product Version   : EVT2
Product Serial: X
Product Asset Tag : XXX
Product FRU ID: 1.0
Product Custom Data 1 : X
Product Custom Data 2 : N/A
root@bmc-oob:~# fruid-util bmc

FRU Information   : BMC
---   : --
Board Mfg Date: Mon Jan 10 21:42:00 2022
Board Mfg : XX
Board Product : BMC Storage Module
Board Serial  : X
Board Part Number : XX
Board FRU ID  : 1.0
Board Custom Data 1   : X
Board Custom Data 2   : XX
Product Manufacturer  : XX
Product Name  : Yosemite V3.5 EVT2
Product Part Number   : XX
Product Version   : EVT2
Product Serial: X
Product Asset Tag : XXX
Product FRU ID: 1.0
Product Custom Data 1 : X
Product Custom Data 2 : Config A
root@bmc-oob:~# fruid-util nic

FRU Information   : NIC
---   : --
Board Mfg Date: Tue Nov  2 08:51:00 2021
Board Mfg : 
Board Product : Mellanox ConnectX-6 DX OCP3.0
Board Serial  : 
Board Part Number : X
Board FRU ID  : FRU Ver 0.02
Product Manufacturer  : 
Product Name  : Mellanox ConnectX-6 DX OCP3.0
Product Part Number   : X
Product Version   : A9
Product Serial: 
Product Custom Data 3 : ConnectX-6 DX

Signed-off-by: Peter Delevoryas 
Reviewed-by: Cédric Le Goater 
---
 hw/arm/aspeed.c | 10 +++--
 hw/arm/aspeed_eeprom.c  | 78 +
 hw/arm/aspeed_eeprom.h  | 16 +++
 hw/arm/meson.build  |  1 +
 include/hw/nvram/eeprom_at24c.h | 14 ++
 5 files changed, 116 insertions(+), 3 deletions(-)
 create mode 100644 hw/arm/aspeed_eeprom.c
 create mode 100644 hw/arm/aspeed_eeprom.h

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index c929c61d582a..382965f82c38 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -14,6 +14,7 @@
 #include "hw/arm/boot.h"
 #include "hw/arm/aspeed.h"
 #include "hw/arm/aspeed_soc.h"
+#include "hw/arm/aspeed_eeprom.h"
 #include "hw/i2c/i2c_mux_pca954x.h"
 #include "hw/i2c/smbus_eeprom.h"
 #include "hw/misc/pca9552.h"
@@ -940,9 +941,12 @@ static void fby35_i2c_init(AspeedMachineState *bmc)
 
 at24c_eeprom_init(i2c[4], 0x51, 128 * KiB);
 at24c_eeprom_init(i2c[6], 0x51, 128 * KiB);
-at24c_eeprom_init(i2c[8], 0x50, 32 * KiB);
-at24c_eeprom_init(i2c[11], 0x51, 128 * KiB);
-at24c_eeprom_init(i2c[11], 0x54, 128 * KiB);
+at24c_eeprom_init_rom(i2c[8], 0x50, 32 * KiB, fby35_nic_fruid,
+  sizeof(fby35_nic_fruid));
+at24c_eeprom_init_rom(i2c[11], 0x51, 128 * KiB, fby35_bb_fruid,
+  sizeof(fby35_bb_fruid));
+at24c_eeprom_init_rom(i2c[11], 0x54, 128 * KiB, fby35_bmc_fruid,
+  sizeof(fby35_bmc_fruid));
 
 /*
  * TODO: There is a multi-master i2c connection to an AST1030 MiniBMC on
diff --git a/hw/arm/aspeed_eeprom.c b/hw/arm/aspeed_eeprom.c
new file mode 100644
index ..9d0700d4b709
--- /dev/null
+++ b/hw/arm/aspeed_eeprom.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ */
+
+#include "aspeed_eeprom.h"
+
+const uint8_t fby35_nic_fruid[] = {
+0x01, 0x00, 0x00, 0x01, 0x0f, 0x20, 0x00, 0xcf, 0x01, 0x0e, 0x19, 0xd7,
+0x5e, 0xcf, 0xc8, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xdd,
+0x4d, 0x65, 0x6c, 0x6c, 0x61, 0x6e, 0x6f, 

[PATCH v3 5/5] hw/nvram/eeprom_at24c: Make reset behavior more like hardware

2023-01-17 Thread Peter Delevoryas
EEPROM's are a form of non-volatile memory. After power-cycling an EEPROM,
I would expect the I2C state machine to be reset to default values, but I
wouldn't really expect the memory to change at all.

The current implementation of the at24c EEPROM resets its internal memory on
reset. This matches the specification in docs/devel/reset.rst:

  Cold reset is supported by every resettable object. In QEMU, it means we reset
  to the initial state corresponding to the start of QEMU; this might differ
  from what is a real hardware cold reset. It differs from other resets (like
  warm or bus resets) which may keep certain parts untouched.

But differs from my intuition. For example, if someone writes some information
to an EEPROM, then AC power cycles their board, they would expect the EEPROM to
retain that information. It's very useful to be able to test things like this
in QEMU as well, to verify software instrumentation like determining the cause
of a reboot.

Fixes: 5d8424dbd3e8 ("nvram: add AT24Cx i2c eeprom")
Signed-off-by: Peter Delevoryas 
---
 hw/nvram/eeprom_at24c.c | 22 ++
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
index f8d751fa278d..5074776bff04 100644
--- a/hw/nvram/eeprom_at24c.c
+++ b/hw/nvram/eeprom_at24c.c
@@ -185,18 +185,6 @@ static void at24c_eeprom_realize(DeviceState *dev, Error 
**errp)
 }
 
 ee->mem = g_malloc0(ee->rsize);
-
-}
-
-static
-void at24c_eeprom_reset(DeviceState *state)
-{
-EEPROMState *ee = AT24C_EE(state);
-
-ee->changed = false;
-ee->cur = 0;
-ee->haveaddr = 0;
-
 memset(ee->mem, 0, ee->rsize);
 
 if (ee->init_rom) {
@@ -214,6 +202,16 @@ void at24c_eeprom_reset(DeviceState *state)
 }
 }
 
+static
+void at24c_eeprom_reset(DeviceState *state)
+{
+EEPROMState *ee = AT24C_EE(state);
+
+ee->changed = false;
+ee->cur = 0;
+ee->haveaddr = 0;
+}
+
 static Property at24c_eeprom_props[] = {
 DEFINE_PROP_UINT32("rom-size", EEPROMState, rsize, 0),
 DEFINE_PROP_BOOL("writable", EEPROMState, writable, true),
-- 
2.39.0




[PATCH v3 3/5] hw/nvram/eeprom_at24c: Add init_rom field and at24c_eeprom_init_rom helper

2023-01-17 Thread Peter Delevoryas
Allows users to specify binary data to initialize an EEPROM, allowing users to
emulate data programmed at manufacturing time.

- Added init_rom and init_rom_size attributes to TYPE_AT24C_EE
- Added at24c_eeprom_init_rom helper function to initialize attributes
- If -drive property is provided, it overrides init_rom data

Signed-off-by: Peter Delevoryas 
---
 hw/nvram/eeprom_at24c.c | 37 -
 include/hw/nvram/eeprom_at24c.h |  2 ++
 2 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
index 98857e3626b9..f8d751fa278d 100644
--- a/hw/nvram/eeprom_at24c.c
+++ b/hw/nvram/eeprom_at24c.c
@@ -50,6 +50,9 @@ struct EEPROMState {
 uint8_t *mem;
 
 BlockBackend *blk;
+
+const uint8_t *init_rom;
+uint32_t init_rom_size;
 };
 
 static
@@ -131,19 +134,38 @@ int at24c_eeprom_send(I2CSlave *s, uint8_t data)
 
 I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t rom_size)
 {
-I2CSlave *i2c_dev = i2c_slave_new(TYPE_AT24C_EE, address);
-DeviceState *dev = DEVICE(i2c_dev);
+return at24c_eeprom_init_rom(bus, address, rom_size, NULL, 0);
+}
+
+I2CSlave *at24c_eeprom_init_rom(I2CBus *bus, uint8_t address, uint32_t 
rom_size,
+const uint8_t *init_rom, uint32_t 
init_rom_size)
+{
+EEPROMState *s;
+
+s = AT24C_EE(qdev_new(TYPE_AT24C_EE));
+
+qdev_prop_set_uint8(DEVICE(s), "address", address);
+qdev_prop_set_uint32(DEVICE(s), "rom-size", rom_size);
 
-qdev_prop_set_uint32(dev, "rom-size", rom_size);
-i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
+/* TODO: Model init_rom with QOM properties. */
+s->init_rom = init_rom;
+s->init_rom_size = init_rom_size;
 
-return i2c_dev;
+i2c_slave_realize_and_unref(I2C_SLAVE(s), bus, _abort);
+
+return I2C_SLAVE(s);
 }
 
 static void at24c_eeprom_realize(DeviceState *dev, Error **errp)
 {
 EEPROMState *ee = AT24C_EE(dev);
 
+if (ee->init_rom_size > ee->rsize) {
+error_setg(errp, "%s: init rom is larger than rom: %u > %u",
+   TYPE_AT24C_EE, ee->init_rom_size, ee->rsize);
+return;
+}
+
 if (ee->blk) {
 int64_t len = blk_getlength(ee->blk);
 
@@ -163,6 +185,7 @@ static void at24c_eeprom_realize(DeviceState *dev, Error 
**errp)
 }
 
 ee->mem = g_malloc0(ee->rsize);
+
 }
 
 static
@@ -176,6 +199,10 @@ void at24c_eeprom_reset(DeviceState *state)
 
 memset(ee->mem, 0, ee->rsize);
 
+if (ee->init_rom) {
+memcpy(ee->mem, ee->init_rom, MIN(ee->init_rom_size, ee->rsize));
+}
+
 if (ee->blk) {
 int ret = blk_pread(ee->blk, 0, ee->rsize, ee->mem, 0);
 
diff --git a/include/hw/nvram/eeprom_at24c.h b/include/hw/nvram/eeprom_at24c.h
index 196db309d451..5c9149331144 100644
--- a/include/hw/nvram/eeprom_at24c.h
+++ b/include/hw/nvram/eeprom_at24c.h
@@ -19,5 +19,7 @@
  * @bus, and drop the reference to it (the device is realized).
  */
 I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t rom_size);
+I2CSlave *at24c_eeprom_init_rom(I2CBus *bus, uint8_t address, uint32_t 
rom_size,
+const uint8_t *init_rom, uint32_t 
init_rom_size);
 
 #endif
-- 
2.39.0




[PATCH v3 0/5] hw/nvram/eeprom_at24c: Cleanup + FRUID EEPROM init example

2023-01-17 Thread Peter Delevoryas
v1: https://lore.kernel.org/qemu-devel/20230114170151.87833-1-pe...@pjd.dev/
v2:
- Squashed 3 commits from original series into extract helper commit
- Dropped last 2 commits from original series
- Changed at24c_eeprom_init to return the I2CSlave object
- Added commit to introduce at24c-eeprom "init_rom" attribute
- Added aspeed_eeprom.c and fby35-bmc BMC FRUID EEPROM initialization
- Added commit to change reset behavior for at24c-eeprom (optional)
v3:
- Added doc comments to function headers
- Added fby35 NIC and baseboard EEPROM's (to illustrate 2+ EEPROM's)
- Replaced "extern uint32 fby35_bmc_fruid_size" by adding explicit array
  sizes, e.g. "extern uint8_t fby35_bmc_fruid[200]".
- Fixed Meta Platforms licenses by adding SPDX-License-Identifier for GPL2.
- Moved ee->init_rom initialization code before ee->blk, so that -drive
  property overrides init_rom initialization. This gives more flexibility
  (people can override contents of an AT24C EEPROM using a file for
  debugging/prototyping) while still allowing the init_rom data to be
  specified for a board for default behavior.

Thanks,
Peter

Peter Delevoryas (5):
  hw/arm: Extract at24c_eeprom_init helper from Aspeed and Nuvoton
boards
  hw/arm/aspeed: Replace aspeed_eeprom_init with at24c_eeprom_init
  hw/nvram/eeprom_at24c: Add init_rom field and at24c_eeprom_init_rom
helper
  hw/arm/aspeed: Add aspeed_eeprom.c
  hw/nvram/eeprom_at24c: Make reset behavior more like hardware

 hw/arm/aspeed.c | 109 ++--
 hw/arm/aspeed_eeprom.c  |  78 +++
 hw/arm/aspeed_eeprom.h  |  16 +
 hw/arm/meson.build  |   1 +
 hw/arm/npcm7xx_boards.c |  20 ++
 hw/nvram/eeprom_at24c.c |  59 +
 include/hw/nvram/eeprom_at24c.h |  39 
 7 files changed, 235 insertions(+), 87 deletions(-)
 create mode 100644 hw/arm/aspeed_eeprom.c
 create mode 100644 hw/arm/aspeed_eeprom.h
 create mode 100644 include/hw/nvram/eeprom_at24c.h

-- 
2.39.0




[PATCH v3 1/5] hw/arm: Extract at24c_eeprom_init helper from Aspeed and Nuvoton boards

2023-01-17 Thread Peter Delevoryas
This helper is useful in board initialization because lets users initialize and
realize an EEPROM on an I2C bus with a single function call.

Signed-off-by: Peter Delevoryas 
Reviewed-by: Cédric Le Goater 
---
 hw/arm/aspeed.c | 10 +-
 hw/arm/npcm7xx_boards.c | 20 +---
 hw/nvram/eeprom_at24c.c | 12 
 include/hw/nvram/eeprom_at24c.h | 23 +++
 4 files changed, 41 insertions(+), 24 deletions(-)
 create mode 100644 include/hw/nvram/eeprom_at24c.h

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 55f114ef729f..1f9799d4321e 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -17,6 +17,7 @@
 #include "hw/i2c/i2c_mux_pca954x.h"
 #include "hw/i2c/smbus_eeprom.h"
 #include "hw/misc/pca9552.h"
+#include "hw/nvram/eeprom_at24c.h"
 #include "hw/sensor/tmp105.h"
 #include "hw/misc/led.h"
 #include "hw/qdev-properties.h"
@@ -429,15 +430,6 @@ static void aspeed_machine_init(MachineState *machine)
 arm_load_kernel(ARM_CPU(first_cpu), machine, _board_binfo);
 }
 
-static void at24c_eeprom_init(I2CBus *bus, uint8_t addr, uint32_t rsize)
-{
-I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
-DeviceState *dev = DEVICE(i2c_dev);
-
-qdev_prop_set_uint32(dev, "rom-size", rsize);
-i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
-}
-
 static void palmetto_bmc_i2c_init(AspeedMachineState *bmc)
 {
 AspeedSoCState *soc = >soc;
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
index 6bc6f5d2fe29..9b31207a06e9 100644
--- a/hw/arm/npcm7xx_boards.c
+++ b/hw/arm/npcm7xx_boards.c
@@ -21,6 +21,7 @@
 #include "hw/i2c/i2c_mux_pca954x.h"
 #include "hw/i2c/smbus_eeprom.h"
 #include "hw/loader.h"
+#include "hw/nvram/eeprom_at24c.h"
 #include "hw/qdev-core.h"
 #include "hw/qdev-properties.h"
 #include "qapi/error.h"
@@ -140,17 +141,6 @@ static I2CBus *npcm7xx_i2c_get_bus(NPCM7xxState *soc, 
uint32_t num)
 return I2C_BUS(qdev_get_child_bus(DEVICE(>smbus[num]), "i2c-bus"));
 }
 
-static void at24c_eeprom_init(NPCM7xxState *soc, int bus, uint8_t addr,
-  uint32_t rsize)
-{
-I2CBus *i2c_bus = npcm7xx_i2c_get_bus(soc, bus);
-I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
-DeviceState *dev = DEVICE(i2c_dev);
-
-qdev_prop_set_uint32(dev, "rom-size", rsize);
-i2c_slave_realize_and_unref(i2c_dev, i2c_bus, _abort);
-}
-
 static void npcm7xx_init_pwm_splitter(NPCM7xxMachine *machine,
   NPCM7xxState *soc, const int *fan_counts)
 {
@@ -253,8 +243,8 @@ static void quanta_gsj_i2c_init(NPCM7xxState *soc)
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 3), "tmp105", 0x5c);
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 4), "tmp105", 0x5c);
 
-at24c_eeprom_init(soc, 9, 0x55, 8192);
-at24c_eeprom_init(soc, 10, 0x55, 8192);
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 9), 0x55, 8192);
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 10), 0x55, 8192);
 
 /*
  * i2c-11:
@@ -360,7 +350,7 @@ static void kudo_bmc_i2c_init(NPCM7xxState *soc)
 
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 4), TYPE_PCA9548, 0x77);
 
-at24c_eeprom_init(soc, 4, 0x50, 8192); /* mbfru */
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 4), 0x50, 8192); /* mbfru */
 
 i2c_mux = i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 13),
   TYPE_PCA9548, 0x77);
@@ -371,7 +361,7 @@ static void kudo_bmc_i2c_init(NPCM7xxState *soc)
 i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 4), "tmp105", 0x48);
 i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 5), "tmp105", 0x49);
 
-at24c_eeprom_init(soc, 14, 0x55, 8192); /* bmcfru */
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 14), 0x55, 8192); /* bmcfru */
 
 /* TODO: Add remaining i2c devices. */
 }
diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
index 2d4d8b952f38..98857e3626b9 100644
--- a/hw/nvram/eeprom_at24c.c
+++ b/hw/nvram/eeprom_at24c.c
@@ -12,6 +12,7 @@
 #include "qapi/error.h"
 #include "qemu/module.h"
 #include "hw/i2c/i2c.h"
+#include "hw/nvram/eeprom_at24c.h"
 #include "hw/qdev-properties.h"
 #include "hw/qdev-properties-system.h"
 #include "sysemu/block-backend.h"
@@ -128,6 +129,17 @@ int at24c_eeprom_send(I2CSlave *s, uint8_t data)
 return 0;
 }
 
+I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t rom_size)
+{
+I2CSlave *i2c_dev = i2c_slave_new(TYPE_AT24C_EE, address);
+DeviceState *dev = DEVICE(i2c_dev);
+
+qdev_prop_set_uint32(dev, "rom-size", rom_size);
+i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
+
+return i2c_dev;
+}
+
 static void at24c_eeprom_realize(DeviceState *dev, Error **errp)
 {
 EEPROMState *ee = AT24C_EE(dev);
diff --git a/include/hw/nvram/eeprom_at24c.h b/include/hw/nvram/eeprom_at24c.h
new file mode 100644
index ..196db309d451
--- /dev/null
+++ b/include/hw/nvram/eeprom_at24c.h
@@ -0,0 +1,23 @@
+/*
+ * 

[PULL 19/22] tcg/sparc64: Reorg goto_tb implementation

2023-01-17 Thread Richard Henderson
The old sparc64 implementation may replace two insns, which leaves
a race condition in which a thread could be stopped at a PC in the
middle of the sequence, and when restarted does not see the complete
address computation and branches to nowhere.

The new implemetation replaces only one insn, swapping between a
direct branch and a direct call.  The TCG_REG_TB register is loaded
from tb->jmp_target_addr[] in the delay slot.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 tcg/sparc64/tcg-target.c.inc | 87 +++-
 1 file changed, 37 insertions(+), 50 deletions(-)

diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
index e0b3957149..dd406bc065 100644
--- a/tcg/sparc64/tcg-target.c.inc
+++ b/tcg/sparc64/tcg-target.c.inc
@@ -1436,33 +1436,56 @@ static void tcg_out_exit_tb(TCGContext *s, uintptr_t a0)
 
 static void tcg_out_goto_tb(TCGContext *s, int which)
 {
-int c;
+ptrdiff_t off = tcg_tbrel_diff(s, (void *)get_jmp_target_addr(s, which));
 
-/* Direct jump. */
-/* make sure the patch is 8-byte aligned.  */
-if ((intptr_t)s->code_ptr & 4) {
-tcg_out_nop(s);
-}
+/* Direct branch will be patched by tb_target_set_jmp_target. */
 set_jmp_insn_offset(s, which);
-tcg_out_sethi(s, TCG_REG_T1, 0);
-tcg_out_arithi(s, TCG_REG_T1, TCG_REG_T1, 0, ARITH_OR);
-tcg_out_arith(s, TCG_REG_G0, TCG_REG_TB, TCG_REG_T1, JMPL);
-tcg_out_arith(s, TCG_REG_TB, TCG_REG_TB, TCG_REG_T1, ARITH_ADD);
+tcg_out32(s, CALL);
+/* delay slot */
+tcg_debug_assert(check_fit_ptr(off, 13));
+tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TB, TCG_REG_TB, off);
 set_jmp_reset_offset(s, which);
 
 /*
  * For the unlinked path of goto_tb, we need to reset TCG_REG_TB
  * to the beginning of this TB.
  */
-c = -tcg_current_code_size(s);
-if (check_fit_i32(c, 13)) {
-tcg_out_arithi(s, TCG_REG_TB, TCG_REG_TB, c, ARITH_ADD);
+off = -tcg_current_code_size(s);
+if (check_fit_i32(off, 13)) {
+tcg_out_arithi(s, TCG_REG_TB, TCG_REG_TB, off, ARITH_ADD);
 } else {
-tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_T1, c);
+tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_T1, off);
 tcg_out_arith(s, TCG_REG_TB, TCG_REG_TB, TCG_REG_T1, ARITH_ADD);
 }
 }
 
+void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
+  uintptr_t jmp_rx, uintptr_t jmp_rw)
+{
+uintptr_t addr = tb->jmp_target_addr[n];
+intptr_t br_disp = (intptr_t)(addr - jmp_rx) >> 2;
+tcg_insn_unit insn;
+
+br_disp >>= 2;
+if (check_fit_ptr(br_disp, 19)) {
+/* ba,pt %icc, addr */
+insn = deposit32(INSN_OP(0) | INSN_OP2(1) | INSN_COND(COND_A)
+ | BPCC_ICC | BPCC_PT, 0, 19, br_disp);
+} else if (check_fit_ptr(br_disp, 22)) {
+/* ba addr */
+insn = deposit32(INSN_OP(0) | INSN_OP2(2) | INSN_COND(COND_A),
+ 0, 22, br_disp);
+} else {
+/* The code_gen_buffer can't be larger than 2GB.  */
+tcg_debug_assert(check_fit_ptr(br_disp, 30));
+/* call addr */
+insn = deposit32(CALL, 0, 30, br_disp);
+}
+
+qatomic_set((uint32_t *)jmp_rw, insn);
+flush_idcache_range(jmp_rx, jmp_rw, 4);
+}
+
 static void tcg_out_op(TCGContext *s, TCGOpcode opc,
const TCGArg args[TCG_MAX_OP_ARGS],
const int const_args[TCG_MAX_OP_ARGS])
@@ -1871,39 +1894,3 @@ void tcg_register_jit(const void *buf, size_t buf_size)
 {
 tcg_register_jit_int(buf, buf_size, _frame, sizeof(debug_frame));
 }
-
-void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
-  uintptr_t jmp_rx, uintptr_t jmp_rw)
-{
-uintptr_t addr = tb->jmp_target_addr[n];
-intptr_t tb_disp = addr - (uintptr_t)tb->tc.ptr;
-intptr_t br_disp = addr - jmp_rx;
-tcg_insn_unit i1, i2;
-
-/* We can reach the entire address space for ILP32.
-   For LP64, the code_gen_buffer can't be larger than 2GB.  */
-tcg_debug_assert(tb_disp == (int32_t)tb_disp);
-tcg_debug_assert(br_disp == (int32_t)br_disp);
-
-/* This does not exercise the range of the branch, but we do
-   still need to be able to load the new value of TCG_REG_TB.
-   But this does still happen quite often.  */
-if (check_fit_ptr(tb_disp, 13)) {
-/* ba,pt %icc, addr */
-i1 = (INSN_OP(0) | INSN_OP2(1) | INSN_COND(COND_A)
-  | BPCC_ICC | BPCC_PT | INSN_OFF19(br_disp));
-i2 = (ARITH_ADD | INSN_RD(TCG_REG_TB) | INSN_RS1(TCG_REG_TB)
-  | INSN_IMM13(tb_disp));
-} else if (tb_disp >= 0) {
-i1 = SETHI | INSN_RD(TCG_REG_T1) | ((tb_disp & 0xfc00) >> 10);
-i2 = (ARITH_OR | INSN_RD(TCG_REG_T1) | INSN_RS1(TCG_REG_T1)
-  | INSN_IMM13(tb_disp & 0x3ff));
-} else {
-i1 = SETHI | INSN_RD(TCG_REG_T1) | ((~tb_disp & 0xfc00) >> 10);
-i2 = 

[PULL 10/22] tcg: Add gen_tb to TCGContext

2023-01-17 Thread Richard Henderson
This can replace four other variables that are references
into the TranslationBlock structure.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 include/tcg/tcg.h | 11 +++
 accel/tcg/translate-all.c |  2 +-
 tcg/tcg-op.c  | 14 +++---
 tcg/tcg.c | 14 +++---
 4 files changed, 14 insertions(+), 27 deletions(-)

diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
index b949d75fdd..c2d5430b5a 100644
--- a/include/tcg/tcg.h
+++ b/include/tcg/tcg.h
@@ -552,20 +552,15 @@ struct TCGContext {
 int nb_indirects;
 int nb_ops;
 
-/* goto_tb support */
-tcg_insn_unit *code_buf;
-uint16_t *tb_jmp_reset_offset; /* tb->jmp_reset_offset */
-uintptr_t *tb_jmp_insn_offset; /* tb->jmp_target_arg if direct_jump */
-uintptr_t *tb_jmp_target_addr; /* tb->jmp_target_arg if !direct_jump */
-
 TCGRegSet reserved_regs;
-uint32_t tb_cflags; /* cflags of the current TB */
 intptr_t current_frame_offset;
 intptr_t frame_start;
 intptr_t frame_end;
 TCGTemp *frame_temp;
 
-tcg_insn_unit *code_ptr;
+TranslationBlock *gen_tb; /* tb for which code is being generated */
+tcg_insn_unit *code_buf;  /* pointer for start of tb */
+tcg_insn_unit *code_ptr;  /* pointer for running end of tb */
 
 #ifdef CONFIG_PROFILER
 TCGProfile prof;
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index a4fdce5b72..9e925c10f3 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -350,7 +350,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
 tb->trace_vcpu_dstate = *cpu->trace_dstate;
 tb_set_page_addr0(tb, phys_pc);
 tb_set_page_addr1(tb, -1);
-tcg_ctx->tb_cflags = cflags;
+tcg_ctx->gen_tb = tb;
  tb_overflow:
 
 #ifdef CONFIG_PROFILER
diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
index cd1cd4e736..9fa9f1b0fd 100644
--- a/tcg/tcg-op.c
+++ b/tcg/tcg-op.c
@@ -86,7 +86,7 @@ void tcg_gen_op6(TCGOpcode opc, TCGArg a1, TCGArg a2, TCGArg 
a3,
 
 void tcg_gen_mb(TCGBar mb_type)
 {
-if (tcg_ctx->tb_cflags & CF_PARALLEL) {
+if (tcg_ctx->gen_tb->cflags & CF_PARALLEL) {
 tcg_gen_op1(INDEX_op_mb, mb_type);
 }
 }
@@ -2782,7 +2782,7 @@ void tcg_gen_exit_tb(const TranslationBlock *tb, unsigned 
idx)
 void tcg_gen_goto_tb(unsigned idx)
 {
 /* We tested CF_NO_GOTO_TB in translator_use_goto_tb. */
-tcg_debug_assert(!(tcg_ctx->tb_cflags & CF_NO_GOTO_TB));
+tcg_debug_assert(!(tcg_ctx->gen_tb->cflags & CF_NO_GOTO_TB));
 /* We only support two chained exits.  */
 tcg_debug_assert(idx <= TB_EXIT_IDXMAX);
 #ifdef CONFIG_DEBUG_TCG
@@ -2798,7 +2798,7 @@ void tcg_gen_lookup_and_goto_ptr(void)
 {
 TCGv_ptr ptr;
 
-if (tcg_ctx->tb_cflags & CF_NO_GOTO_PTR) {
+if (tcg_ctx->gen_tb->cflags & CF_NO_GOTO_PTR) {
 tcg_gen_exit_tb(NULL, 0);
 return;
 }
@@ -3165,7 +3165,7 @@ void tcg_gen_atomic_cmpxchg_i32(TCGv_i32 retv, TCGv addr, 
TCGv_i32 cmpv,
 {
 memop = tcg_canonicalize_memop(memop, 0, 0);
 
-if (!(tcg_ctx->tb_cflags & CF_PARALLEL)) {
+if (!(tcg_ctx->gen_tb->cflags & CF_PARALLEL)) {
 TCGv_i32 t1 = tcg_temp_new_i32();
 TCGv_i32 t2 = tcg_temp_new_i32();
 
@@ -3203,7 +3203,7 @@ void tcg_gen_atomic_cmpxchg_i64(TCGv_i64 retv, TCGv addr, 
TCGv_i64 cmpv,
 {
 memop = tcg_canonicalize_memop(memop, 1, 0);
 
-if (!(tcg_ctx->tb_cflags & CF_PARALLEL)) {
+if (!(tcg_ctx->gen_tb->cflags & CF_PARALLEL)) {
 TCGv_i64 t1 = tcg_temp_new_i64();
 TCGv_i64 t2 = tcg_temp_new_i64();
 
@@ -3364,7 +3364,7 @@ static void * const table_##NAME[(MO_SIZE | MO_BSWAP) + 
1] = {  \
 void tcg_gen_atomic_##NAME##_i32\
 (TCGv_i32 ret, TCGv addr, TCGv_i32 val, TCGArg idx, MemOp memop)\
 {   \
-if (tcg_ctx->tb_cflags & CF_PARALLEL) { \
+if (tcg_ctx->gen_tb->cflags & CF_PARALLEL) {\
 do_atomic_op_i32(ret, addr, val, idx, memop, table_##NAME); \
 } else {\
 do_nonatomic_op_i32(ret, addr, val, idx, memop, NEW,\
@@ -3374,7 +3374,7 @@ void tcg_gen_atomic_##NAME##_i32  
  \
 void tcg_gen_atomic_##NAME##_i64\
 (TCGv_i64 ret, TCGv addr, TCGv_i64 val, TCGArg idx, MemOp memop)\
 {   \
-if (tcg_ctx->tb_cflags & CF_PARALLEL) { \
+if (tcg_ctx->gen_tb->cflags & CF_PARALLEL) {\
 do_atomic_op_i64(ret, addr, val, idx, memop, table_##NAME); \
 } else {\
 do_nonatomic_op_i64(ret, addr, val, idx, memop, NEW,\
diff --git a/tcg/tcg.c 

[PULL 06/22] tcg: Introduce set_jmp_insn_offset

2023-01-17 Thread Richard Henderson
Similar to the existing set_jmp_reset_offset.  Move any assert for
TCG_TARGET_HAS_direct_jump into the new function (which now cannot
be build-time).  Will be unused if TCG_TARGET_HAS_direct_jump is
constant 0, but we can't test for constant in the preprocessor,
so just mark it G_GNUC_UNUSED.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 tcg/tcg.c| 10 ++
 tcg/aarch64/tcg-target.c.inc |  3 +--
 tcg/i386/tcg-target.c.inc|  3 +--
 tcg/loongarch64/tcg-target.c.inc |  3 +--
 tcg/ppc/tcg-target.c.inc |  7 +++
 tcg/s390x/tcg-target.c.inc   |  2 +-
 tcg/sparc64/tcg-target.c.inc |  5 ++---
 7 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 257479337c..4092dac294 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -313,6 +313,16 @@ static void set_jmp_reset_offset(TCGContext *s, int which)
 s->tb_jmp_reset_offset[which] = tcg_current_code_size(s);
 }
 
+static void G_GNUC_UNUSED set_jmp_insn_offset(TCGContext *s, int which)
+{
+/*
+ * We will check for overflow at the end of the opcode loop in
+ * tcg_gen_code, where we bound tcg_current_code_size to UINT16_MAX.
+ */
+tcg_debug_assert(TCG_TARGET_HAS_direct_jump);
+s->tb_jmp_insn_offset[which] = tcg_current_code_size(s);
+}
+
 /* Signal overflow, starting over with fewer guest insns. */
 static G_NORETURN
 void tcg_raise_tb_overflow(TCGContext *s)
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
index 90af096c11..59e6a08e93 100644
--- a/tcg/aarch64/tcg-target.c.inc
+++ b/tcg/aarch64/tcg-target.c.inc
@@ -1918,7 +1918,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 
 switch (opc) {
 case INDEX_op_goto_tb:
-qemu_build_assert(TCG_TARGET_HAS_direct_jump);
 /*
  * Ensure that ADRP+ADD are 8-byte aligned so that an atomic
  * write can be used to patch the target address.
@@ -1926,7 +1925,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 if ((uintptr_t)s->code_ptr & 7) {
 tcg_out32(s, NOP);
 }
-s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s);
+set_jmp_insn_offset(s, a0);
 /*
  * actual branch destination will be patched by
  * tb_target_set_jmp_target later
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
index c4ff59e9ee..6fb40fe8ba 100644
--- a/tcg/i386/tcg-target.c.inc
+++ b/tcg/i386/tcg-target.c.inc
@@ -2383,7 +2383,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode 
opc,
 
 switch (opc) {
 case INDEX_op_goto_tb:
-qemu_build_assert(TCG_TARGET_HAS_direct_jump);
 {
 /*
  * Jump displacement must be aligned for atomic patching;
@@ -2394,7 +2393,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode 
opc,
 tcg_out_nopn(s, gap - 1);
 }
 tcg_out8(s, OPC_JMP_long); /* jmp im */
-s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s);
+set_jmp_insn_offset(s, a0);
 tcg_out32(s, 0);
 }
 set_jmp_reset_offset(s, a0);
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 5dd645fd17..bce7340604 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -1090,7 +1090,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 
 switch (opc) {
 case INDEX_op_goto_tb:
-qemu_build_assert(TCG_TARGET_HAS_direct_jump);
 /*
  * Ensure that patch area is 8-byte aligned so that an
  * atomic write can be used to patch the target address.
@@ -1098,7 +1097,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 if ((uintptr_t)s->code_ptr & 7) {
 tcg_out_nop(s);
 }
-s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s);
+set_jmp_insn_offset(s, a0);
 /*
  * actual branch destination will be patched by
  * tb_target_set_jmp_target later
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
index b72e266990..dbe8ccd353 100644
--- a/tcg/ppc/tcg-target.c.inc
+++ b/tcg/ppc/tcg-target.c.inc
@@ -2630,20 +2630,19 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 
 switch (opc) {
 case INDEX_op_goto_tb:
-qemu_build_assert(TCG_TARGET_HAS_direct_jump);
 /* Direct jump. */
 if (TCG_TARGET_REG_BITS == 64) {
 /* Ensure the next insns are 8 or 16-byte aligned. */
 while ((uintptr_t)s->code_ptr & (have_isa_2_07 ? 15 : 7)) {
 tcg_out32(s, NOP);
 }
-s->tb_jmp_insn_offset[args[0]] = tcg_current_code_size(s);
+set_jmp_insn_offset(s, args[0]);
 tcg_out32(s, ADDIS | TAI(TCG_REG_TB, TCG_REG_TB, 0));
 tcg_out32(s, ADDI | TAI(TCG_REG_TB, TCG_REG_TB, 0));
 } else {
-s->tb_jmp_insn_offset[args[0]] = tcg_current_code_size(s);

[PULL 13/22] tcg: Move tb_target_set_jmp_target declaration to tcg.h

2023-01-17 Thread Richard Henderson
Reviewed-by: Alex Bennée 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 include/tcg/tcg.h| 3 +++
 tcg/aarch64/tcg-target.h | 4 
 tcg/arm/tcg-target.h | 5 -
 tcg/i386/tcg-target.h| 3 ---
 tcg/loongarch64/tcg-target.h | 3 ---
 tcg/mips/tcg-target.h| 5 -
 tcg/ppc/tcg-target.h | 4 
 tcg/riscv/tcg-target.h   | 4 
 tcg/s390x/tcg-target.h   | 4 
 tcg/sparc64/tcg-target.h | 4 
 tcg/tci/tcg-target.h | 4 
 11 files changed, 3 insertions(+), 40 deletions(-)

diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
index c2d5430b5a..6f497172f8 100644
--- a/include/tcg/tcg.h
+++ b/include/tcg/tcg.h
@@ -833,6 +833,9 @@ void tcg_func_start(TCGContext *s);
 
 int tcg_gen_code(TCGContext *s, TranslationBlock *tb, target_ulong pc_start);
 
+void tb_target_set_jmp_target(const TranslationBlock *, int,
+  uintptr_t, uintptr_t);
+
 void tcg_set_frame(TCGContext *s, TCGReg reg, intptr_t start, intptr_t size);
 
 TCGTemp *tcg_global_mem_new_internal(TCGType, TCGv_ptr,
diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
index d491c198da..a585d035d9 100644
--- a/tcg/aarch64/tcg-target.h
+++ b/tcg/aarch64/tcg-target.h
@@ -151,10 +151,6 @@ typedef enum {
 
 #define TCG_TARGET_DEFAULT_MO (0)
 #define TCG_TARGET_HAS_MEMORY_BSWAP 0
-
-void tb_target_set_jmp_target(const TranslationBlock *, int,
-  uintptr_t, uintptr_t);
-
 #define TCG_TARGET_NEED_LDST_LABELS
 #define TCG_TARGET_NEED_POOL_LABELS
 
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
index 4c1433093c..d347a5dc53 100644
--- a/tcg/arm/tcg-target.h
+++ b/tcg/arm/tcg-target.h
@@ -150,11 +150,6 @@ extern bool use_neon_instructions;
 
 #define TCG_TARGET_DEFAULT_MO (0)
 #define TCG_TARGET_HAS_MEMORY_BSWAP 0
-
-/* not defined -- call should be eliminated at compile time */
-void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
-  uintptr_t, uintptr_t);
-
 #define TCG_TARGET_NEED_LDST_LABELS
 #define TCG_TARGET_NEED_POOL_LABELS
 
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index 7500ceaab9..d3705da2ed 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -220,9 +220,6 @@ extern bool have_movbe;
 #define TCG_TARGET_extract_i64_valid(ofs, len) \
 (((ofs) == 8 && (len) == 8) || ((ofs) + (len)) == 32)
 
-void tb_target_set_jmp_target(const TranslationBlock *, int,
-  uintptr_t, uintptr_t);
-
 /* This defines the natural memory order supported by this
  * architecture before guarantees made by various barrier
  * instructions.
diff --git a/tcg/loongarch64/tcg-target.h b/tcg/loongarch64/tcg-target.h
index a150c3c7b2..5782c6887c 100644
--- a/tcg/loongarch64/tcg-target.h
+++ b/tcg/loongarch64/tcg-target.h
@@ -171,9 +171,6 @@ typedef enum {
 #define TCG_TARGET_HAS_muluh_i641
 #define TCG_TARGET_HAS_mulsh_i641
 
-void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
-  uintptr_t, uintptr_t);
-
 #define TCG_TARGET_DEFAULT_MO (0)
 
 #define TCG_TARGET_NEED_LDST_LABELS
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
index d1adf3e326..82b40100cf 100644
--- a/tcg/mips/tcg-target.h
+++ b/tcg/mips/tcg-target.h
@@ -205,11 +205,6 @@ extern bool use_mips32r2_instructions;
 #define TCG_TARGET_DEFAULT_MO (0)
 #define TCG_TARGET_HAS_MEMORY_BSWAP 1
 
-/* not defined -- call should be eliminated at compile time */
-void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
-  uintptr_t, uintptr_t)
-QEMU_ERROR("code path is reachable");
-
 #define TCG_TARGET_NEED_LDST_LABELS
 
 #endif
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
index 02764c3331..5ffb41fb57 100644
--- a/tcg/ppc/tcg-target.h
+++ b/tcg/ppc/tcg-target.h
@@ -180,12 +180,8 @@ extern bool have_vsx;
 #define TCG_TARGET_HAS_bitsel_vec   have_vsx
 #define TCG_TARGET_HAS_cmpsel_vec   0
 
-void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
-  uintptr_t, uintptr_t);
-
 #define TCG_TARGET_DEFAULT_MO (0)
 #define TCG_TARGET_HAS_MEMORY_BSWAP 1
-
 #define TCG_TARGET_NEED_LDST_LABELS
 #define TCG_TARGET_NEED_POOL_LABELS
 
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
index bce164fde2..c9af6d592f 100644
--- a/tcg/riscv/tcg-target.h
+++ b/tcg/riscv/tcg-target.h
@@ -165,10 +165,6 @@ typedef enum {
 #define TCG_TARGET_HAS_mulsh_i641
 #endif
 
-/* not defined -- call should be eliminated at compile time */
-void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
-  uintptr_t, uintptr_t);
-
 #define TCG_TARGET_DEFAULT_MO (0)
 
 #define TCG_TARGET_NEED_LDST_LABELS
diff --git a/tcg/s390x/tcg-target.h b/tcg/s390x/tcg-target.h
index 57ba165800..9f5d1cf1c7 100644
--- a/tcg/s390x/tcg-target.h
+++ b/tcg/s390x/tcg-target.h
@@ -174,10 +174,6 

[PULL 04/22] tcg/sparc64: Remove unused goto_tb code for indirect jump

2023-01-17 Thread Richard Henderson
Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 tcg/sparc64/tcg-target.c.inc | 41 +++-
 1 file changed, 12 insertions(+), 29 deletions(-)

diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
index d2d8b46815..26b00d1638 100644
--- a/tcg/sparc64/tcg-target.c.inc
+++ b/tcg/sparc64/tcg-target.c.inc
@@ -537,17 +537,6 @@ static bool tcg_out_sti(TCGContext *s, TCGType type, 
TCGArg val,
 return false;
 }
 
-static void tcg_out_ld_ptr(TCGContext *s, TCGReg ret, const void *arg)
-{
-intptr_t diff = tcg_tbrel_diff(s, arg);
-if (USE_REG_TB && check_fit_ptr(diff, 13)) {
-tcg_out_ld(s, TCG_TYPE_PTR, ret, TCG_REG_TB, diff);
-return;
-}
-tcg_out_movi(s, TCG_TYPE_PTR, ret, (uintptr_t)arg & ~0x3ff);
-tcg_out_ld(s, TCG_TYPE_PTR, ret, ret, (uintptr_t)arg & 0x3ff);
-}
-
 static void tcg_out_sety(TCGContext *s, TCGReg rs)
 {
 tcg_out32(s, WRY | INSN_RS1(TCG_REG_G0) | INSN_RS2(rs));
@@ -1463,27 +1452,21 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 
 switch (opc) {
 case INDEX_op_goto_tb:
-if (s->tb_jmp_insn_offset) {
-/* direct jump method */
-if (USE_REG_TB) {
-/* make sure the patch is 8-byte aligned.  */
-if ((intptr_t)s->code_ptr & 4) {
-tcg_out_nop(s);
-}
-s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s);
-tcg_out_sethi(s, TCG_REG_T1, 0);
-tcg_out_arithi(s, TCG_REG_T1, TCG_REG_T1, 0, ARITH_OR);
-tcg_out_arith(s, TCG_REG_G0, TCG_REG_TB, TCG_REG_T1, JMPL);
-tcg_out_arith(s, TCG_REG_TB, TCG_REG_TB, TCG_REG_T1, 
ARITH_ADD);
-} else {
-s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s);
-tcg_out32(s, CALL);
+qemu_build_assert(TCG_TARGET_HAS_direct_jump);
+/* Direct jump. */
+if (USE_REG_TB) {
+/* make sure the patch is 8-byte aligned.  */
+if ((intptr_t)s->code_ptr & 4) {
 tcg_out_nop(s);
 }
+s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s);
+tcg_out_sethi(s, TCG_REG_T1, 0);
+tcg_out_arithi(s, TCG_REG_T1, TCG_REG_T1, 0, ARITH_OR);
+tcg_out_arith(s, TCG_REG_G0, TCG_REG_TB, TCG_REG_T1, JMPL);
+tcg_out_arith(s, TCG_REG_TB, TCG_REG_TB, TCG_REG_T1, ARITH_ADD);
 } else {
-/* indirect jump method */
-tcg_out_ld_ptr(s, TCG_REG_TB, s->tb_jmp_target_addr + a0);
-tcg_out_arithi(s, TCG_REG_G0, TCG_REG_TB, 0, JMPL);
+s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s);
+tcg_out32(s, CALL);
 tcg_out_nop(s);
 }
 set_jmp_reset_offset(s, a0);
-- 
2.34.1




[PULL 05/22] tcg: Replace asserts on tcg_jmp_insn_offset

2023-01-17 Thread Richard Henderson
Test TCG_TARGET_HAS_direct_jump instead of testing an
implementation pointer.

Reviewed-by: Alex Bennée 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 tcg/aarch64/tcg-target.c.inc | 2 +-
 tcg/arm/tcg-target.c.inc | 2 +-
 tcg/loongarch64/tcg-target.c.inc | 2 +-
 tcg/mips/tcg-target.c.inc| 2 +-
 tcg/riscv/tcg-target.c.inc   | 2 +-
 tcg/tci/tcg-target.c.inc | 2 +-
 6 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
index 501b77c215..90af096c11 100644
--- a/tcg/aarch64/tcg-target.c.inc
+++ b/tcg/aarch64/tcg-target.c.inc
@@ -1918,7 +1918,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 
 switch (opc) {
 case INDEX_op_goto_tb:
-tcg_debug_assert(s->tb_jmp_insn_offset != NULL);
+qemu_build_assert(TCG_TARGET_HAS_direct_jump);
 /*
  * Ensure that ADRP+ADD are 8-byte aligned so that an atomic
  * write can be used to patch the target address.
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
index 799cf13536..033ff90daa 100644
--- a/tcg/arm/tcg-target.c.inc
+++ b/tcg/arm/tcg-target.c.inc
@@ -1953,7 +1953,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 intptr_t ptr, dif, dil;
 TCGReg base = TCG_REG_PC;
 
-tcg_debug_assert(s->tb_jmp_insn_offset == 0);
+qemu_build_assert(!TCG_TARGET_HAS_direct_jump);
 ptr = (intptr_t)tcg_splitwx_to_rx(s->tb_jmp_target_addr + args[0]);
 dif = tcg_pcrel_diff(s, (void *)ptr) - 8;
 dil = sextract32(dif, 0, 12);
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 29e4bfcb49..5dd645fd17 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -1090,7 +1090,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 
 switch (opc) {
 case INDEX_op_goto_tb:
-tcg_debug_assert(s->tb_jmp_insn_offset != NULL);
+qemu_build_assert(TCG_TARGET_HAS_direct_jump);
 /*
  * Ensure that patch area is 8-byte aligned so that an
  * atomic write can be used to patch the target address.
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
index 52881abd35..02887d7cb1 100644
--- a/tcg/mips/tcg-target.c.inc
+++ b/tcg/mips/tcg-target.c.inc
@@ -1987,7 +1987,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 switch (opc) {
 case INDEX_op_goto_tb:
 /* indirect jump method */
-tcg_debug_assert(s->tb_jmp_insn_offset == 0);
+qemu_build_assert(!TCG_TARGET_HAS_direct_jump);
 tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP0, TCG_REG_ZERO,
(uintptr_t)(s->tb_jmp_target_addr + a0));
 tcg_out_opc_reg(s, OPC_JR, 0, TCG_TMP0, 0);
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index 9b42cb4b2e..b977c8025d 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -1311,7 +1311,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 
 switch (opc) {
 case INDEX_op_goto_tb:
-assert(s->tb_jmp_insn_offset == 0);
+qemu_build_assert(!TCG_TARGET_HAS_direct_jump);
 /* indirect jump method */
 tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP0, TCG_REG_ZERO,
(uintptr_t)(s->tb_jmp_target_addr + a0));
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
index 2f3bcce3a7..ad356f1875 100644
--- a/tcg/tci/tcg-target.c.inc
+++ b/tcg/tci/tcg-target.c.inc
@@ -603,7 +603,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 
 switch (opc) {
 case INDEX_op_goto_tb:
-tcg_debug_assert(s->tb_jmp_insn_offset == 0);
+qemu_build_assert(!TCG_TARGET_HAS_direct_jump);
 /* indirect jump method. */
 tcg_out_op_p(s, opc, s->tb_jmp_target_addr + args[0]);
 set_jmp_reset_offset(s, args[0]);
-- 
2.34.1




[PULL 01/22] tcg: Split out tcg_out_exit_tb

2023-01-17 Thread Richard Henderson
The INDEX_op_exit_tb opcode needs no register allocation.
Split out a dedicated helper function for it.

Reviewed-by: Alex Bennée 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 tcg/tcg.c|  4 
 tcg/aarch64/tcg-target.c.inc | 22 ++
 tcg/arm/tcg-target.c.inc | 11 +
 tcg/i386/tcg-target.c.inc| 21 +
 tcg/loongarch64/tcg-target.c.inc | 22 ++
 tcg/mips/tcg-target.c.inc| 33 +--
 tcg/ppc/tcg-target.c.inc | 11 +
 tcg/riscv/tcg-target.c.inc   | 22 ++
 tcg/s390x/tcg-target.c.inc   | 23 ++-
 tcg/sparc64/tcg-target.c.inc | 39 +---
 tcg/tci/tcg-target.c.inc | 10 
 11 files changed, 121 insertions(+), 97 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 9b7df71e7a..257479337c 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -104,6 +104,7 @@ static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg 
ret, TCGReg arg1,
 static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
 static void tcg_out_movi(TCGContext *s, TCGType type,
  TCGReg ret, tcg_target_long arg);
+static void tcg_out_exit_tb(TCGContext *s, uintptr_t arg);
 static void tcg_out_op(TCGContext *s, TCGOpcode opc,
const TCGArg args[TCG_MAX_OP_ARGS],
const int const_args[TCG_MAX_OP_ARGS]);
@@ -4718,6 +4719,9 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, 
target_ulong pc_start)
 case INDEX_op_call:
 tcg_reg_alloc_call(s, op);
 break;
+case INDEX_op_exit_tb:
+tcg_out_exit_tb(s, op->args[0]);
+break;
 case INDEX_op_dup2_vec:
 if (tcg_reg_alloc_dup2(s, op)) {
 break;
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
index ad1816e32d..501b77c215 100644
--- a/tcg/aarch64/tcg-target.c.inc
+++ b/tcg/aarch64/tcg-target.c.inc
@@ -1887,6 +1887,17 @@ static void tcg_out_qemu_st(TCGContext *s, TCGReg 
data_reg, TCGReg addr_reg,
 
 static const tcg_insn_unit *tb_ret_addr;
 
+static void tcg_out_exit_tb(TCGContext *s, uintptr_t a0)
+{
+/* Reuse the zeroing that exists for goto_ptr.  */
+if (a0 == 0) {
+tcg_out_goto_long(s, tcg_code_gen_epilogue);
+} else {
+tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_X0, a0);
+tcg_out_goto_long(s, tb_ret_addr);
+}
+}
+
 static void tcg_out_op(TCGContext *s, TCGOpcode opc,
const TCGArg args[TCG_MAX_OP_ARGS],
const int const_args[TCG_MAX_OP_ARGS])
@@ -1906,16 +1917,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 #define REG0(I)  (const_args[I] ? TCG_REG_XZR : (TCGReg)args[I])
 
 switch (opc) {
-case INDEX_op_exit_tb:
-/* Reuse the zeroing that exists for goto_ptr.  */
-if (a0 == 0) {
-tcg_out_goto_long(s, tcg_code_gen_epilogue);
-} else {
-tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_X0, a0);
-tcg_out_goto_long(s, tb_ret_addr);
-}
-break;
-
 case INDEX_op_goto_tb:
 tcg_debug_assert(s->tb_jmp_insn_offset != NULL);
 /*
@@ -2305,6 +2306,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
 case INDEX_op_mov_i64:
 case INDEX_op_call: /* Always emitted via tcg_out_call.  */
+case INDEX_op_exit_tb:  /* Always emitted via tcg_out_exit_tb.  */
 default:
 g_assert_not_reached();
 }
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
index 9245ea86d0..799cf13536 100644
--- a/tcg/arm/tcg-target.c.inc
+++ b/tcg/arm/tcg-target.c.inc
@@ -1933,6 +1933,12 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg 
*args, bool is64)
 
 static void tcg_out_epilogue(TCGContext *s);
 
+static void tcg_out_exit_tb(TCGContext *s, uintptr_t arg)
+{
+tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R0, arg);
+tcg_out_epilogue(s);
+}
+
 static void tcg_out_op(TCGContext *s, TCGOpcode opc,
const TCGArg args[TCG_MAX_OP_ARGS],
const int const_args[TCG_MAX_OP_ARGS])
@@ -1941,10 +1947,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 int c;
 
 switch (opc) {
-case INDEX_op_exit_tb:
-tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R0, args[0]);
-tcg_out_epilogue(s);
-break;
 case INDEX_op_goto_tb:
 {
 /* Indirect jump method */
@@ -2256,6 +2258,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 
 case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
 case INDEX_op_call: /* Always emitted via tcg_out_call.  */
+case INDEX_op_exit_tb:  /* Always emitted via tcg_out_exit_tb.  */
 default:
 tcg_abort();
 }
diff --git 

[PULL 03/22] tcg/ppc: Remove unused goto_tb code for indirect jump

2023-01-17 Thread Richard Henderson
Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 tcg/ppc/tcg-target.c.inc | 32 +---
 1 file changed, 13 insertions(+), 19 deletions(-)

diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
index a95e4001d3..b72e266990 100644
--- a/tcg/ppc/tcg-target.c.inc
+++ b/tcg/ppc/tcg-target.c.inc
@@ -2630,27 +2630,21 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 
 switch (opc) {
 case INDEX_op_goto_tb:
-if (s->tb_jmp_insn_offset) {
-/* Direct jump. */
-if (TCG_TARGET_REG_BITS == 64) {
-/* Ensure the next insns are 8 or 16-byte aligned. */
-while ((uintptr_t)s->code_ptr & (have_isa_2_07 ? 15 : 7)) {
-tcg_out32(s, NOP);
-}
-s->tb_jmp_insn_offset[args[0]] = tcg_current_code_size(s);
-tcg_out32(s, ADDIS | TAI(TCG_REG_TB, TCG_REG_TB, 0));
-tcg_out32(s, ADDI | TAI(TCG_REG_TB, TCG_REG_TB, 0));
-} else {
-s->tb_jmp_insn_offset[args[0]] = tcg_current_code_size(s);
-tcg_out32(s, B);
-s->tb_jmp_reset_offset[args[0]] = tcg_current_code_size(s);
-break;
+qemu_build_assert(TCG_TARGET_HAS_direct_jump);
+/* Direct jump. */
+if (TCG_TARGET_REG_BITS == 64) {
+/* Ensure the next insns are 8 or 16-byte aligned. */
+while ((uintptr_t)s->code_ptr & (have_isa_2_07 ? 15 : 7)) {
+tcg_out32(s, NOP);
 }
+s->tb_jmp_insn_offset[args[0]] = tcg_current_code_size(s);
+tcg_out32(s, ADDIS | TAI(TCG_REG_TB, TCG_REG_TB, 0));
+tcg_out32(s, ADDI | TAI(TCG_REG_TB, TCG_REG_TB, 0));
 } else {
-/* Indirect jump. */
-tcg_debug_assert(s->tb_jmp_insn_offset == NULL);
-tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TB, 0,
-   (intptr_t)(s->tb_jmp_insn_offset + args[0]));
+s->tb_jmp_insn_offset[args[0]] = tcg_current_code_size(s);
+tcg_out32(s, B);
+s->tb_jmp_reset_offset[args[0]] = tcg_current_code_size(s);
+break;
 }
 tcg_out32(s, MTSPR | RS(TCG_REG_TB) | CTR);
 tcg_out32(s, BCCTR | BO_ALWAYS);
-- 
2.34.1




[PULL 11/22] tcg: Add TranslationBlock.jmp_insn_offset

2023-01-17 Thread Richard Henderson
Stop overloading jmp_target_arg for both offset and address,
depending on TCG_TARGET_HAS_direct_jump.  Instead, add a new
field to hold the jump insn offset and always set the target
address in jmp_target_addr[].  This will allow a tcg backend
to use either direct or indirect depending on displacement.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 include/exec/exec-all.h | 3 ++-
 accel/tcg/cpu-exec.c| 5 ++---
 tcg/tcg.c   | 6 --
 3 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index b4d09c89ab..54585a9954 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -587,7 +587,8 @@ struct TranslationBlock {
  */
 #define TB_JMP_OFFSET_INVALID 0x /* indicates no jump generated */
 uint16_t jmp_reset_offset[2]; /* offset of original jump target */
-uintptr_t jmp_target_arg[2];  /* target address or offset */
+uint16_t jmp_insn_offset[2];  /* offset of direct jump insn */
+uintptr_t jmp_target_addr[2]; /* target address */
 
 /*
  * Each TB has a NULL-terminated list (jmp_list_head) of incoming jumps.
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 8927092537..25c4b04445 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -572,14 +572,13 @@ void cpu_exec_step_atomic(CPUState *cpu)
 
 void tb_set_jmp_target(TranslationBlock *tb, int n, uintptr_t addr)
 {
+tb->jmp_target_addr[n] = addr;
 if (TCG_TARGET_HAS_direct_jump) {
-uintptr_t offset = tb->jmp_target_arg[n];
+uintptr_t offset = tb->jmp_insn_offset[n];
 uintptr_t tc_ptr = (uintptr_t)tb->tc.ptr;
 uintptr_t jmp_rx = tc_ptr + offset;
 uintptr_t jmp_rw = jmp_rx - tcg_splitwx_diff;
 tb_target_set_jmp_target(tc_ptr, jmp_rx, jmp_rw, addr);
-} else {
-tb->jmp_target_arg[n] = addr;
 }
 }
 
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 4ac7086afe..af2af99583 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -321,7 +321,7 @@ static void G_GNUC_UNUSED set_jmp_insn_offset(TCGContext 
*s, int which)
  * tcg_gen_code, where we bound tcg_current_code_size to UINT16_MAX.
  */
 tcg_debug_assert(TCG_TARGET_HAS_direct_jump);
-s->gen_tb->jmp_target_arg[which] = tcg_current_code_size(s);
+s->gen_tb->jmp_insn_offset[which] = tcg_current_code_size(s);
 }
 
 static uintptr_t G_GNUC_UNUSED get_jmp_target_addr(TCGContext *s, int which)
@@ -330,7 +330,7 @@ static uintptr_t G_GNUC_UNUSED 
get_jmp_target_addr(TCGContext *s, int which)
  * Return the read-execute version of the pointer, for the benefit
  * of any pc-relative addressing mode.
  */
-return (uintptr_t)tcg_splitwx_to_rx(s->gen_tb->jmp_target_arg + which);
+return (uintptr_t)tcg_splitwx_to_rx(>gen_tb->jmp_target_addr[which]);
 }
 
 /* Signal overflow, starting over with fewer guest insns. */
@@ -4668,6 +4668,8 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, 
target_ulong pc_start)
 /* Initialize goto_tb jump offsets. */
 tb->jmp_reset_offset[0] = TB_JMP_OFFSET_INVALID;
 tb->jmp_reset_offset[1] = TB_JMP_OFFSET_INVALID;
+tb->jmp_insn_offset[0] = TB_JMP_OFFSET_INVALID;
+tb->jmp_insn_offset[1] = TB_JMP_OFFSET_INVALID;
 
 tcg_reg_alloc_start(s);
 
-- 
2.34.1




[PULL 21/22] tcg/riscv: Introduce OPC_NOP

2023-01-17 Thread Richard Henderson
Reviewed-by: Alex Bennée 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 tcg/riscv/tcg-target.c.inc | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index 136fe54d4b..82ca86431e 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -267,6 +267,7 @@ typedef enum {
 #endif
 
 OPC_FENCE = 0x000f,
+OPC_NOP   = OPC_ADDI,   /* nop = addi r0,r0,0 */
 } RISCVInsn;
 
 /*
@@ -403,7 +404,7 @@ static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
 {
 int i;
 for (i = 0; i < count; ++i) {
-p[i] = encode_i(OPC_ADDI, TCG_REG_ZERO, TCG_REG_ZERO, 0);
+p[i] = OPC_NOP;
 }
 }
 
-- 
2.34.1




[PULL 09/22] tcg: Rename TB_JMP_RESET_OFFSET_INVALID to TB_JMP_OFFSET_INVALID

2023-01-17 Thread Richard Henderson
This will shortly be used for more than reset.

Reviewed-by: Alex Bennée 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 include/exec/exec-all.h   | 2 +-
 accel/tcg/translate-all.c | 8 
 tcg/tcg.c | 4 ++--
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 25e11b0a8d..b4d09c89ab 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -585,8 +585,8 @@ struct TranslationBlock {
  * setting one of the jump targets (or patching the jump instruction). Only
  * two of such jumps are supported.
  */
+#define TB_JMP_OFFSET_INVALID 0x /* indicates no jump generated */
 uint16_t jmp_reset_offset[2]; /* offset of original jump target */
-#define TB_JMP_RESET_OFFSET_INVALID 0x /* indicates no jump generated */
 uintptr_t jmp_target_arg[2];  /* target address or offset */
 
 /*
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index 979f8e1107..a4fdce5b72 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -508,10 +508,10 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
 tb->jmp_dest[1] = (uintptr_t)NULL;
 
 /* init original jump addresses which have been set during tcg_gen_code() 
*/
-if (tb->jmp_reset_offset[0] != TB_JMP_RESET_OFFSET_INVALID) {
+if (tb->jmp_reset_offset[0] != TB_JMP_OFFSET_INVALID) {
 tb_reset_jump(tb, 0);
 }
-if (tb->jmp_reset_offset[1] != TB_JMP_RESET_OFFSET_INVALID) {
+if (tb->jmp_reset_offset[1] != TB_JMP_OFFSET_INVALID) {
 tb_reset_jump(tb, 1);
 }
 
@@ -693,9 +693,9 @@ static gboolean tb_tree_stats_iter(gpointer key, gpointer 
value, gpointer data)
 if (tb_page_addr1(tb) != -1) {
 tst->cross_page++;
 }
-if (tb->jmp_reset_offset[0] != TB_JMP_RESET_OFFSET_INVALID) {
+if (tb->jmp_reset_offset[0] != TB_JMP_OFFSET_INVALID) {
 tst->direct_jmp_count++;
-if (tb->jmp_reset_offset[1] != TB_JMP_RESET_OFFSET_INVALID) {
+if (tb->jmp_reset_offset[1] != TB_JMP_OFFSET_INVALID) {
 tst->direct_jmp2_count++;
 }
 }
diff --git a/tcg/tcg.c b/tcg/tcg.c
index ffa4506e57..ff674c5122 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -4666,8 +4666,8 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, 
target_ulong pc_start)
 #endif
 
 /* Initialize goto_tb jump offsets. */
-tb->jmp_reset_offset[0] = TB_JMP_RESET_OFFSET_INVALID;
-tb->jmp_reset_offset[1] = TB_JMP_RESET_OFFSET_INVALID;
+tb->jmp_reset_offset[0] = TB_JMP_OFFSET_INVALID;
+tb->jmp_reset_offset[1] = TB_JMP_OFFSET_INVALID;
 tcg_ctx->tb_jmp_reset_offset = tb->jmp_reset_offset;
 if (TCG_TARGET_HAS_direct_jump) {
 tcg_ctx->tb_jmp_insn_offset = tb->jmp_target_arg;
-- 
2.34.1




[PULL 15/22] tcg: Remove TCG_TARGET_HAS_direct_jump

2023-01-17 Thread Richard Henderson
We now have the option to generate direct or indirect
goto_tb depending on the dynamic displacement, thus
the define is no longer necessary or completely accurate.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 tcg/aarch64/tcg-target.h |  1 -
 tcg/arm/tcg-target.h |  1 -
 tcg/i386/tcg-target.h|  1 -
 tcg/loongarch64/tcg-target.h |  1 -
 tcg/mips/tcg-target.h|  1 -
 tcg/ppc/tcg-target.h |  1 -
 tcg/riscv/tcg-target.h   |  1 -
 tcg/s390x/tcg-target.h   |  1 -
 tcg/sparc64/tcg-target.h |  1 -
 tcg/tci/tcg-target.h |  1 -
 accel/tcg/cpu-exec.c | 23 +++
 tcg/tcg.c|  1 -
 tcg/arm/tcg-target.c.inc |  1 -
 tcg/mips/tcg-target.c.inc|  1 -
 tcg/riscv/tcg-target.c.inc   |  1 -
 tcg/s390x/tcg-target.c.inc   |  3 +++
 tcg/tci/tcg-target.c.inc |  1 -
 17 files changed, 14 insertions(+), 27 deletions(-)

diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
index a585d035d9..6067446b03 100644
--- a/tcg/aarch64/tcg-target.h
+++ b/tcg/aarch64/tcg-target.h
@@ -123,7 +123,6 @@ typedef enum {
 #define TCG_TARGET_HAS_muls2_i640
 #define TCG_TARGET_HAS_muluh_i641
 #define TCG_TARGET_HAS_mulsh_i641
-#define TCG_TARGET_HAS_direct_jump  1
 
 #define TCG_TARGET_HAS_v64  1
 #define TCG_TARGET_HAS_v128 1
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
index d347a5dc53..91b8954804 100644
--- a/tcg/arm/tcg-target.h
+++ b/tcg/arm/tcg-target.h
@@ -121,7 +121,6 @@ extern bool use_neon_instructions;
 #define TCG_TARGET_HAS_mulsh_i320
 #define TCG_TARGET_HAS_div_i32  use_idiv_instructions
 #define TCG_TARGET_HAS_rem_i32  0
-#define TCG_TARGET_HAS_direct_jump  0
 #define TCG_TARGET_HAS_qemu_st8_i32 0
 
 #define TCG_TARGET_HAS_v64  use_neon_instructions
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index d3705da2ed..5797a55ea0 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -141,7 +141,6 @@ extern bool have_movbe;
 #define TCG_TARGET_HAS_muls2_i321
 #define TCG_TARGET_HAS_muluh_i320
 #define TCG_TARGET_HAS_mulsh_i320
-#define TCG_TARGET_HAS_direct_jump  1
 
 #if TCG_TARGET_REG_BITS == 64
 /* Keep target addresses zero-extended in a register.  */
diff --git a/tcg/loongarch64/tcg-target.h b/tcg/loongarch64/tcg-target.h
index 5782c6887c..1c3e48d662 100644
--- a/tcg/loongarch64/tcg-target.h
+++ b/tcg/loongarch64/tcg-target.h
@@ -128,7 +128,6 @@ typedef enum {
 #define TCG_TARGET_HAS_clz_i32  1
 #define TCG_TARGET_HAS_ctz_i32  1
 #define TCG_TARGET_HAS_ctpop_i320
-#define TCG_TARGET_HAS_direct_jump  1
 #define TCG_TARGET_HAS_brcond2  0
 #define TCG_TARGET_HAS_setcond2 0
 #define TCG_TARGET_HAS_qemu_st8_i32 0
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
index 82b40100cf..7bc8e15293 100644
--- a/tcg/mips/tcg-target.h
+++ b/tcg/mips/tcg-target.h
@@ -134,7 +134,6 @@ extern bool use_mips32r2_instructions;
 #define TCG_TARGET_HAS_muluh_i321
 #define TCG_TARGET_HAS_mulsh_i321
 #define TCG_TARGET_HAS_bswap32_i32  1
-#define TCG_TARGET_HAS_direct_jump  0
 
 #if TCG_TARGET_REG_BITS == 64
 #define TCG_TARGET_HAS_add2_i32 0
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
index 5ffb41fb57..f253184915 100644
--- a/tcg/ppc/tcg-target.h
+++ b/tcg/ppc/tcg-target.h
@@ -108,7 +108,6 @@ extern bool have_vsx;
 #define TCG_TARGET_HAS_muls2_i320
 #define TCG_TARGET_HAS_muluh_i321
 #define TCG_TARGET_HAS_mulsh_i321
-#define TCG_TARGET_HAS_direct_jump  1
 #define TCG_TARGET_HAS_qemu_st8_i32 0
 
 #if TCG_TARGET_REG_BITS == 64
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
index c9af6d592f..1337bc1f1e 100644
--- a/tcg/riscv/tcg-target.h
+++ b/tcg/riscv/tcg-target.h
@@ -121,7 +121,6 @@ typedef enum {
 #define TCG_TARGET_HAS_clz_i32  0
 #define TCG_TARGET_HAS_ctz_i32  0
 #define TCG_TARGET_HAS_ctpop_i320
-#define TCG_TARGET_HAS_direct_jump  0
 #define TCG_TARGET_HAS_brcond2  1
 #define TCG_TARGET_HAS_setcond2 1
 #define TCG_TARGET_HAS_qemu_st8_i32 0
diff --git a/tcg/s390x/tcg-target.h b/tcg/s390x/tcg-target.h
index 9f5d1cf1c7..e597e47e60 100644
--- a/tcg/s390x/tcg-target.h
+++ b/tcg/s390x/tcg-target.h
@@ -105,7 +105,6 @@ extern uint64_t s390_facilities[3];
 #define TCG_TARGET_HAS_mulsh_i32  0
 #define TCG_TARGET_HAS_extrl_i64_i32  0
 #define TCG_TARGET_HAS_extrh_i64_i32  0
-#define TCG_TARGET_HAS_direct_jump1
 #define TCG_TARGET_HAS_qemu_st8_i32   0
 
 #define TCG_TARGET_HAS_div2_i64   1
diff --git a/tcg/sparc64/tcg-target.h b/tcg/sparc64/tcg-target.h
index b78a545581..1d6a5c8b07 100644
--- a/tcg/sparc64/tcg-target.h
+++ b/tcg/sparc64/tcg-target.h
@@ -111,7 +111,6 @@ extern bool use_vis3_instructions;
 #define TCG_TARGET_HAS_muls2_i321
 #define 

[PULL 22/22] tcg/riscv: Implement direct branch for goto_tb

2023-01-17 Thread Richard Henderson
Now that tcg can handle direct and indirect goto_tb simultaneously,
we can optimistically leave space for a direct branch and fall back
to loading the pointer from the TB for an indirect branch.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 tcg/riscv/tcg-target.c.inc | 19 +--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index 82ca86431e..fc0edd811f 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -1303,7 +1303,11 @@ static void tcg_out_exit_tb(TCGContext *s, uintptr_t a0)
 
 static void tcg_out_goto_tb(TCGContext *s, int which)
 {
-/* indirect jump method */
+/* Direct branch will be patched by tb_target_set_jmp_target. */
+set_jmp_insn_offset(s, which);
+tcg_out32(s, OPC_JAL);
+
+/* When branch is out of range, fall through to indirect. */
 tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP0, TCG_REG_ZERO,
get_jmp_target_addr(s, which));
 tcg_out_opc_imm(s, OPC_JALR, TCG_REG_ZERO, TCG_REG_TMP0, 0);
@@ -1313,7 +1317,18 @@ static void tcg_out_goto_tb(TCGContext *s, int which)
 void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
   uintptr_t jmp_rx, uintptr_t jmp_rw)
 {
-/* Always indirect, nothing to do */
+uintptr_t addr = tb->jmp_target_addr[n];
+ptrdiff_t offset = addr - jmp_rx;
+tcg_insn_unit insn;
+
+/* Either directly branch, or fall through to indirect branch. */
+if (offset == sextreg(offset, 0, 20)) {
+insn = encode_uj(OPC_JAL, TCG_REG_ZERO, offset);
+} else {
+insn = OPC_NOP;
+}
+qatomic_set((uint32_t *)jmp_rw, insn);
+flush_idcache_range(jmp_rx, jmp_rw, 4);
 }
 
 static void tcg_out_op(TCGContext *s, TCGOpcode opc,
-- 
2.34.1




[PULL 16/22] tcg/aarch64: Reorg goto_tb implementation

2023-01-17 Thread Richard Henderson
The old implementation replaces two insns, swapping between

b   
nop
br  x30
and
adrpx30, 
addix30, x30, lo12:
br  x30

There is a race condition in which a thread could be stopped at
the PC of the second insn, and when restarted does not see the
complete address computation and branches to nowhere.

The new implemetation replaces only one insn, swapping between

b   
br  tmp
and
ldr tmp, 
br  tmp

Reported-by: hev 
Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 tcg/aarch64/tcg-target.h |  2 +-
 tcg/aarch64/tcg-target.c.inc | 66 +++-
 2 files changed, 29 insertions(+), 39 deletions(-)

diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
index 6067446b03..8d244292aa 100644
--- a/tcg/aarch64/tcg-target.h
+++ b/tcg/aarch64/tcg-target.h
@@ -15,7 +15,7 @@
 
 #define TCG_TARGET_INSN_UNIT_SIZE  4
 #define TCG_TARGET_TLB_DISPLACEMENT_BITS 24
-#define MAX_CODE_GEN_BUFFER_SIZE  (2 * GiB)
+#define MAX_CODE_GEN_BUFFER_SIZE  ((size_t)-1)
 
 typedef enum {
 TCG_REG_X0, TCG_REG_X1, TCG_REG_X2, TCG_REG_X3,
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
index 0b65f2cac1..330d26b395 100644
--- a/tcg/aarch64/tcg-target.c.inc
+++ b/tcg/aarch64/tcg-target.c.inc
@@ -1353,33 +1353,6 @@ static void tcg_out_call(TCGContext *s, const 
tcg_insn_unit *target,
 tcg_out_call_int(s, target);
 }
 
-void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
-  uintptr_t jmp_rx, uintptr_t jmp_rw)
-{
-uintptr_t addr = tb->jmp_target_addr[n];
-tcg_insn_unit i1, i2;
-TCGType rt = TCG_TYPE_I64;
-TCGReg  rd = TCG_REG_TMP;
-uint64_t pair;
-
-ptrdiff_t offset = addr - jmp_rx;
-
-if (offset == sextract64(offset, 0, 26)) {
-i1 = I3206_B | ((offset >> 2) & 0x3ff);
-i2 = NOP;
-} else {
-offset = (addr >> 12) - (jmp_rx >> 12);
-
-/* patch ADRP */
-i1 = I3406_ADRP | (offset & 3) << 29 | (offset & 0x1c) << (5 - 2) 
| rd;
-/* patch ADDI */
-i2 = I3401_ADDI | rt << 31 | (addr & 0xfff) << 10 | rd << 5 | rd;
-}
-pair = (uint64_t)i2 << 32 | i1;
-qatomic_set((uint64_t *)jmp_rw, pair);
-flush_idcache_range(jmp_rx, jmp_rw, 8);
-}
-
 static inline void tcg_out_goto_label(TCGContext *s, TCGLabel *l)
 {
 if (!l->has_value) {
@@ -1902,23 +1875,40 @@ static void tcg_out_exit_tb(TCGContext *s, uintptr_t a0)
 static void tcg_out_goto_tb(TCGContext *s, int which)
 {
 /*
- * Ensure that ADRP+ADD are 8-byte aligned so that an atomic
- * write can be used to patch the target address.
+ * Direct branch, or indirect address load, will be patched
+ * by tb_target_set_jmp_target.  Assert indirect load offset
+ * in range early, regardless of direct branch distance.
  */
-if ((uintptr_t)s->code_ptr & 7) {
-tcg_out32(s, NOP);
-}
+intptr_t i_off = tcg_pcrel_diff(s, (void *)get_jmp_target_addr(s, which));
+tcg_debug_assert(i_off == sextract64(i_off, 0, 21));
+
 set_jmp_insn_offset(s, which);
-/*
- * actual branch destination will be patched by
- * tb_target_set_jmp_target later
- */
-tcg_out_insn(s, 3406, ADRP, TCG_REG_TMP, 0);
-tcg_out_insn(s, 3401, ADDI, TCG_TYPE_I64, TCG_REG_TMP, TCG_REG_TMP, 0);
+tcg_out32(s, I3206_B);
 tcg_out_insn(s, 3207, BR, TCG_REG_TMP);
 set_jmp_reset_offset(s, which);
 }
 
+void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
+  uintptr_t jmp_rx, uintptr_t jmp_rw)
+{
+uintptr_t d_addr = tb->jmp_target_addr[n];
+ptrdiff_t d_offset = d_addr - jmp_rx;
+tcg_insn_unit insn;
+
+/* Either directly branch, or indirect branch load. */
+if (d_offset == sextract64(d_offset, 0, 28)) {
+insn = deposit32(I3206_B, 0, 26, d_offset >> 2);
+} else {
+uintptr_t i_addr = (uintptr_t)>jmp_target_addr[n];
+ptrdiff_t i_offset = i_addr - jmp_rx;
+
+/* Note that we asserted this in range in tcg_out_goto_tb. */
+insn = deposit32(I3305_LDR | TCG_REG_TMP, 0, 5, i_offset >> 2);
+}
+qatomic_set((uint32_t *)jmp_rw, insn);
+flush_idcache_range(jmp_rx, jmp_rw, 4);
+}
+
 static void tcg_out_op(TCGContext *s, TCGOpcode opc,
const TCGArg args[TCG_MAX_OP_ARGS],
const int const_args[TCG_MAX_OP_ARGS])
-- 
2.34.1




[PULL 18/22] tcg/sparc64: Remove USE_REG_TB

2023-01-17 Thread Richard Henderson
This is always true for sparc64, so this is dead since 3a5f6805c7ca.

Reviewed-by: Alex Bennée 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 tcg/sparc64/tcg-target.c.inc | 62 
 1 file changed, 21 insertions(+), 41 deletions(-)

diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
index fdb711bdf6..e0b3957149 100644
--- a/tcg/sparc64/tcg-target.c.inc
+++ b/tcg/sparc64/tcg-target.c.inc
@@ -92,7 +92,6 @@ static const char * const 
tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
 #endif
 
 #define TCG_REG_TB  TCG_REG_I1
-#define USE_REG_TB  (sizeof(void *) > 4)
 
 static const int tcg_target_reg_alloc_order[] = {
 TCG_REG_L0,
@@ -439,7 +438,7 @@ static void tcg_out_movi_int(TCGContext *s, TCGType type, 
TCGReg ret,
 }
 
 /* A 13-bit constant relative to the TB.  */
-if (!in_prologue && USE_REG_TB) {
+if (!in_prologue) {
 test = tcg_tbrel_diff(s, (void *)arg);
 if (check_fit_ptr(test, 13)) {
 tcg_out_arithi(s, ret, TCG_REG_TB, test, ARITH_ADD);
@@ -468,7 +467,7 @@ static void tcg_out_movi_int(TCGContext *s, TCGType type, 
TCGReg ret,
 }
 
 /* Use the constant pool, if possible. */
-if (!in_prologue && USE_REG_TB) {
+if (!in_prologue) {
 new_pool_label(s, arg, R_SPARC_13, s->code_ptr,
tcg_tbrel_diff(s, NULL));
 tcg_out32(s, LDX | INSN_RD(ret) | INSN_RS1(TCG_REG_TB));
@@ -1015,10 +1014,8 @@ static void tcg_target_qemu_prologue(TCGContext *s)
 #endif
 
 /* We choose TCG_REG_TB such that no move is required.  */
-if (USE_REG_TB) {
-QEMU_BUILD_BUG_ON(TCG_REG_TB != TCG_REG_I1);
-tcg_regset_set_reg(s->reserved_regs, TCG_REG_TB);
-}
+QEMU_BUILD_BUG_ON(TCG_REG_TB != TCG_REG_I1);
+tcg_regset_set_reg(s->reserved_regs, TCG_REG_TB);
 
 tcg_out_arithi(s, TCG_REG_G0, TCG_REG_I1, 0, JMPL);
 /* delay slot */
@@ -1423,7 +1420,7 @@ static void tcg_out_exit_tb(TCGContext *s, uintptr_t a0)
 tcg_out_arithi(s, TCG_REG_G0, TCG_REG_I7, 8, RETURN);
 tcg_out_movi_imm13(s, TCG_REG_O0, a0);
 return;
-} else if (USE_REG_TB) {
+} else {
 intptr_t tb_diff = tcg_tbrel_diff(s, (void *)a0);
 if (check_fit_ptr(tb_diff, 13)) {
 tcg_out_arithi(s, TCG_REG_G0, TCG_REG_I7, 8, RETURN);
@@ -1439,36 +1436,30 @@ static void tcg_out_exit_tb(TCGContext *s, uintptr_t a0)
 
 static void tcg_out_goto_tb(TCGContext *s, int which)
 {
+int c;
+
 /* Direct jump. */
-if (USE_REG_TB) {
-/* make sure the patch is 8-byte aligned.  */
-if ((intptr_t)s->code_ptr & 4) {
-tcg_out_nop(s);
-}
-set_jmp_insn_offset(s, which);
-tcg_out_sethi(s, TCG_REG_T1, 0);
-tcg_out_arithi(s, TCG_REG_T1, TCG_REG_T1, 0, ARITH_OR);
-tcg_out_arith(s, TCG_REG_G0, TCG_REG_TB, TCG_REG_T1, JMPL);
-tcg_out_arith(s, TCG_REG_TB, TCG_REG_TB, TCG_REG_T1, ARITH_ADD);
-} else {
-set_jmp_insn_offset(s, which);
-tcg_out32(s, CALL);
+/* make sure the patch is 8-byte aligned.  */
+if ((intptr_t)s->code_ptr & 4) {
 tcg_out_nop(s);
 }
+set_jmp_insn_offset(s, which);
+tcg_out_sethi(s, TCG_REG_T1, 0);
+tcg_out_arithi(s, TCG_REG_T1, TCG_REG_T1, 0, ARITH_OR);
+tcg_out_arith(s, TCG_REG_G0, TCG_REG_TB, TCG_REG_T1, JMPL);
+tcg_out_arith(s, TCG_REG_TB, TCG_REG_TB, TCG_REG_T1, ARITH_ADD);
 set_jmp_reset_offset(s, which);
 
 /*
  * For the unlinked path of goto_tb, we need to reset TCG_REG_TB
  * to the beginning of this TB.
  */
-if (USE_REG_TB) {
-int c = -tcg_current_code_size(s);
-if (check_fit_i32(c, 13)) {
-tcg_out_arithi(s, TCG_REG_TB, TCG_REG_TB, c, ARITH_ADD);
-} else {
-tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_T1, c);
-tcg_out_arith(s, TCG_REG_TB, TCG_REG_TB, TCG_REG_T1, ARITH_ADD);
-}
+c = -tcg_current_code_size(s);
+if (check_fit_i32(c, 13)) {
+tcg_out_arithi(s, TCG_REG_TB, TCG_REG_TB, c, ARITH_ADD);
+} else {
+tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_T1, c);
+tcg_out_arith(s, TCG_REG_TB, TCG_REG_TB, TCG_REG_T1, ARITH_ADD);
 }
 }
 
@@ -1488,11 +1479,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 switch (opc) {
 case INDEX_op_goto_ptr:
 tcg_out_arithi(s, TCG_REG_G0, a0, 0, JMPL);
-if (USE_REG_TB) {
-tcg_out_mov_delay(s, TCG_REG_TB, a0);
-} else {
-tcg_out_nop(s);
-}
+tcg_out_mov_delay(s, TCG_REG_TB, a0);
 break;
 case INDEX_op_br:
 tcg_out_bpcc(s, COND_A, BPCC_PT, arg_label(a0));
@@ -1898,13 +1885,6 @@ void tb_target_set_jmp_target(const TranslationBlock 
*tb, int n,
 tcg_debug_assert(tb_disp == (int32_t)tb_disp);
 tcg_debug_assert(br_disp == (int32_t)br_disp);
 
-if (!USE_REG_TB) {
-qatomic_set((uint32_t *)jmp_rw,
-

[PULL 12/22] tcg: Change tb_target_set_jmp_target arguments

2023-01-17 Thread Richard Henderson
Replace 'tc_ptr' and 'addr' with 'tb' and 'n'.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 tcg/aarch64/tcg-target.h |  3 ++-
 tcg/arm/tcg-target.h |  3 ++-
 tcg/i386/tcg-target.h|  9 ++---
 tcg/loongarch64/tcg-target.h |  3 ++-
 tcg/mips/tcg-target.h|  3 ++-
 tcg/ppc/tcg-target.h |  3 ++-
 tcg/riscv/tcg-target.h   |  3 ++-
 tcg/s390x/tcg-target.h   | 10 ++
 tcg/sparc64/tcg-target.h |  3 ++-
 tcg/tci/tcg-target.h |  3 ++-
 accel/tcg/cpu-exec.c | 11 ---
 tcg/aarch64/tcg-target.c.inc |  5 +++--
 tcg/i386/tcg-target.c.inc|  9 +
 tcg/loongarch64/tcg-target.c.inc |  5 +++--
 tcg/ppc/tcg-target.c.inc |  7 ---
 tcg/s390x/tcg-target.c.inc   | 10 ++
 tcg/sparc64/tcg-target.c.inc |  7 ---
 17 files changed, 61 insertions(+), 36 deletions(-)

diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
index 413a5410c5..d491c198da 100644
--- a/tcg/aarch64/tcg-target.h
+++ b/tcg/aarch64/tcg-target.h
@@ -152,7 +152,8 @@ typedef enum {
 #define TCG_TARGET_DEFAULT_MO (0)
 #define TCG_TARGET_HAS_MEMORY_BSWAP 0
 
-void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
+void tb_target_set_jmp_target(const TranslationBlock *, int,
+  uintptr_t, uintptr_t);
 
 #define TCG_TARGET_NEED_LDST_LABELS
 #define TCG_TARGET_NEED_POOL_LABELS
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
index b7843d2d54..4c1433093c 100644
--- a/tcg/arm/tcg-target.h
+++ b/tcg/arm/tcg-target.h
@@ -152,7 +152,8 @@ extern bool use_neon_instructions;
 #define TCG_TARGET_HAS_MEMORY_BSWAP 0
 
 /* not defined -- call should be eliminated at compile time */
-void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
+void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
+  uintptr_t, uintptr_t);
 
 #define TCG_TARGET_NEED_LDST_LABELS
 #define TCG_TARGET_NEED_POOL_LABELS
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index 7edb7f1d9a..7500ceaab9 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -220,13 +220,8 @@ extern bool have_movbe;
 #define TCG_TARGET_extract_i64_valid(ofs, len) \
 (((ofs) == 8 && (len) == 8) || ((ofs) + (len)) == 32)
 
-static inline void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx,
-uintptr_t jmp_rw, uintptr_t addr)
-{
-/* patch the branch destination */
-qatomic_set((int32_t *)jmp_rw, addr - (jmp_rx + 4));
-/* no need to flush icache explicitly */
-}
+void tb_target_set_jmp_target(const TranslationBlock *, int,
+  uintptr_t, uintptr_t);
 
 /* This defines the natural memory order supported by this
  * architecture before guarantees made by various barrier
diff --git a/tcg/loongarch64/tcg-target.h b/tcg/loongarch64/tcg-target.h
index e5f7a1f09d..a150c3c7b2 100644
--- a/tcg/loongarch64/tcg-target.h
+++ b/tcg/loongarch64/tcg-target.h
@@ -171,7 +171,8 @@ typedef enum {
 #define TCG_TARGET_HAS_muluh_i641
 #define TCG_TARGET_HAS_mulsh_i641
 
-void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
+void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
+  uintptr_t, uintptr_t);
 
 #define TCG_TARGET_DEFAULT_MO (0)
 
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
index 15721c3e42..d1adf3e326 100644
--- a/tcg/mips/tcg-target.h
+++ b/tcg/mips/tcg-target.h
@@ -206,7 +206,8 @@ extern bool use_mips32r2_instructions;
 #define TCG_TARGET_HAS_MEMORY_BSWAP 1
 
 /* not defined -- call should be eliminated at compile time */
-void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t)
+void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
+  uintptr_t, uintptr_t)
 QEMU_ERROR("code path is reachable");
 
 #define TCG_TARGET_NEED_LDST_LABELS
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
index b5cd225cfa..02764c3331 100644
--- a/tcg/ppc/tcg-target.h
+++ b/tcg/ppc/tcg-target.h
@@ -180,7 +180,8 @@ extern bool have_vsx;
 #define TCG_TARGET_HAS_bitsel_vec   have_vsx
 #define TCG_TARGET_HAS_cmpsel_vec   0
 
-void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
+void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
+  uintptr_t, uintptr_t);
 
 #define TCG_TARGET_DEFAULT_MO (0)
 #define TCG_TARGET_HAS_MEMORY_BSWAP 1
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
index 232537ccea..bce164fde2 100644
--- a/tcg/riscv/tcg-target.h
+++ b/tcg/riscv/tcg-target.h
@@ -166,7 +166,8 @@ typedef enum {
 #endif
 
 /* not defined -- call should be eliminated at compile time */
-void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
+void tb_target_set_jmp_target(const 

[PULL 17/22] tcg/ppc: Reorg goto_tb implementation

2023-01-17 Thread Richard Henderson
The old ppc64 implementation replaces 2 or 4 insns, which leaves a race
condition in which a thread could be stopped at a PC in the middle of
the sequence, and when restarted does not see the complete address
computation and branches to nowhere.

The new implemetation replaces only one insn, swapping between

b   
and
mtctr   r31

falling through to a general-case indirect branch.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 tcg/ppc/tcg-target.h |   3 +-
 tcg/ppc/tcg-target.c.inc | 158 +++
 2 files changed, 44 insertions(+), 117 deletions(-)

diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
index f253184915..af81c5a57f 100644
--- a/tcg/ppc/tcg-target.h
+++ b/tcg/ppc/tcg-target.h
@@ -27,11 +27,10 @@
 
 #ifdef _ARCH_PPC64
 # define TCG_TARGET_REG_BITS  64
-# define MAX_CODE_GEN_BUFFER_SIZE  (2 * GiB)
 #else
 # define TCG_TARGET_REG_BITS  32
-# define MAX_CODE_GEN_BUFFER_SIZE  (32 * MiB)
 #endif
+#define MAX_CODE_GEN_BUFFER_SIZE  ((size_t)-1)
 
 #define TCG_TARGET_NB_REGS 64
 #define TCG_TARGET_INSN_UNIT_SIZE 4
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
index 6f2c8faea6..8d6899cf40 100644
--- a/tcg/ppc/tcg-target.c.inc
+++ b/tcg/ppc/tcg-target.c.inc
@@ -1854,104 +1854,6 @@ static void tcg_out_mb(TCGContext *s, TCGArg a0)
 tcg_out32(s, insn);
 }
 
-static inline uint64_t make_pair(tcg_insn_unit i1, tcg_insn_unit i2)
-{
-if (HOST_BIG_ENDIAN) {
-return (uint64_t)i1 << 32 | i2;
-}
-return (uint64_t)i2 << 32 | i1;
-}
-
-static inline void ppc64_replace2(uintptr_t rx, uintptr_t rw,
-  tcg_insn_unit i0, tcg_insn_unit i1)
-{
-#if TCG_TARGET_REG_BITS == 64
-qatomic_set((uint64_t *)rw, make_pair(i0, i1));
-flush_idcache_range(rx, rw, 8);
-#else
-qemu_build_not_reached();
-#endif
-}
-
-static inline void ppc64_replace4(uintptr_t rx, uintptr_t rw,
-  tcg_insn_unit i0, tcg_insn_unit i1,
-  tcg_insn_unit i2, tcg_insn_unit i3)
-{
-uint64_t p[2];
-
-p[!HOST_BIG_ENDIAN] = make_pair(i0, i1);
-p[HOST_BIG_ENDIAN] = make_pair(i2, i3);
-
-/*
- * There's no convenient way to get the compiler to allocate a pair
- * of registers at an even index, so copy into r6/r7 and clobber.
- */
-asm("mr  %%r6, %1\n\t"
-"mr  %%r7, %2\n\t"
-"stq %%r6, %0"
-: "=Q"(*(__int128 *)rw) : "r"(p[0]), "r"(p[1]) : "r6", "r7");
-flush_idcache_range(rx, rw, 16);
-}
-
-void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
-  uintptr_t jmp_rx, uintptr_t jmp_rw)
-{
-tcg_insn_unit i0, i1, i2, i3;
-uintptr_t addr = tb->jmp_target_addr[n];
-intptr_t tb_diff = addr - (uintptr_t)tb->tc.ptr;
-intptr_t br_diff = addr - (jmp_rx + 4);
-intptr_t lo, hi;
-
-if (TCG_TARGET_REG_BITS == 32) {
-intptr_t diff = addr - jmp_rx;
-tcg_debug_assert(in_range_b(diff));
-qatomic_set((uint32_t *)jmp_rw, B | (diff & 0x3fc));
-flush_idcache_range(jmp_rx, jmp_rw, 4);
-return;
-}
-
-/*
- * For 16-bit displacements, we can use a single add + branch.
- * This happens quite often.
- */
-if (tb_diff == (int16_t)tb_diff) {
-i0 = ADDI | TAI(TCG_REG_TB, TCG_REG_TB, tb_diff);
-i1 = B | (br_diff & 0x3fc);
-ppc64_replace2(jmp_rx, jmp_rw, i0, i1);
-return;
-}
-
-lo = (int16_t)tb_diff;
-hi = (int32_t)(tb_diff - lo);
-assert(tb_diff == hi + lo);
-i0 = ADDIS | TAI(TCG_REG_TB, TCG_REG_TB, hi >> 16);
-i1 = ADDI | TAI(TCG_REG_TB, TCG_REG_TB, lo);
-
-/*
- * Without stq from 2.07, we can only update two insns,
- * and those must be the ones that load the target address.
- */
-if (!have_isa_2_07) {
-ppc64_replace2(jmp_rx, jmp_rw, i0, i1);
-return;
-}
-
-/*
- * For 26-bit displacements, we can use a direct branch.
- * Otherwise we still need the indirect branch, which we
- * must restore after a potential direct branch write.
- */
-br_diff -= 4;
-if (in_range_b(br_diff)) {
-i2 = B | (br_diff & 0x3fc);
-i3 = NOP;
-} else {
-i2 = MTSPR | RS(TCG_REG_TB) | CTR;
-i3 = BCCTR | BO_ALWAYS;
-}
-ppc64_replace4(jmp_rx, jmp_rw, i0, i1, i2, i3);
-}
-
 static void tcg_out_call_int(TCGContext *s, int lk,
  const tcg_insn_unit *target)
 {
@@ -2625,30 +2527,56 @@ static void tcg_out_exit_tb(TCGContext *s, uintptr_t 
arg)
 
 static void tcg_out_goto_tb(TCGContext *s, int which)
 {
-/* Direct jump. */
-if (TCG_TARGET_REG_BITS == 64) {
-/* Ensure the next insns are 8 or 16-byte aligned. */
-while ((uintptr_t)s->code_ptr & (have_isa_2_07 ? 15 : 7)) {
-tcg_out32(s, NOP);
-}
+uintptr_t ptr = get_jmp_target_addr(s, which);
+
+if (USE_REG_TB) {
+

[PULL 00/22] tcg patch queue

2023-01-17 Thread Richard Henderson
Second pull for this week, since this set is large enough by itself.


r~


The following changes since commit 7c9236d6d61f30583d5d860097d88dbf0fe487bf:

  Merge tag 'pull-tcg-20230116' of https://gitlab.com/rth7680/qemu into staging 
(2023-01-17 10:24:16 +)

are available in the Git repository at:

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

for you to fetch changes up to 493c9b19a7fb7f387c4fcf57d3836504d5242bf5:

  tcg/riscv: Implement direct branch for goto_tb (2023-01-17 22:36:17 +)


tcg: Fix race conditions in (most) goto_tb implementations


Richard Henderson (22):
  tcg: Split out tcg_out_exit_tb
  tcg/i386: Remove unused goto_tb code for indirect jump
  tcg/ppc: Remove unused goto_tb code for indirect jump
  tcg/sparc64: Remove unused goto_tb code for indirect jump
  tcg: Replace asserts on tcg_jmp_insn_offset
  tcg: Introduce set_jmp_insn_offset
  tcg: Introduce get_jmp_target_addr
  tcg: Split out tcg_out_goto_tb
  tcg: Rename TB_JMP_RESET_OFFSET_INVALID to TB_JMP_OFFSET_INVALID
  tcg: Add gen_tb to TCGContext
  tcg: Add TranslationBlock.jmp_insn_offset
  tcg: Change tb_target_set_jmp_target arguments
  tcg: Move tb_target_set_jmp_target declaration to tcg.h
  tcg: Always define tb_target_set_jmp_target
  tcg: Remove TCG_TARGET_HAS_direct_jump
  tcg/aarch64: Reorg goto_tb implementation
  tcg/ppc: Reorg goto_tb implementation
  tcg/sparc64: Remove USE_REG_TB
  tcg/sparc64: Reorg goto_tb implementation
  tcg/arm: Implement direct branch for goto_tb
  tcg/riscv: Introduce OPC_NOP
  tcg/riscv: Implement direct branch for goto_tb

 include/exec/exec-all.h  |   5 +-
 include/tcg/tcg.h|  14 ++-
 tcg/aarch64/tcg-target.h |   6 +-
 tcg/arm/tcg-target.h |   5 -
 tcg/i386/tcg-target.h|   9 --
 tcg/loongarch64/tcg-target.h |   3 -
 tcg/mips/tcg-target.h|   5 -
 tcg/ppc/tcg-target.h |   7 +-
 tcg/riscv/tcg-target.h   |   4 -
 tcg/s390x/tcg-target.h   |  11 ---
 tcg/sparc64/tcg-target.h |   4 -
 tcg/tci/tcg-target.h |   4 -
 accel/tcg/cpu-exec.c |  21 ++--
 accel/tcg/translate-all.c|  10 +-
 tcg/tcg-op.c |  14 +--
 tcg/tcg.c|  42 +---
 tcg/aarch64/tcg-target.c.inc | 106 ++---
 tcg/arm/tcg-target.c.inc |  89 +++--
 tcg/i386/tcg-target.c.inc|  68 +++--
 tcg/loongarch64/tcg-target.c.inc |  66 +++--
 tcg/mips/tcg-target.c.inc|  59 +++-
 tcg/ppc/tcg-target.c.inc | 193 -
 tcg/riscv/tcg-target.c.inc   |  65 +
 tcg/s390x/tcg-target.c.inc   |  67 -
 tcg/sparc64/tcg-target.c.inc | 201 +++
 tcg/tci/tcg-target.c.inc |  31 +++---
 26 files changed, 528 insertions(+), 581 deletions(-)



[PULL 20/22] tcg/arm: Implement direct branch for goto_tb

2023-01-17 Thread Richard Henderson
Now that tcg can handle direct and indirect goto_tb
simultaneously, we can optimistically leave space for
a direct branch and fall back to loading the pointer
from the TB for an indirect branch.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 tcg/arm/tcg-target.c.inc | 52 
 1 file changed, 37 insertions(+), 15 deletions(-)

diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
index e1e1c2620d..6abe94137e 100644
--- a/tcg/arm/tcg-target.c.inc
+++ b/tcg/arm/tcg-target.c.inc
@@ -135,6 +135,8 @@ typedef enum {
 ARITH_BIC = 0xe << 21,
 ARITH_MVN = 0xf << 21,
 
+INSN_B = 0x0a00,
+
 INSN_CLZ   = 0x016f0f10,
 INSN_RBIT  = 0x06ff0f30,
 
@@ -546,7 +548,7 @@ static bool tcg_target_const_match(int64_t val, TCGType 
type, int ct)
 
 static void tcg_out_b_imm(TCGContext *s, ARMCond cond, int32_t offset)
 {
-tcg_out32(s, (cond << 28) | 0x0a00 |
+tcg_out32(s, (cond << 28) | INSN_B |
 (((offset - 8) >> 2) & 0x00ff));
 }
 
@@ -1941,32 +1943,52 @@ static void tcg_out_exit_tb(TCGContext *s, uintptr_t 
arg)
 
 static void tcg_out_goto_tb(TCGContext *s, int which)
 {
-/* Indirect jump method */
-intptr_t ptr, dif, dil;
-TCGReg base = TCG_REG_PC;
+uintptr_t i_addr;
+intptr_t i_disp;
 
-ptr = get_jmp_target_addr(s, which);
-dif = tcg_pcrel_diff(s, (void *)ptr) - 8;
-dil = sextract32(dif, 0, 12);
-if (dif != dil) {
+/* Direct branch will be patched by tb_target_set_jmp_target. */
+set_jmp_insn_offset(s, which);
+tcg_out32(s, INSN_NOP);
+
+/* When branch is out of range, fall through to indirect. */
+i_addr = get_jmp_target_addr(s, which);
+i_disp = tcg_pcrel_diff(s, (void *)i_addr) - 8;
+tcg_debug_assert(i_disp < 0);
+if (i_disp >= -0xfff) {
+tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_PC, i_disp);
+} else {
 /*
  * The TB is close, but outside the 12 bits addressable by
  * the load.  We can extend this to 20 bits with a sub of a
- * shifted immediate from pc.  In the vastly unlikely event
- * the code requires more than 1MB, we'll use 2 insns and
- * be no worse off.
+ * shifted immediate from pc.
  */
-base = TCG_REG_R0;
-tcg_out_movi32(s, COND_AL, base, ptr - dil);
+int h = -i_disp;
+int l = h & 0xfff;
+
+h = encode_imm_nofail(h - l);
+tcg_out_dat_imm(s, COND_AL, ARITH_SUB, TCG_REG_R0, TCG_REG_PC, h);
+tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_R0, l);
 }
-tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, base, dil);
 set_jmp_reset_offset(s, which);
 }
 
 void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
   uintptr_t jmp_rx, uintptr_t jmp_rw)
 {
-/* Always indirect, nothing to do */
+uintptr_t addr = tb->jmp_target_addr[n];
+ptrdiff_t offset = addr - (jmp_rx + 8);
+tcg_insn_unit insn;
+
+/* Either directly branch, or fall through to indirect branch. */
+if (offset == sextract64(offset, 0, 26)) {
+/* B  */
+insn = deposit32((COND_AL << 28) | INSN_B, 0, 24, offset >> 2);
+} else {
+insn = INSN_NOP;
+}
+
+qatomic_set((uint32_t *)jmp_rw, insn);
+flush_idcache_range(jmp_rx, jmp_rw, 4);
 }
 
 static void tcg_out_op(TCGContext *s, TCGOpcode opc,
-- 
2.34.1




[PULL 08/22] tcg: Split out tcg_out_goto_tb

2023-01-17 Thread Richard Henderson
The INDEX_op_goto_tb opcode needs no register allocation.
Split out a dedicated helper function for it.

Reviewed-by: Alex Bennée 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 tcg/tcg.c|  4 ++
 tcg/aarch64/tcg-target.c.inc | 40 ++-
 tcg/arm/tcg-target.c.inc | 49 ---
 tcg/i386/tcg-target.c.inc| 33 
 tcg/loongarch64/tcg-target.c.inc | 38 +-
 tcg/mips/tcg-target.c.inc| 21 +-
 tcg/ppc/tcg-target.c.inc | 52 
 tcg/riscv/tcg-target.c.inc   | 20 +-
 tcg/s390x/tcg-target.c.inc   | 31 ---
 tcg/sparc64/tcg-target.c.inc | 68 +---
 tcg/tci/tcg-target.c.inc | 16 
 11 files changed, 199 insertions(+), 173 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 2a14fc2a97..ffa4506e57 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -105,6 +105,7 @@ static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg 
ret, TCGReg arg);
 static void tcg_out_movi(TCGContext *s, TCGType type,
  TCGReg ret, tcg_target_long arg);
 static void tcg_out_exit_tb(TCGContext *s, uintptr_t arg);
+static void tcg_out_goto_tb(TCGContext *s, int which);
 static void tcg_out_op(TCGContext *s, TCGOpcode opc,
const TCGArg args[TCG_MAX_OP_ARGS],
const int const_args[TCG_MAX_OP_ARGS]);
@@ -4741,6 +4742,9 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, 
target_ulong pc_start)
 case INDEX_op_exit_tb:
 tcg_out_exit_tb(s, op->args[0]);
 break;
+case INDEX_op_goto_tb:
+tcg_out_goto_tb(s, op->args[0]);
+break;
 case INDEX_op_dup2_vec:
 if (tcg_reg_alloc_dup2(s, op)) {
 break;
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
index 59e6a08e93..ad35bee8af 100644
--- a/tcg/aarch64/tcg-target.c.inc
+++ b/tcg/aarch64/tcg-target.c.inc
@@ -1898,6 +1898,26 @@ static void tcg_out_exit_tb(TCGContext *s, uintptr_t a0)
 }
 }
 
+static void tcg_out_goto_tb(TCGContext *s, int which)
+{
+/*
+ * Ensure that ADRP+ADD are 8-byte aligned so that an atomic
+ * write can be used to patch the target address.
+ */
+if ((uintptr_t)s->code_ptr & 7) {
+tcg_out32(s, NOP);
+}
+set_jmp_insn_offset(s, which);
+/*
+ * actual branch destination will be patched by
+ * tb_target_set_jmp_target later
+ */
+tcg_out_insn(s, 3406, ADRP, TCG_REG_TMP, 0);
+tcg_out_insn(s, 3401, ADDI, TCG_TYPE_I64, TCG_REG_TMP, TCG_REG_TMP, 0);
+tcg_out_insn(s, 3207, BR, TCG_REG_TMP);
+set_jmp_reset_offset(s, which);
+}
+
 static void tcg_out_op(TCGContext *s, TCGOpcode opc,
const TCGArg args[TCG_MAX_OP_ARGS],
const int const_args[TCG_MAX_OP_ARGS])
@@ -1917,25 +1937,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 #define REG0(I)  (const_args[I] ? TCG_REG_XZR : (TCGReg)args[I])
 
 switch (opc) {
-case INDEX_op_goto_tb:
-/*
- * Ensure that ADRP+ADD are 8-byte aligned so that an atomic
- * write can be used to patch the target address.
- */
-if ((uintptr_t)s->code_ptr & 7) {
-tcg_out32(s, NOP);
-}
-set_jmp_insn_offset(s, a0);
-/*
- * actual branch destination will be patched by
- * tb_target_set_jmp_target later
- */
-tcg_out_insn(s, 3406, ADRP, TCG_REG_TMP, 0);
-tcg_out_insn(s, 3401, ADDI, TCG_TYPE_I64, TCG_REG_TMP, TCG_REG_TMP, 0);
-tcg_out_insn(s, 3207, BR, TCG_REG_TMP);
-set_jmp_reset_offset(s, a0);
-break;
-
 case INDEX_op_goto_ptr:
 tcg_out_insn(s, 3207, BR, a0);
 break;
@@ -2306,6 +2307,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 case INDEX_op_mov_i64:
 case INDEX_op_call: /* Always emitted via tcg_out_call.  */
 case INDEX_op_exit_tb:  /* Always emitted via tcg_out_exit_tb.  */
+case INDEX_op_goto_tb:  /* Always emitted via tcg_out_goto_tb.  */
 default:
 g_assert_not_reached();
 }
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
index 83b6d77e2e..b8f3b0c634 100644
--- a/tcg/arm/tcg-target.c.inc
+++ b/tcg/arm/tcg-target.c.inc
@@ -1939,6 +1939,31 @@ static void tcg_out_exit_tb(TCGContext *s, uintptr_t arg)
 tcg_out_epilogue(s);
 }
 
+static void tcg_out_goto_tb(TCGContext *s, int which)
+{
+/* Indirect jump method */
+intptr_t ptr, dif, dil;
+TCGReg base = TCG_REG_PC;
+
+qemu_build_assert(!TCG_TARGET_HAS_direct_jump);
+ptr = get_jmp_target_addr(s, which);
+dif = tcg_pcrel_diff(s, (void *)ptr) - 8;
+dil = sextract32(dif, 0, 12);
+if (dif != dil) {
+/*
+ * The TB is close, but outside the 12 bits addressable by
+ * the load.  We can extend 

[PULL 14/22] tcg: Always define tb_target_set_jmp_target

2023-01-17 Thread Richard Henderson
Install empty versions for !TCG_TARGET_HAS_direct_jump hosts.

Reviewed-by: Alex Bennée 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 tcg/arm/tcg-target.c.inc   | 6 ++
 tcg/mips/tcg-target.c.inc  | 6 ++
 tcg/riscv/tcg-target.c.inc | 6 ++
 tcg/tci/tcg-target.c.inc   | 6 ++
 4 files changed, 24 insertions(+)

diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
index b8f3b0c634..b21dd561fa 100644
--- a/tcg/arm/tcg-target.c.inc
+++ b/tcg/arm/tcg-target.c.inc
@@ -1964,6 +1964,12 @@ static void tcg_out_goto_tb(TCGContext *s, int which)
 set_jmp_reset_offset(s, which);
 }
 
+void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
+  uintptr_t jmp_rx, uintptr_t jmp_rw)
+{
+/* Always indirect, nothing to do */
+}
+
 static void tcg_out_op(TCGContext *s, TCGOpcode opc,
const TCGArg args[TCG_MAX_OP_ARGS],
const int const_args[TCG_MAX_OP_ARGS])
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
index e54df4128b..0b5e100cb1 100644
--- a/tcg/mips/tcg-target.c.inc
+++ b/tcg/mips/tcg-target.c.inc
@@ -1977,6 +1977,12 @@ static void tcg_out_goto_tb(TCGContext *s, int which)
 set_jmp_reset_offset(s, which);
 }
 
+void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
+  uintptr_t jmp_rx, uintptr_t jmp_rw)
+{
+/* Always indirect, nothing to do */
+}
+
 static void tcg_out_op(TCGContext *s, TCGOpcode opc,
const TCGArg args[TCG_MAX_OP_ARGS],
const int const_args[TCG_MAX_OP_ARGS])
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index ee6759f787..e6a3915859 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -1310,6 +1310,12 @@ static void tcg_out_goto_tb(TCGContext *s, int which)
 set_jmp_reset_offset(s, which);
 }
 
+void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
+  uintptr_t jmp_rx, uintptr_t jmp_rw)
+{
+/* Always indirect, nothing to do */
+}
+
 static void tcg_out_op(TCGContext *s, TCGOpcode opc,
const TCGArg args[TCG_MAX_OP_ARGS],
const int const_args[TCG_MAX_OP_ARGS])
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
index f2ac356900..54779d86d9 100644
--- a/tcg/tci/tcg-target.c.inc
+++ b/tcg/tci/tcg-target.c.inc
@@ -603,6 +603,12 @@ static void tcg_out_goto_tb(TCGContext *s, int which)
 set_jmp_reset_offset(s, which);
 }
 
+void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
+  uintptr_t jmp_rx, uintptr_t jmp_rw)
+{
+/* Always indirect, nothing to do */
+}
+
 static void tcg_out_op(TCGContext *s, TCGOpcode opc,
const TCGArg args[TCG_MAX_OP_ARGS],
const int const_args[TCG_MAX_OP_ARGS])
-- 
2.34.1




[PULL 07/22] tcg: Introduce get_jmp_target_addr

2023-01-17 Thread Richard Henderson
Similar to the existing set_jmp_reset_offset.  Include the
rw->rx address space conversion done by arm and s390x, and
forgotten by mips and riscv.

Reviewed-by: Alex Bennée 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 tcg/tcg.c  | 9 +
 tcg/arm/tcg-target.c.inc   | 2 +-
 tcg/mips/tcg-target.c.inc  | 2 +-
 tcg/riscv/tcg-target.c.inc | 2 +-
 tcg/tci/tcg-target.c.inc   | 2 +-
 5 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 4092dac294..2a14fc2a97 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -323,6 +323,15 @@ static void G_GNUC_UNUSED set_jmp_insn_offset(TCGContext 
*s, int which)
 s->tb_jmp_insn_offset[which] = tcg_current_code_size(s);
 }
 
+static uintptr_t G_GNUC_UNUSED get_jmp_target_addr(TCGContext *s, int which)
+{
+/*
+ * Return the read-execute version of the pointer, for the benefit
+ * of any pc-relative addressing mode.
+ */
+return (uintptr_t)tcg_splitwx_to_rx(>tb_jmp_target_addr[which]);
+}
+
 /* Signal overflow, starting over with fewer guest insns. */
 static G_NORETURN
 void tcg_raise_tb_overflow(TCGContext *s)
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
index 033ff90daa..83b6d77e2e 100644
--- a/tcg/arm/tcg-target.c.inc
+++ b/tcg/arm/tcg-target.c.inc
@@ -1954,7 +1954,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 TCGReg base = TCG_REG_PC;
 
 qemu_build_assert(!TCG_TARGET_HAS_direct_jump);
-ptr = (intptr_t)tcg_splitwx_to_rx(s->tb_jmp_target_addr + args[0]);
+ptr = get_jmp_target_addr(s, args[0]);
 dif = tcg_pcrel_diff(s, (void *)ptr) - 8;
 dil = sextract32(dif, 0, 12);
 if (dif != dil) {
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
index 02887d7cb1..c30173ab64 100644
--- a/tcg/mips/tcg-target.c.inc
+++ b/tcg/mips/tcg-target.c.inc
@@ -1989,7 +1989,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 /* indirect jump method */
 qemu_build_assert(!TCG_TARGET_HAS_direct_jump);
 tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP0, TCG_REG_ZERO,
-   (uintptr_t)(s->tb_jmp_target_addr + a0));
+   get_jmp_target_addr(s, a0));
 tcg_out_opc_reg(s, OPC_JR, 0, TCG_TMP0, 0);
 tcg_out_nop(s);
 set_jmp_reset_offset(s, a0);
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index b977c8025d..5b2eac6ab8 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -1314,7 +1314,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 qemu_build_assert(!TCG_TARGET_HAS_direct_jump);
 /* indirect jump method */
 tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP0, TCG_REG_ZERO,
-   (uintptr_t)(s->tb_jmp_target_addr + a0));
+   get_jmp_target_addr(s, a0));
 tcg_out_opc_imm(s, OPC_JALR, TCG_REG_ZERO, TCG_REG_TMP0, 0);
 set_jmp_reset_offset(s, a0);
 break;
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
index ad356f1875..59daffc0a0 100644
--- a/tcg/tci/tcg-target.c.inc
+++ b/tcg/tci/tcg-target.c.inc
@@ -605,7 +605,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 case INDEX_op_goto_tb:
 qemu_build_assert(!TCG_TARGET_HAS_direct_jump);
 /* indirect jump method. */
-tcg_out_op_p(s, opc, s->tb_jmp_target_addr + args[0]);
+tcg_out_op_p(s, opc, (void *)get_jmp_target_addr(s, args[0]));
 set_jmp_reset_offset(s, args[0]);
 break;
 
-- 
2.34.1




[PULL 02/22] tcg/i386: Remove unused goto_tb code for indirect jump

2023-01-17 Thread Richard Henderson
Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 tcg/i386/tcg-target.c.inc | 14 +-
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
index feb257db01..c4ff59e9ee 100644
--- a/tcg/i386/tcg-target.c.inc
+++ b/tcg/i386/tcg-target.c.inc
@@ -2383,23 +2383,19 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode 
opc,
 
 switch (opc) {
 case INDEX_op_goto_tb:
-if (s->tb_jmp_insn_offset) {
-/* direct jump method */
-int gap;
-/* jump displacement must be aligned for atomic patching;
+qemu_build_assert(TCG_TARGET_HAS_direct_jump);
+{
+/*
+ * Jump displacement must be aligned for atomic patching;
  * see if we need to add extra nops before jump
  */
-gap = QEMU_ALIGN_PTR_UP(s->code_ptr + 1, 4) - s->code_ptr;
+int gap = QEMU_ALIGN_PTR_UP(s->code_ptr + 1, 4) - s->code_ptr;
 if (gap != 1) {
 tcg_out_nopn(s, gap - 1);
 }
 tcg_out8(s, OPC_JMP_long); /* jmp im */
 s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s);
 tcg_out32(s, 0);
-} else {
-/* indirect jump method */
-tcg_out_modrm_offset(s, OPC_GRP5, EXT5_JMPN_Ev, -1,
- (intptr_t)(s->tb_jmp_target_addr + a0));
 }
 set_jmp_reset_offset(s, a0);
 break;
-- 
2.34.1




[PATCH] tcg/riscv: Use tcg_pcrel_diff in tcg_out_ldst

2023-01-17 Thread Richard Henderson
We failed to update this with the w^x split, so misses the fact
that true pc-relative offsets are usually small.

Signed-off-by: Richard Henderson 
---
 tcg/riscv/tcg-target.c.inc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index fc0edd811f..01cb67ef7b 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -599,7 +599,7 @@ static void tcg_out_ldst(TCGContext *s, RISCVInsn opc, 
TCGReg data,
 intptr_t imm12 = sextreg(offset, 0, 12);
 
 if (offset != imm12) {
-intptr_t diff = offset - (uintptr_t)s->code_ptr;
+intptr_t diff = tcg_pcrel_diff(s, (void *)offset);
 
 if (addr == TCG_REG_ZERO && diff == (int32_t)diff) {
 imm12 = sextreg(diff, 0, 12);
-- 
2.34.1




Re: [PATCH v2 0/6] Resolve TYPE_PIIX3_XEN_DEVICE

2023-01-17 Thread Bernhard Beschow



Am 4. Januar 2023 14:44:31 UTC schrieb Bernhard Beschow :
>This series first renders TYPE_PIIX3_XEN_DEVICE redundant and finally removes
>
>it. The motivation is to 1/ decouple PIIX from Xen and 2/ to make Xen in the PC
>
>machine agnostic to the precise southbridge being used. 2/ will become
>
>particularily interesting once PIIX4 becomes usable in the PC machine, avoiding
>
>the "Frankenstein" use of PIIX4_ACPI in PIIX3.
>
>
>
>v2:
>
>- xen_piix3_set_irq() is already generic. Just rename it. (Chuck)
>
>
>
>Testing done:
>
>None, because I don't know how to conduct this properly :(

Ping

Successfully tested by Chuck. Patches 2, 4 and 6 still need review.

I can rebase to master if that eases review -- please let me know. Currently 
this series is based on my "Consolidate PIIX south bridges" series:

>Based-on: <20221221170003.2929-1-shen...@gmail.com>
>
>  "[PATCH v4 00/30] Consolidate PIIX south bridges"
>
>
>
>Bernhard Beschow (6):
>
>  include/hw/xen/xen: Rename xen_piix3_set_irq() to xen_intx_set_irq()
>
>  hw/isa/piix: Reuse piix3_realize() in piix3_xen_realize()
>
>  hw/isa/piix: Wire up Xen PCI IRQ handling outside of PIIX3
>
>  hw/isa/piix: Avoid Xen-specific variant of piix_write_config()
>
>  hw/isa/piix: Resolve redundant k->config_write assignments
>
>  hw/isa/piix: Resolve redundant TYPE_PIIX3_XEN_DEVICE
>
>
>
> hw/i386/pc_piix.c | 34 --
>
> hw/i386/xen/xen-hvm.c |  2 +-
>
> hw/isa/piix.c | 66 +--
>
> include/hw/southbridge/piix.h |  1 -
>
> include/hw/xen/xen.h  |  2 +-
>
> stubs/xen-hw-stub.c   |  2 +-
>
> 6 files changed, 35 insertions(+), 72 deletions(-)
>
>
>
>-- >
>2.39.0
>
>
>



Re: [PATCH qemu v2 3/3] target/arm/gdbstub: Support reading M security extension registers from GDB

2023-01-17 Thread David Reiss
On 1/17/23 1:42 PM, Richard Henderson wrote:
> Is there a reason why these are separate from m_systemreg?

GDB puts these in a separate file, and J-Link puts them in a separate feature 
block.
In general, I think it's nice to separate stuff related to the secure extension
so folks not working with it can ignore it more easily.



Re: [PATCH qemu v2 2/3] target/arm/gdbstub: Support reading M system registers from GDB

2023-01-17 Thread David Reiss



On 1/17/23 1:40 PM, Richard Henderson wrote:
>> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
>> index bf2bce046d..fdbb0d9107 100644
>> --- a/target/arm/cpu.h
>> +++ b/target/arm/cpu.h
>> @@ -856,6 +856,7 @@ struct ArchCPU {
>>     DynamicGDBXMLInfo dyn_sysreg_xml;
>>   DynamicGDBXMLInfo dyn_svereg_xml;
>> +    DynamicGDBXMLInfo dyn_m_systemreg_xml;
> 
> You don't need a new variable here, because a given cpu cannot be both 
> a-profile and m-profile -- dyn_sysreg_xml can hold the xml for the current 
> set of system registers.

Maybe I'm missing something?  It looks like 
arm_cpu_register_gdb_regs_for_features
unconditionally calls

gdb_register_coprocessor(..., arm_gen_dynamic_sysreg_xml(...), ...);

which would cause a collision.



  1   2   3   4   >