[PULL 03/15] hw/intc: Move some files out of the target-specific source set
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
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
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
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
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
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
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[]
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
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
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
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
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
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
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
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
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
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)
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
- 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
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/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/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
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
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
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
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()
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
- 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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.