* Fix emulated LCCB, LOCFHR, MXDB and MXDBR s390x instructions

* Fix the malta machine on s390x (big endian) hosts
 * Emulate /proc/cpuinfo on s390x
 * Remove pointless QOM casts
 * Improve the inclusion logic for libkeyutils and ipmi-bt-test in meson.build
 -----BEGIN PGP SIGNATURE-----
 
 iQJFBAABCAAvFiEEJ7iIR+7gJQEY8+q5LtnXdP5wLbUFAmR+ycgRHHRodXRoQHJl
 ZGhhdC5jb20ACgkQLtnXdP5wLbWXXw//WPz3ng50KLS+M1t3/ULEjO6XkGfP2LQZ
 RsZq3hf9THFPZgcREk+6SQvttOSTuvHNfakfujS6U1Ou5thReWqLe4itFW6+hB5j
 kQ+Sm6YJ+fpezkBnSefcUoL5nA9VVKZ6KE6kxq5CUBZNoIk1sSsfrU8y8wjzW0yg
 2nraOcG10aLpO2BfvKHVEAhJtwl9pHJsFANmHC2/h2wC9BZIAzdxiytzdcJ909gN
 AAa0hIrLK/oFgJjkSSxu+QTaVGPARXqkx5WV546F/zmDMFUWd9nrXaegwqxjgPBN
 m9Ua0SXll5hX2Z57vjJWlbTYkD+JUB22L0N7p5/xzhYRpLVSq1pdveo9psrzIC3E
 Bt7chZB58acQepJHxxa3UHDOHcnfdfaN+Dd9wD29wHr7nK8lOcsen7/7V+5YXomc
 qenkCtkpjKTl07OBxe6MDGZtPZYA8fK1CjEyYwHCe8QvxEzsyg96Bm3j4N2VPxQU
 +f/sFPX7SgogZI4mB4wdoxOF1RmQ+DXQ2tnB970txZRkmFq2jJHpW86jkkbq2Jl1
 KIjgdIXjVgy+MPtuQzO5cT+jfhGQL7FQynGXHjv/UidBid5XD3TDVNa9AthN3Mng
 +rPT90VJ7j9soMqvmNT1COSIRD+M49dQKBIQuq/gWplaTOHaAcJrCwYScwqe0u0P
 zmjCNeuPVw8=
 =dfJr
 -----END PGP SIGNATURE-----

Merge tag 'pull-request-2023-06-06' of https://gitlab.com/thuth/qemu into staging

* Fix emulated LCCB, LOCFHR, MXDB and MXDBR s390x instructions
* Fix the malta machine on s390x (big endian) hosts
* Emulate /proc/cpuinfo on s390x
* Remove pointless QOM casts
* Improve the inclusion logic for libkeyutils and ipmi-bt-test in meson.build

# -----BEGIN PGP SIGNATURE-----
#
# iQJFBAABCAAvFiEEJ7iIR+7gJQEY8+q5LtnXdP5wLbUFAmR+ycgRHHRodXRoQHJl
# ZGhhdC5jb20ACgkQLtnXdP5wLbWXXw//WPz3ng50KLS+M1t3/ULEjO6XkGfP2LQZ
# RsZq3hf9THFPZgcREk+6SQvttOSTuvHNfakfujS6U1Ou5thReWqLe4itFW6+hB5j
# kQ+Sm6YJ+fpezkBnSefcUoL5nA9VVKZ6KE6kxq5CUBZNoIk1sSsfrU8y8wjzW0yg
# 2nraOcG10aLpO2BfvKHVEAhJtwl9pHJsFANmHC2/h2wC9BZIAzdxiytzdcJ909gN
# AAa0hIrLK/oFgJjkSSxu+QTaVGPARXqkx5WV546F/zmDMFUWd9nrXaegwqxjgPBN
# m9Ua0SXll5hX2Z57vjJWlbTYkD+JUB22L0N7p5/xzhYRpLVSq1pdveo9psrzIC3E
# Bt7chZB58acQepJHxxa3UHDOHcnfdfaN+Dd9wD29wHr7nK8lOcsen7/7V+5YXomc
# qenkCtkpjKTl07OBxe6MDGZtPZYA8fK1CjEyYwHCe8QvxEzsyg96Bm3j4N2VPxQU
# +f/sFPX7SgogZI4mB4wdoxOF1RmQ+DXQ2tnB970txZRkmFq2jJHpW86jkkbq2Jl1
# KIjgdIXjVgy+MPtuQzO5cT+jfhGQL7FQynGXHjv/UidBid5XD3TDVNa9AthN3Mng
# +rPT90VJ7j9soMqvmNT1COSIRD+M49dQKBIQuq/gWplaTOHaAcJrCwYScwqe0u0P
# zmjCNeuPVw8=
# =dfJr
# -----END PGP SIGNATURE-----
# gpg: Signature made Mon 05 Jun 2023 10:53:12 PM PDT
# gpg:                using RSA key 27B88847EEE0250118F3EAB92ED9D774FE702DB5
# gpg:                issuer "thuth@redhat.com"
# gpg: Good signature from "Thomas Huth <th.huth@gmx.de>" [unknown]
# gpg:                 aka "Thomas Huth <thuth@redhat.com>" [unknown]
# gpg:                 aka "Thomas Huth <th.huth@posteo.de>" [unknown]
# gpg:                 aka "Thomas Huth <huth@tuxfamily.org>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 27B8 8847 EEE0 2501 18F3  EAB9 2ED9 D774 FE70 2DB5

* tag 'pull-request-2023-06-06' of https://gitlab.com/thuth/qemu:
  linux-user: Emulate /proc/cpuinfo on s390x
  linux-user/elfload: Introduce elf_hwcap_str() on s390x
  linux-user/elfload: Expose get_elf_hwcap() on s390x
  s390x/tcg: Fix CPU address returned by STIDP
  bulk: Remove pointless QOM casts
  scripts: Add qom-cast-macro-clean-cocci-gen.py
  hw/mips/malta: Fix the malta machine on big endian hosts
  gitlab-ci: Remove unused Python package
  tests/qtest: Run ipmi-bt-test only if CONFIG_IPMI_EXTERN is set
  tests/tcg/s390x: Test MXDB and MXDBR
  target/s390x: Fix MXDB and MXDBR
  Add conditional dependency for libkeyutils
  tests/tcg/s390x: Test single-stepping SVC
  linux-user/s390x: Fix single-stepping SVC
  tests/tcg/s390x: Test LOCFHR
  target/s390x: Fix LOCFHR taking the wrong half of R2
  tests/tcg/s390x: Test LCBB
  target/s390x: Fix LCBB overwriting the top 32 bits

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2023-06-06 07:07:37 -07:00
commit 7ce5a15fa6
46 changed files with 480 additions and 76 deletions

View file

@ -7,7 +7,6 @@
before_script: before_script:
- export TAG="$CI_REGISTRY_IMAGE/qemu/$NAME:latest" - export TAG="$CI_REGISTRY_IMAGE/qemu/$NAME:latest"
- export COMMON_TAG="$CI_REGISTRY/qemu-project/qemu/qemu/$NAME:latest" - export COMMON_TAG="$CI_REGISTRY/qemu-project/qemu/qemu/$NAME:latest"
- apk add python3
- docker login $CI_REGISTRY -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" - docker login $CI_REGISTRY -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD"
- until docker info; do sleep 1; done - until docker info; do sleep 1; done
script: script:

View file

@ -3046,6 +3046,7 @@ F: include/qom/
F: qapi/qom.json F: qapi/qom.json
F: qapi/qdev.json F: qapi/qdev.json
F: scripts/coccinelle/qom-parent-type.cocci F: scripts/coccinelle/qom-parent-type.cocci
F: scripts/qom-cast-macro-clean-cocci-gen.py
F: softmmu/qdev-monitor.c F: softmmu/qdev-monitor.c
F: stubs/qdev.c F: stubs/qdev.c
F: qom/ F: qom/

View file

@ -397,7 +397,7 @@ static void coroutine_fn GRAPH_RDLOCK nbd_reconnect_attempt(BDRVNBDState *s)
/* Finalize previous connection if any */ /* Finalize previous connection if any */
if (s->ioc) { if (s->ioc) {
qio_channel_detach_aio_context(QIO_CHANNEL(s->ioc)); qio_channel_detach_aio_context(s->ioc);
yank_unregister_function(BLOCKDEV_YANK_INSTANCE(s->bs->node_name), yank_unregister_function(BLOCKDEV_YANK_INSTANCE(s->bs->node_name),
nbd_yank, s->bs); nbd_yank, s->bs);
object_unref(OBJECT(s->ioc)); object_unref(OBJECT(s->ioc));
@ -1455,7 +1455,7 @@ static void nbd_yank(void *opaque)
BDRVNBDState *s = (BDRVNBDState *)bs->opaque; BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
QEMU_LOCK_GUARD(&s->requests_lock); QEMU_LOCK_GUARD(&s->requests_lock);
qio_channel_shutdown(QIO_CHANNEL(s->ioc), QIO_CHANNEL_SHUTDOWN_BOTH, NULL); qio_channel_shutdown(s->ioc, QIO_CHANNEL_SHUTDOWN_BOTH, NULL);
s->state = NBD_CLIENT_QUIT; s->state = NBD_CLIENT_QUIT;
} }

View file

@ -334,7 +334,7 @@ static void char_pty_open(Chardev *chr,
s = PTY_CHARDEV(chr); s = PTY_CHARDEV(chr);
s->ioc = QIO_CHANNEL(qio_channel_file_new_fd(master_fd)); s->ioc = QIO_CHANNEL(qio_channel_file_new_fd(master_fd));
name = g_strdup_printf("chardev-pty-%s", chr->label); name = g_strdup_printf("chardev-pty-%s", chr->label);
qio_channel_set_name(QIO_CHANNEL(s->ioc), name); qio_channel_set_name(s->ioc, name);
g_free(name); g_free(name);
s->timer_src = NULL; s->timer_src = NULL;
*be_opened = false; *be_opened = false;

View file

@ -1250,7 +1250,7 @@ static void musicpal_init(MachineState *machine)
uart_orgate = DEVICE(object_new(TYPE_OR_IRQ)); uart_orgate = DEVICE(object_new(TYPE_OR_IRQ));
object_property_set_int(OBJECT(uart_orgate), "num-lines", 2, &error_fatal); object_property_set_int(OBJECT(uart_orgate), "num-lines", 2, &error_fatal);
qdev_realize_and_unref(uart_orgate, NULL, &error_fatal); qdev_realize_and_unref(uart_orgate, NULL, &error_fatal);
qdev_connect_gpio_out(DEVICE(uart_orgate), 0, qdev_connect_gpio_out(uart_orgate, 0,
qdev_get_gpio_in(pic, MP_UART_SHARED_IRQ)); qdev_get_gpio_in(pic, MP_UART_SHARED_IRQ));
serial_mm_init(address_space_mem, MP_UART1_BASE, 2, serial_mm_init(address_space_mem, MP_UART1_BASE, 2,

View file

@ -327,7 +327,7 @@ static void versal_create_rtc(Versal *s, qemu_irq *pic)
object_initialize_child(OBJECT(s), "rtc", &s->pmc.rtc, object_initialize_child(OBJECT(s), "rtc", &s->pmc.rtc,
TYPE_XLNX_ZYNQMP_RTC); TYPE_XLNX_ZYNQMP_RTC);
sbd = SYS_BUS_DEVICE(&s->pmc.rtc); sbd = SYS_BUS_DEVICE(&s->pmc.rtc);
sysbus_realize(SYS_BUS_DEVICE(sbd), &error_fatal); sysbus_realize(sbd, &error_fatal);
mr = sysbus_mmio_get_region(sbd, 0); mr = sysbus_mmio_get_region(sbd, 0);
memory_region_add_subregion(&s->mr_ps, MM_PMC_RTC, mr); memory_region_add_subregion(&s->mr_ps, MM_PMC_RTC, mr);

View file

@ -364,11 +364,11 @@ vhost_user_gpu_gl_flushed(VirtIOGPUBase *b)
VhostUserGPU *g = VHOST_USER_GPU(b); VhostUserGPU *g = VHOST_USER_GPU(b);
if (g->backend_blocked) { if (g->backend_blocked) {
vhost_user_gpu_unblock(VHOST_USER_GPU(g)); vhost_user_gpu_unblock(g);
g->backend_blocked = false; g->backend_blocked = false;
} }
vhost_user_gpu_update_blocked(VHOST_USER_GPU(g), false); vhost_user_gpu_update_blocked(g, false);
} }
static bool static bool

View file

@ -276,7 +276,7 @@ static void loongarch_extioi_instance_init(Object *obj)
int i, cpu, pin; int i, cpu, pin;
for (i = 0; i < EXTIOI_IRQS; i++) { for (i = 0; i < EXTIOI_IRQS; i++) {
sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq[i]); sysbus_init_irq(dev, &s->irq[i]);
} }
qdev_init_gpio_in(DEVICE(obj), extioi_setirq, EXTIOI_IRQS); qdev_init_gpio_in(DEVICE(obj), extioi_setirq, EXTIOI_IRQS);
@ -284,14 +284,14 @@ static void loongarch_extioi_instance_init(Object *obj)
for (cpu = 0; cpu < EXTIOI_CPUS; cpu++) { for (cpu = 0; cpu < EXTIOI_CPUS; cpu++) {
memory_region_init_io(&s->extioi_iocsr_mem[cpu], OBJECT(s), &extioi_ops, memory_region_init_io(&s->extioi_iocsr_mem[cpu], OBJECT(s), &extioi_ops,
s, "extioi_iocsr", 0x900); s, "extioi_iocsr", 0x900);
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->extioi_iocsr_mem[cpu]); sysbus_init_mmio(dev, &s->extioi_iocsr_mem[cpu]);
for (pin = 0; pin < LS3A_INTC_IP; pin++) { for (pin = 0; pin < LS3A_INTC_IP; pin++) {
qdev_init_gpio_out(DEVICE(obj), &s->parent_irq[cpu][pin], 1); qdev_init_gpio_out(DEVICE(obj), &s->parent_irq[cpu][pin], 1);
} }
} }
memory_region_init_io(&s->extioi_system_mem, OBJECT(s), &extioi_ops, memory_region_init_io(&s->extioi_system_mem, OBJECT(s), &extioi_ops,
s, "extioi_system_mem", 0x900); s, "extioi_system_mem", 0x900);
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->extioi_system_mem); sysbus_init_mmio(dev, &s->extioi_system_mem);
} }
static void loongarch_extioi_class_init(ObjectClass *klass, void *data) static void loongarch_extioi_class_init(ObjectClass *klass, void *data)

View file

@ -525,7 +525,7 @@ static void q800_init(MachineState *machine)
qdev_realize_and_unref(escc_orgate, NULL, &error_fatal); qdev_realize_and_unref(escc_orgate, NULL, &error_fatal);
sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(escc_orgate, 0)); sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(escc_orgate, 0));
sysbus_connect_irq(sysbus, 1, qdev_get_gpio_in(escc_orgate, 1)); sysbus_connect_irq(sysbus, 1, qdev_get_gpio_in(escc_orgate, 1));
qdev_connect_gpio_out(DEVICE(escc_orgate), 0, qdev_connect_gpio_out(escc_orgate, 0,
qdev_get_gpio_in(glue, GLUE_IRQ_IN_ESCC)); qdev_get_gpio_in(glue, GLUE_IRQ_IN_ESCC));
sysbus_mmio_map(sysbus, 0, SCC_BASE); sysbus_mmio_map(sysbus, 0, SCC_BASE);

View file

@ -629,9 +629,9 @@ static void bl_setup_gt64120_jump_kernel(void **p, uint64_t run_addr,
/* Bus endianess is always reversed */ /* Bus endianess is always reversed */
#if TARGET_BIG_ENDIAN #if TARGET_BIG_ENDIAN
#define cpu_to_gt32 cpu_to_le32 #define cpu_to_gt32(x) (x)
#else #else
#define cpu_to_gt32 cpu_to_be32 #define cpu_to_gt32(x) bswap32(x)
#endif #endif
/* setup MEM-to-PCI0 mapping as done by YAMON */ /* setup MEM-to-PCI0 mapping as done by YAMON */

View file

@ -656,7 +656,7 @@ static void bonito_pci_realize(PCIDevice *dev, Error **errp)
PCIBonitoState *s = PCI_BONITO(dev); PCIBonitoState *s = PCI_BONITO(dev);
SysBusDevice *sysbus = SYS_BUS_DEVICE(s->pcihost); SysBusDevice *sysbus = SYS_BUS_DEVICE(s->pcihost);
PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost); PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost);
BonitoState *bs = BONITO_PCI_HOST_BRIDGE(s->pcihost); BonitoState *bs = s->pcihost;
MemoryRegion *pcimem_alias = g_new(MemoryRegion, 1); MemoryRegion *pcimem_alias = g_new(MemoryRegion, 1);
/* /*

View file

@ -744,7 +744,7 @@ static void pnv_lpc_realize(DeviceState *dev, Error **errp)
memory_region_add_subregion(&lpc->opb_mr, LPC_HC_REGS_OPB_ADDR, memory_region_add_subregion(&lpc->opb_mr, LPC_HC_REGS_OPB_ADDR,
&lpc->lpc_hc_regs); &lpc->lpc_hc_regs);
qdev_init_gpio_out(DEVICE(dev), &lpc->psi_irq, 1); qdev_init_gpio_out(dev, &lpc->psi_irq, 1);
} }
static void pnv_lpc_class_init(ObjectClass *klass, void *data) static void pnv_lpc_class_init(ObjectClass *klass, void *data)

View file

@ -278,7 +278,7 @@ static void pnv_occ_realize(DeviceState *dev, Error **errp)
occ, "occ-common-area", occ, "occ-common-area",
PNV_OCC_SENSOR_DATA_BLOCK_SIZE); PNV_OCC_SENSOR_DATA_BLOCK_SIZE);
qdev_init_gpio_out(DEVICE(dev), &occ->psi_irq, 1); qdev_init_gpio_out(dev, &occ->psi_irq, 1);
} }
static void pnv_occ_class_init(ObjectClass *klass, void *data) static void pnv_occ_class_init(ObjectClass *klass, void *data)

View file

@ -381,7 +381,7 @@ static void pnv_sbe_realize(DeviceState *dev, Error **errp)
psc->xscom_mbox_ops, sbe, "xscom-sbe-mbox", psc->xscom_mbox_ops, sbe, "xscom-sbe-mbox",
psc->xscom_mbox_size); psc->xscom_mbox_size);
qdev_init_gpio_out(DEVICE(dev), &sbe->psi_irq, 1); qdev_init_gpio_out(dev, &sbe->psi_irq, 1);
sbe->timer = timer_new_us(QEMU_CLOCK_VIRTUAL, sbe_timer, sbe); sbe->timer = timer_new_us(QEMU_CLOCK_VIRTUAL, sbe_timer, sbe);
} }

View file

@ -1488,7 +1488,7 @@ static void virt_machine_init(MachineState *machine)
for (i = 0; i < VIRTIO_COUNT; i++) { for (i = 0; i < VIRTIO_COUNT; i++) {
sysbus_create_simple("virtio-mmio", sysbus_create_simple("virtio-mmio",
memmap[VIRT_VIRTIO].base + i * memmap[VIRT_VIRTIO].size, memmap[VIRT_VIRTIO].base + i * memmap[VIRT_VIRTIO].size,
qdev_get_gpio_in(DEVICE(virtio_irqchip), VIRTIO_IRQ + i)); qdev_get_gpio_in(virtio_irqchip, VIRTIO_IRQ + i));
} }
gpex_pcie_init(system_memory, gpex_pcie_init(system_memory,
@ -1499,16 +1499,16 @@ static void virt_machine_init(MachineState *machine)
virt_high_pcie_memmap.base, virt_high_pcie_memmap.base,
virt_high_pcie_memmap.size, virt_high_pcie_memmap.size,
memmap[VIRT_PCIE_PIO].base, memmap[VIRT_PCIE_PIO].base,
DEVICE(pcie_irqchip)); pcie_irqchip);
create_platform_bus(s, DEVICE(mmio_irqchip)); create_platform_bus(s, mmio_irqchip);
serial_mm_init(system_memory, memmap[VIRT_UART0].base, serial_mm_init(system_memory, memmap[VIRT_UART0].base,
0, qdev_get_gpio_in(DEVICE(mmio_irqchip), UART0_IRQ), 399193, 0, qdev_get_gpio_in(mmio_irqchip, UART0_IRQ), 399193,
serial_hd(0), DEVICE_LITTLE_ENDIAN); serial_hd(0), DEVICE_LITTLE_ENDIAN);
sysbus_create_simple("goldfish_rtc", memmap[VIRT_RTC].base, sysbus_create_simple("goldfish_rtc", memmap[VIRT_RTC].base,
qdev_get_gpio_in(DEVICE(mmio_irqchip), RTC_IRQ)); qdev_get_gpio_in(mmio_irqchip, RTC_IRQ));
virt_flash_create(s); virt_flash_create(s);

View file

@ -154,7 +154,7 @@ static void register_icu(RX62NState *s)
sysbus_connect_irq(icu, 0, qdev_get_gpio_in(DEVICE(&s->cpu), RX_CPU_IRQ)); sysbus_connect_irq(icu, 0, qdev_get_gpio_in(DEVICE(&s->cpu), RX_CPU_IRQ));
sysbus_connect_irq(icu, 1, qdev_get_gpio_in(DEVICE(&s->cpu), RX_CPU_FIR)); sysbus_connect_irq(icu, 1, qdev_get_gpio_in(DEVICE(&s->cpu), RX_CPU_FIR));
sysbus_connect_irq(icu, 2, s->irq[SWI]); sysbus_connect_irq(icu, 2, s->irq[SWI]);
sysbus_mmio_map(SYS_BUS_DEVICE(icu), 0, RX62N_ICU_BASE); sysbus_mmio_map(icu, 0, RX62N_ICU_BASE);
} }
static void register_tmr(RX62NState *s, int unit) static void register_tmr(RX62NState *s, int unit)

View file

@ -79,7 +79,7 @@ struct PCIESPState {
static void esp_pci_handle_idle(PCIESPState *pci, uint32_t val) static void esp_pci_handle_idle(PCIESPState *pci, uint32_t val)
{ {
ESPState *s = ESP(&pci->esp); ESPState *s = &pci->esp;
trace_esp_pci_dma_idle(val); trace_esp_pci_dma_idle(val);
esp_dma_enable(s, 0, 0); esp_dma_enable(s, 0, 0);
@ -93,7 +93,7 @@ static void esp_pci_handle_blast(PCIESPState *pci, uint32_t val)
static void esp_pci_handle_abort(PCIESPState *pci, uint32_t val) static void esp_pci_handle_abort(PCIESPState *pci, uint32_t val)
{ {
ESPState *s = ESP(&pci->esp); ESPState *s = &pci->esp;
trace_esp_pci_dma_abort(val); trace_esp_pci_dma_abort(val);
if (s->current_req) { if (s->current_req) {
@ -103,7 +103,7 @@ static void esp_pci_handle_abort(PCIESPState *pci, uint32_t val)
static void esp_pci_handle_start(PCIESPState *pci, uint32_t val) static void esp_pci_handle_start(PCIESPState *pci, uint32_t val)
{ {
ESPState *s = ESP(&pci->esp); ESPState *s = &pci->esp;
trace_esp_pci_dma_start(val); trace_esp_pci_dma_start(val);
@ -161,7 +161,7 @@ static void esp_pci_dma_write(PCIESPState *pci, uint32_t saddr, uint32_t val)
static uint32_t esp_pci_dma_read(PCIESPState *pci, uint32_t saddr) static uint32_t esp_pci_dma_read(PCIESPState *pci, uint32_t saddr)
{ {
ESPState *s = ESP(&pci->esp); ESPState *s = &pci->esp;
uint32_t val; uint32_t val;
val = pci->dma_regs[saddr]; val = pci->dma_regs[saddr];
@ -183,7 +183,7 @@ static void esp_pci_io_write(void *opaque, hwaddr addr,
uint64_t val, unsigned int size) uint64_t val, unsigned int size)
{ {
PCIESPState *pci = opaque; PCIESPState *pci = opaque;
ESPState *s = ESP(&pci->esp); ESPState *s = &pci->esp;
if (size < 4 || addr & 3) { if (size < 4 || addr & 3) {
/* need to upgrade request: we only support 4-bytes accesses */ /* need to upgrade request: we only support 4-bytes accesses */
@ -228,7 +228,7 @@ static uint64_t esp_pci_io_read(void *opaque, hwaddr addr,
unsigned int size) unsigned int size)
{ {
PCIESPState *pci = opaque; PCIESPState *pci = opaque;
ESPState *s = ESP(&pci->esp); ESPState *s = &pci->esp;
uint32_t ret; uint32_t ret;
if (addr < 0x40) { if (addr < 0x40) {
@ -315,7 +315,7 @@ static const MemoryRegionOps esp_pci_io_ops = {
static void esp_pci_hard_reset(DeviceState *dev) static void esp_pci_hard_reset(DeviceState *dev)
{ {
PCIESPState *pci = PCI_ESP(dev); PCIESPState *pci = PCI_ESP(dev);
ESPState *s = ESP(&pci->esp); ESPState *s = &pci->esp;
esp_hard_reset(s); esp_hard_reset(s);
pci->dma_regs[DMA_CMD] &= ~(DMA_CMD_DIR | DMA_CMD_INTE_D | DMA_CMD_INTE_P pci->dma_regs[DMA_CMD] &= ~(DMA_CMD_DIR | DMA_CMD_INTE_D | DMA_CMD_INTE_P
@ -366,7 +366,7 @@ static void esp_pci_scsi_realize(PCIDevice *dev, Error **errp)
{ {
PCIESPState *pci = PCI_ESP(dev); PCIESPState *pci = PCI_ESP(dev);
DeviceState *d = DEVICE(dev); DeviceState *d = DEVICE(dev);
ESPState *s = ESP(&pci->esp); ESPState *s = &pci->esp;
uint8_t *pci_conf; uint8_t *pci_conf;
if (!qdev_realize(DEVICE(s), NULL, errp)) { if (!qdev_realize(DEVICE(s), NULL, errp)) {
@ -394,7 +394,7 @@ static void esp_pci_scsi_realize(PCIDevice *dev, Error **errp)
static void esp_pci_scsi_exit(PCIDevice *d) static void esp_pci_scsi_exit(PCIDevice *d)
{ {
PCIESPState *pci = PCI_ESP(d); PCIESPState *pci = PCI_ESP(d);
ESPState *s = ESP(&pci->esp); ESPState *s = &pci->esp;
qemu_free_irq(s->irq); qemu_free_irq(s->irq);
} }

View file

@ -982,7 +982,7 @@ static void sun4m_hw_init(MachineState *machine)
qdev_realize_and_unref(ms_kb_orgate, NULL, &error_fatal); qdev_realize_and_unref(ms_kb_orgate, NULL, &error_fatal);
sysbus_connect_irq(s, 0, qdev_get_gpio_in(ms_kb_orgate, 0)); sysbus_connect_irq(s, 0, qdev_get_gpio_in(ms_kb_orgate, 0));
sysbus_connect_irq(s, 1, qdev_get_gpio_in(ms_kb_orgate, 1)); sysbus_connect_irq(s, 1, qdev_get_gpio_in(ms_kb_orgate, 1));
qdev_connect_gpio_out(DEVICE(ms_kb_orgate), 0, slavio_irq[14]); qdev_connect_gpio_out(ms_kb_orgate, 0, slavio_irq[14]);
dev = qdev_new(TYPE_ESCC); dev = qdev_new(TYPE_ESCC);
qdev_prop_set_uint32(dev, "disabled", 0); qdev_prop_set_uint32(dev, "disabled", 0);
@ -1004,7 +1004,7 @@ static void sun4m_hw_init(MachineState *machine)
qdev_realize_and_unref(serial_orgate, NULL, &error_fatal); qdev_realize_and_unref(serial_orgate, NULL, &error_fatal);
sysbus_connect_irq(s, 0, qdev_get_gpio_in(serial_orgate, 0)); sysbus_connect_irq(s, 0, qdev_get_gpio_in(serial_orgate, 0));
sysbus_connect_irq(s, 1, qdev_get_gpio_in(serial_orgate, 1)); sysbus_connect_irq(s, 1, qdev_get_gpio_in(serial_orgate, 1));
qdev_connect_gpio_out(DEVICE(serial_orgate), 0, slavio_irq[15]); qdev_connect_gpio_out(serial_orgate, 0, slavio_irq[15]);
if (hwdef->apc_base) { if (hwdef->apc_base) {
apc_init(hwdef->apc_base, qemu_allocate_irq(cpu_halt_signal, NULL, 0)); apc_init(hwdef->apc_base, qemu_allocate_irq(cpu_halt_signal, NULL, 0));

View file

@ -42,7 +42,7 @@ static MemoryRegion *virtio_mem_pci_get_memory_region(MemoryDeviceState *md,
Error **errp) Error **errp)
{ {
VirtIOMEMPCI *pci_mem = VIRTIO_MEM_PCI(md); VirtIOMEMPCI *pci_mem = VIRTIO_MEM_PCI(md);
VirtIOMEM *vmem = VIRTIO_MEM(&pci_mem->vdev); VirtIOMEM *vmem = &pci_mem->vdev;
VirtIOMEMClass *vmc = VIRTIO_MEM_GET_CLASS(vmem); VirtIOMEMClass *vmc = VIRTIO_MEM_GET_CLASS(vmem);
return vmc->get_memory_region(vmem, errp); return vmc->get_memory_region(vmem, errp);
@ -60,7 +60,7 @@ static void virtio_mem_pci_fill_device_info(const MemoryDeviceState *md,
{ {
VirtioMEMDeviceInfo *vi = g_new0(VirtioMEMDeviceInfo, 1); VirtioMEMDeviceInfo *vi = g_new0(VirtioMEMDeviceInfo, 1);
VirtIOMEMPCI *pci_mem = VIRTIO_MEM_PCI(md); VirtIOMEMPCI *pci_mem = VIRTIO_MEM_PCI(md);
VirtIOMEM *vmem = VIRTIO_MEM(&pci_mem->vdev); VirtIOMEM *vmem = &pci_mem->vdev;
VirtIOMEMClass *vpc = VIRTIO_MEM_GET_CLASS(vmem); VirtIOMEMClass *vpc = VIRTIO_MEM_GET_CLASS(vmem);
DeviceState *dev = DEVICE(md); DeviceState *dev = DEVICE(md);
@ -123,7 +123,7 @@ static void virtio_mem_pci_instance_init(Object *obj)
TYPE_VIRTIO_MEM); TYPE_VIRTIO_MEM);
dev->size_change_notifier.notify = virtio_mem_pci_size_change_notify; dev->size_change_notifier.notify = virtio_mem_pci_size_change_notify;
vmem = VIRTIO_MEM(&dev->vdev); vmem = &dev->vdev;
vmc = VIRTIO_MEM_GET_CLASS(vmem); vmc = VIRTIO_MEM_GET_CLASS(vmem);
/* /*
* We never remove the notifier again, as we expect both devices to * We never remove the notifier again, as we expect both devices to

View file

@ -42,7 +42,7 @@ static MemoryRegion *virtio_pmem_pci_get_memory_region(MemoryDeviceState *md,
Error **errp) Error **errp)
{ {
VirtIOPMEMPCI *pci_pmem = VIRTIO_PMEM_PCI(md); VirtIOPMEMPCI *pci_pmem = VIRTIO_PMEM_PCI(md);
VirtIOPMEM *pmem = VIRTIO_PMEM(&pci_pmem->vdev); VirtIOPMEM *pmem = &pci_pmem->vdev;
VirtIOPMEMClass *vpc = VIRTIO_PMEM_GET_CLASS(pmem); VirtIOPMEMClass *vpc = VIRTIO_PMEM_GET_CLASS(pmem);
return vpc->get_memory_region(pmem, errp); return vpc->get_memory_region(pmem, errp);
@ -52,7 +52,7 @@ static uint64_t virtio_pmem_pci_get_plugged_size(const MemoryDeviceState *md,
Error **errp) Error **errp)
{ {
VirtIOPMEMPCI *pci_pmem = VIRTIO_PMEM_PCI(md); VirtIOPMEMPCI *pci_pmem = VIRTIO_PMEM_PCI(md);
VirtIOPMEM *pmem = VIRTIO_PMEM(&pci_pmem->vdev); VirtIOPMEM *pmem = &pci_pmem->vdev;
VirtIOPMEMClass *vpc = VIRTIO_PMEM_GET_CLASS(pmem); VirtIOPMEMClass *vpc = VIRTIO_PMEM_GET_CLASS(pmem);
MemoryRegion *mr = vpc->get_memory_region(pmem, errp); MemoryRegion *mr = vpc->get_memory_region(pmem, errp);
@ -65,7 +65,7 @@ static void virtio_pmem_pci_fill_device_info(const MemoryDeviceState *md,
{ {
VirtioPMEMDeviceInfo *vi = g_new0(VirtioPMEMDeviceInfo, 1); VirtioPMEMDeviceInfo *vi = g_new0(VirtioPMEMDeviceInfo, 1);
VirtIOPMEMPCI *pci_pmem = VIRTIO_PMEM_PCI(md); VirtIOPMEMPCI *pci_pmem = VIRTIO_PMEM_PCI(md);
VirtIOPMEM *pmem = VIRTIO_PMEM(&pci_pmem->vdev); VirtIOPMEM *pmem = &pci_pmem->vdev;
VirtIOPMEMClass *vpc = VIRTIO_PMEM_GET_CLASS(pmem); VirtIOPMEMClass *vpc = VIRTIO_PMEM_GET_CLASS(pmem);
DeviceState *dev = DEVICE(md); DeviceState *dev = DEVICE(md);

View file

@ -1583,7 +1583,7 @@ static inline void init_thread(struct target_pt_regs *regs,
#define GET_FEATURE(_feat, _hwcap) \ #define GET_FEATURE(_feat, _hwcap) \
do { if (s390_has_feat(_feat)) { hwcap |= _hwcap; } } while (0) do { if (s390_has_feat(_feat)) { hwcap |= _hwcap; } } while (0)
static uint32_t get_elf_hwcap(void) uint32_t get_elf_hwcap(void)
{ {
/* /*
* Let's assume we always have esan3 and zarch. * Let's assume we always have esan3 and zarch.
@ -1605,6 +1605,33 @@ static uint32_t get_elf_hwcap(void)
return hwcap; return hwcap;
} }
const char *elf_hwcap_str(uint32_t bit)
{
static const char *hwcap_str[] = {
[HWCAP_S390_ESAN3] = "esan3",
[HWCAP_S390_ZARCH] = "zarch",
[HWCAP_S390_STFLE] = "stfle",
[HWCAP_S390_MSA] = "msa",
[HWCAP_S390_LDISP] = "ldisp",
[HWCAP_S390_EIMM] = "eimm",
[HWCAP_S390_DFP] = "dfp",
[HWCAP_S390_HPAGE] = "edat",
[HWCAP_S390_ETF3EH] = "etf3eh",
[HWCAP_S390_HIGH_GPRS] = "highgprs",
[HWCAP_S390_TE] = "te",
[HWCAP_S390_VXRS] = "vx",
[HWCAP_S390_VXRS_BCD] = "vxd",
[HWCAP_S390_VXRS_EXT] = "vxe",
[HWCAP_S390_GS] = "gs",
[HWCAP_S390_VXRS_EXT2] = "vxe2",
[HWCAP_S390_VXRS_PDE] = "vxp",
[HWCAP_S390_SORT] = "sort",
[HWCAP_S390_DFLT] = "dflt",
};
return bit < ARRAY_SIZE(hwcap_str) ? hwcap_str[bit] : NULL;
}
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
{ {
regs->psw.addr = infop->entry; regs->psw.addr = infop->entry;

View file

@ -56,4 +56,9 @@ abi_long memcpy_to_target(abi_ulong dest, const void *src,
extern unsigned long guest_stack_size; extern unsigned long guest_stack_size;
#ifdef TARGET_S390X
uint32_t get_elf_hwcap(void);
const char *elf_hwcap_str(uint32_t bit);
#endif
#endif /* LINUX_USER_LOADER_H */ #endif /* LINUX_USER_LOADER_H */

View file

@ -86,6 +86,15 @@ void cpu_loop(CPUS390XState *env)
} else if (ret != -QEMU_ESIGRETURN) { } else if (ret != -QEMU_ESIGRETURN) {
env->regs[2] = ret; env->regs[2] = ret;
} }
if (unlikely(cs->singlestep_enabled)) {
/*
* cpu_tb_exec() did not raise EXCP_DEBUG, because it has seen
* that EXCP_SVC was already pending.
*/
cs->exception_index = EXCP_DEBUG;
}
break; break;
case EXCP_DEBUG: case EXCP_DEBUG:

View file

@ -8232,7 +8232,7 @@ void target_exception_dump(CPUArchState *env, const char *fmt, int code)
#if HOST_BIG_ENDIAN != TARGET_BIG_ENDIAN || \ #if HOST_BIG_ENDIAN != TARGET_BIG_ENDIAN || \
defined(TARGET_SPARC) || defined(TARGET_M68K) || defined(TARGET_HPPA) || \ defined(TARGET_SPARC) || defined(TARGET_M68K) || defined(TARGET_HPPA) || \
defined(TARGET_RISCV) defined(TARGET_RISCV) || defined(TARGET_S390X)
static int is_proc(const char *filename, const char *entry) static int is_proc(const char *filename, const char *entry)
{ {
return strcmp(filename, entry) == 0; return strcmp(filename, entry) == 0;
@ -8339,6 +8339,107 @@ static int open_cpuinfo(CPUArchState *cpu_env, int fd)
} }
#endif #endif
#if defined(TARGET_S390X)
/*
* Emulate what a Linux kernel running in qemu-system-s390x -M accel=tcg would
* show in /proc/cpuinfo.
*
* Skip the following in order to match the missing support in op_ecag():
* - show_cacheinfo().
* - show_cpu_topology().
* - show_cpu_mhz().
*
* Use fixed values for certain fields:
* - bogomips per cpu - from a qemu-system-s390x run.
* - max thread id = 0, since SMT / SIGP_SET_MULTI_THREADING is not supported.
*
* Keep the code structure close to arch/s390/kernel/processor.c.
*/
static void show_facilities(int fd)
{
size_t sizeof_stfl_bytes = 2048;
g_autofree uint8_t *stfl_bytes = g_new0(uint8_t, sizeof_stfl_bytes);
unsigned int bit;
dprintf(fd, "facilities :");
s390_get_feat_block(S390_FEAT_TYPE_STFL, stfl_bytes);
for (bit = 0; bit < sizeof_stfl_bytes * 8; bit++) {
if (test_be_bit(bit, stfl_bytes)) {
dprintf(fd, " %d", bit);
}
}
dprintf(fd, "\n");
}
static int cpu_ident(unsigned long n)
{
return deposit32(0, CPU_ID_BITS - CPU_PHYS_ADDR_BITS, CPU_PHYS_ADDR_BITS,
n);
}
static void show_cpu_summary(CPUArchState *cpu_env, int fd)
{
S390CPUModel *model = env_archcpu(cpu_env)->model;
int num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
uint32_t elf_hwcap = get_elf_hwcap();
const char *hwcap_str;
int i;
dprintf(fd, "vendor_id : IBM/S390\n"
"# processors : %i\n"
"bogomips per cpu: 13370.00\n",
num_cpus);
dprintf(fd, "max thread id : 0\n");
dprintf(fd, "features\t: ");
for (i = 0; i < sizeof(elf_hwcap) * 8; i++) {
if (!(elf_hwcap & (1 << i))) {
continue;
}
hwcap_str = elf_hwcap_str(i);
if (hwcap_str) {
dprintf(fd, "%s ", hwcap_str);
}
}
dprintf(fd, "\n");
show_facilities(fd);
for (i = 0; i < num_cpus; i++) {
dprintf(fd, "processor %d: "
"version = %02X, "
"identification = %06X, "
"machine = %04X\n",
i, model->cpu_ver, cpu_ident(i), model->def->type);
}
}
static void show_cpu_ids(CPUArchState *cpu_env, int fd, unsigned long n)
{
S390CPUModel *model = env_archcpu(cpu_env)->model;
dprintf(fd, "version : %02X\n", model->cpu_ver);
dprintf(fd, "identification : %06X\n", cpu_ident(n));
dprintf(fd, "machine : %04X\n", model->def->type);
}
static void show_cpuinfo(CPUArchState *cpu_env, int fd, unsigned long n)
{
dprintf(fd, "\ncpu number : %ld\n", n);
show_cpu_ids(cpu_env, fd, n);
}
static int open_cpuinfo(CPUArchState *cpu_env, int fd)
{
int num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
int i;
show_cpu_summary(cpu_env, fd);
for (i = 0; i < num_cpus; i++) {
show_cpuinfo(cpu_env, fd, i);
}
return 0;
}
#endif
#if defined(TARGET_M68K) #if defined(TARGET_M68K)
static int open_hardware(CPUArchState *cpu_env, int fd) static int open_hardware(CPUArchState *cpu_env, int fd)
{ {
@ -8363,7 +8464,8 @@ static int do_openat(CPUArchState *cpu_env, int dirfd, const char *pathname, int
#if HOST_BIG_ENDIAN != TARGET_BIG_ENDIAN #if HOST_BIG_ENDIAN != TARGET_BIG_ENDIAN
{ "/proc/net/route", open_net_route, is_proc }, { "/proc/net/route", open_net_route, is_proc },
#endif #endif
#if defined(TARGET_SPARC) || defined(TARGET_HPPA) || defined(TARGET_RISCV) #if defined(TARGET_SPARC) || defined(TARGET_HPPA) || \
defined(TARGET_RISCV) || defined(TARGET_S390X)
{ "/proc/cpuinfo", open_cpuinfo, is_proc }, { "/proc/cpuinfo", open_cpuinfo, is_proc },
#endif #endif
#if defined(TARGET_M68K) #if defined(TARGET_M68K)

View file

@ -1781,8 +1781,10 @@ if gnutls.found()
tasn1 = dependency('libtasn1', tasn1 = dependency('libtasn1',
method: 'pkg-config') method: 'pkg-config')
endif endif
keyutils = dependency('libkeyutils', required: false, keyutils = not_found
method: 'pkg-config') if get_option('keyring').enabled()
keyutils = dependency('libkeyutils', required: false, method: 'pkg-config')
endif
has_gettid = cc.has_function('gettid') has_gettid = cc.has_function('gettid')

View file

@ -38,7 +38,7 @@ void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **
return; return;
} }
qio_channel_set_name(QIO_CHANNEL(ioc), "migration-fd-outgoing"); qio_channel_set_name(ioc, "migration-fd-outgoing");
migration_channel_connect(s, ioc, NULL, NULL); migration_channel_connect(s, ioc, NULL, NULL);
object_unref(OBJECT(ioc)); object_unref(OBJECT(ioc));
} }
@ -68,7 +68,7 @@ void fd_start_incoming_migration(const char *fdname, Error **errp)
return; return;
} }
qio_channel_set_name(QIO_CHANNEL(ioc), "migration-fd-incoming"); qio_channel_set_name(ioc, "migration-fd-incoming");
qio_channel_add_watch_full(ioc, G_IO_IN, qio_channel_add_watch_full(ioc, G_IO_IN,
fd_accept_incoming_migration, fd_accept_incoming_migration,
NULL, NULL, NULL, NULL,

View file

@ -894,7 +894,7 @@ static void multifd_new_send_channel_async(QIOTask *task, gpointer opaque)
trace_multifd_new_send_channel_async(p->id); trace_multifd_new_send_channel_async(p->id);
if (!qio_task_propagate_error(task, &local_err)) { if (!qio_task_propagate_error(task, &local_err)) {
p->c = QIO_CHANNEL(sioc); p->c = sioc;
qio_channel_set_delay(p->c, false); qio_channel_set_delay(p->c, false);
p->running = true; p->running = true;
if (multifd_channel_connect(p, sioc, local_err)) { if (multifd_channel_connect(p, sioc, local_err)) {

View file

@ -35,7 +35,7 @@ void migration_ioc_register_yank(QIOChannel *ioc)
if (migration_ioc_yank_supported(ioc)) { if (migration_ioc_yank_supported(ioc)) {
yank_register_function(MIGRATION_YANK_INSTANCE, yank_register_function(MIGRATION_YANK_INSTANCE,
migration_yank_iochannel, migration_yank_iochannel,
QIO_CHANNEL(ioc)); ioc);
} }
} }
@ -44,7 +44,7 @@ void migration_ioc_unregister_yank(QIOChannel *ioc)
if (migration_ioc_yank_supported(ioc)) { if (migration_ioc_yank_supported(ioc)) {
yank_unregister_function(MIGRATION_YANK_INSTANCE, yank_unregister_function(MIGRATION_YANK_INSTANCE,
migration_yank_iochannel, migration_yank_iochannel,
QIO_CHANNEL(ioc)); ioc);
} }
} }

View file

@ -156,7 +156,7 @@ static int nbd_connect(QIOChannelSocket *sioc, SocketAddress *addr,
* channel. * channel.
*/ */
if (outioc && *outioc) { if (outioc && *outioc) {
qio_channel_close(QIO_CHANNEL(*outioc), NULL); qio_channel_close(*outioc, NULL);
object_unref(OBJECT(*outioc)); object_unref(OBJECT(*outioc));
*outioc = NULL; *outioc = NULL;
} else { } else {

View file

@ -1189,7 +1189,7 @@ static int nbd_negotiate_options(NBDClient *client, Error **errp)
} }
ret = 0; ret = 0;
object_unref(OBJECT(client->ioc)); object_unref(OBJECT(client->ioc));
client->ioc = QIO_CHANNEL(tioc); client->ioc = tioc;
break; break;
case NBD_OPT_EXPORT_NAME: case NBD_OPT_EXPORT_NAME:

View file

@ -0,0 +1,49 @@
#!/usr/bin/env python3
#
# Generate a Coccinelle semantic patch to remove pointless QOM cast.
#
# Usage:
#
# $ qom-cast-macro-clean-cocci-gen.py $(git ls-files) > qom_pointless_cast.cocci
# $ spatch \
# --macro-file scripts/cocci-macro-file.h \
# --sp-file qom_pointless_cast.cocci \
# --keep-comments \
# --use-gitgrep \
# --in-place \
# --dir .
#
# SPDX-FileContributor: Philippe Mathieu-Daudé <philmd@linaro.org>
# SPDX-FileCopyrightText: 2023 Linaro Ltd.
# SPDX-License-Identifier: GPL-2.0-or-later
import re
import sys
assert len(sys.argv) > 0
def print_cocci_rule(qom_typedef, qom_cast_macro):
print(f'''@@
typedef {qom_typedef};
{qom_typedef} *obj;
@@
- {qom_cast_macro}(obj)
+ obj
''')
patterns = [
r'DECLARE_INSTANCE_CHECKER\((\w+),\W*(\w+),\W*TYPE_\w+\)',
r'DECLARE_OBJ_CHECKERS\((\w+),\W*\w+,\W*(\w+),\W*TYPE_\w+\)',
r'OBJECT_DECLARE_TYPE\((\w+),\W*\w+,\W*(\w+)\)',
r'OBJECT_DECLARE_SIMPLE_TYPE\((\w+),\W*(\w+)\)',
r'INTERFACE_CHECK\((\w+),\W*\(\w+\),\W*TYPE_(\w+)\)',
]
for fn in sys.argv[1:]:
try:
content = open(fn, 'rt').read()
except:
continue
for pattern in patterns:
for match in re.findall(pattern, content):
print_cocci_rule(match[0], match[1])

View file

@ -711,7 +711,7 @@ DeviceState *qdev_device_add_from_qdict(const QDict *opts,
goto err_del_dev; goto err_del_dev;
} }
if (!qdev_realize(DEVICE(dev), bus, errp)) { if (!qdev_realize(dev, bus, errp)) {
goto err_del_dev; goto err_del_dev;
} }
return dev; return dev;

View file

@ -607,8 +607,8 @@ void s390_realize_cpu_model(CPUState *cs, Error **errp)
#if !defined(CONFIG_USER_ONLY) #if !defined(CONFIG_USER_ONLY)
cpu->env.cpuid = s390_cpuid_from_cpu_model(cpu->model); cpu->env.cpuid = s390_cpuid_from_cpu_model(cpu->model);
if (tcg_enabled()) { if (tcg_enabled()) {
/* basic mode, write the cpu address into the first 4 bit of the ID */ cpu->env.cpuid = deposit64(cpu->env.cpuid, CPU_PHYS_ADDR_SHIFT,
cpu->env.cpuid = deposit64(cpu->env.cpuid, 54, 4, cpu->env.core_id); CPU_PHYS_ADDR_BITS, cpu->env.core_id);
} }
#endif #endif
} }

View file

@ -96,10 +96,18 @@ static inline bool s390_known_cpu_type(uint16_t type)
{ {
return s390_get_gen_for_cpu_type(type) != 0; return s390_get_gen_for_cpu_type(type) != 0;
} }
#define CPU_ID_SHIFT 32
#define CPU_ID_BITS 24
/*
* When cpu_id_format is 0 (basic mode), the leftmost 4 bits of cpu_id contain
* the rightmost 4 bits of the physical CPU address.
*/
#define CPU_PHYS_ADDR_BITS 4
#define CPU_PHYS_ADDR_SHIFT (CPU_ID_SHIFT + CPU_ID_BITS - CPU_PHYS_ADDR_BITS)
static inline uint64_t s390_cpuid_from_cpu_model(const S390CPUModel *model) static inline uint64_t s390_cpuid_from_cpu_model(const S390CPUModel *model)
{ {
return ((uint64_t)model->cpu_ver << 56) | return ((uint64_t)model->cpu_ver << 56) |
((uint64_t)model->cpu_id << 32) | ((uint64_t)model->cpu_id << CPU_ID_SHIFT) |
((uint64_t)model->def->type << 16) | ((uint64_t)model->def->type << 16) |
(model->def->gen == 7 ? 0 : (uint64_t)model->cpu_id_format << 15); (model->def->gen == 7 ? 0 : (uint64_t)model->cpu_id_format << 15);
} }

View file

@ -50,7 +50,7 @@ DEF_HELPER_FLAGS_3(meeb, TCG_CALL_NO_WG, i64, env, i64, i64)
DEF_HELPER_FLAGS_3(mdeb, TCG_CALL_NO_WG, i64, env, i64, i64) DEF_HELPER_FLAGS_3(mdeb, TCG_CALL_NO_WG, i64, env, i64, i64)
DEF_HELPER_FLAGS_3(mdb, TCG_CALL_NO_WG, i64, env, i64, i64) DEF_HELPER_FLAGS_3(mdb, TCG_CALL_NO_WG, i64, env, i64, i64)
DEF_HELPER_FLAGS_3(mxb, TCG_CALL_NO_WG, i128, env, i128, i128) DEF_HELPER_FLAGS_3(mxb, TCG_CALL_NO_WG, i128, env, i128, i128)
DEF_HELPER_FLAGS_3(mxdb, TCG_CALL_NO_WG, i128, env, i128, i64) DEF_HELPER_FLAGS_3(mxdb, TCG_CALL_NO_WG, i128, env, i64, i64)
DEF_HELPER_FLAGS_2(ldeb, TCG_CALL_NO_WG, i64, env, i64) DEF_HELPER_FLAGS_2(ldeb, TCG_CALL_NO_WG, i64, env, i64)
DEF_HELPER_FLAGS_3(ldxb, TCG_CALL_NO_WG, i64, env, i128, i32) DEF_HELPER_FLAGS_3(ldxb, TCG_CALL_NO_WG, i64, env, i128, i32)
DEF_HELPER_FLAGS_2(lxdb, TCG_CALL_NO_WG, i128, env, i64) DEF_HELPER_FLAGS_2(lxdb, TCG_CALL_NO_WG, i128, env, i64)

View file

@ -321,10 +321,11 @@ Int128 HELPER(mxb)(CPUS390XState *env, Int128 a, Int128 b)
} }
/* 128/64-bit FP multiplication */ /* 128/64-bit FP multiplication */
Int128 HELPER(mxdb)(CPUS390XState *env, Int128 a, uint64_t f2) Int128 HELPER(mxdb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
{ {
float128 f1_128 = float64_to_float128(f1, &env->fpu_status);
float128 ret = float64_to_float128(f2, &env->fpu_status); float128 ret = float64_to_float128(f2, &env->fpu_status);
ret = float128_mul(ARG128(a), ret, &env->fpu_status); ret = float128_mul(f1_128, ret, &env->fpu_status);
handle_exceptions(env, false, GETPC()); handle_exceptions(env, false, GETPC());
return RET128(ret); return RET128(ret);
} }

View file

@ -486,7 +486,7 @@
F(0xb343, LCXBR, RRE, Z, x2h, x2l, new_P, x1_P, negf128, f128, IF_BFP) F(0xb343, LCXBR, RRE, Z, x2h, x2l, new_P, x1_P, negf128, f128, IF_BFP)
F(0xb373, LCDFR, RRE, FPSSH, 0, f2, new, f1, negf64, 0, IF_AFP1 | IF_AFP2) F(0xb373, LCDFR, RRE, FPSSH, 0, f2, new, f1, negf64, 0, IF_AFP1 | IF_AFP2)
/* LOAD COUNT TO BLOCK BOUNDARY */ /* LOAD COUNT TO BLOCK BOUNDARY */
C(0xe727, LCBB, RXE, V, la2, 0, r1, 0, lcbb, 0) C(0xe727, LCBB, RXE, V, la2, 0, new, r1_32, lcbb, 0)
/* LOAD HALFWORD */ /* LOAD HALFWORD */
C(0xb927, LHR, RRE, EI, 0, r2_16s, 0, r1_32, mov2, 0) C(0xb927, LHR, RRE, EI, 0, r2_16s, 0, r1_32, mov2, 0)
C(0xb907, LGHR, RRE, EI, 0, r2_16s, 0, r1, mov2, 0) C(0xb907, LGHR, RRE, EI, 0, r2_16s, 0, r1, mov2, 0)
@ -564,7 +564,7 @@
C(0xec46, LOCGHI, RIE_g, LOC2, r1, i2, r1, 0, loc, 0) C(0xec46, LOCGHI, RIE_g, LOC2, r1, i2, r1, 0, loc, 0)
C(0xec4e, LOCHHI, RIE_g, LOC2, r1_sr32, i2, new, r1_32h, loc, 0) C(0xec4e, LOCHHI, RIE_g, LOC2, r1_sr32, i2, new, r1_32h, loc, 0)
/* LOAD HIGH ON CONDITION */ /* LOAD HIGH ON CONDITION */
C(0xb9e0, LOCFHR, RRF_c, LOC2, r1_sr32, r2, new, r1_32h, loc, 0) C(0xb9e0, LOCFHR, RRF_c, LOC2, r1_sr32, r2_sr32, new, r1_32h, loc, 0)
C(0xebe0, LOCFH, RSY_b, LOC2, r1_sr32, m2_32u, new, r1_32h, loc, 0) C(0xebe0, LOCFH, RSY_b, LOC2, r1_sr32, m2_32u, new, r1_32h, loc, 0)
/* LOAD PAIR DISJOINT */ /* LOAD PAIR DISJOINT */
D(0xc804, LPD, SSF, ILA, 0, 0, new_P, r3_P32, lpd, 0, MO_TEUL) D(0xc804, LPD, SSF, ILA, 0, 0, new_P, r3_P32, lpd, 0, MO_TEUL)
@ -668,11 +668,11 @@
F(0xb31c, MDBR, RRE, Z, f1, f2, new, f1, mdb, 0, IF_BFP) F(0xb31c, MDBR, RRE, Z, f1, f2, new, f1, mdb, 0, IF_BFP)
F(0xb34c, MXBR, RRE, Z, x1, x2, new_x, x1, mxb, 0, IF_BFP) F(0xb34c, MXBR, RRE, Z, x1, x2, new_x, x1, mxb, 0, IF_BFP)
F(0xb30c, MDEBR, RRE, Z, f1, e2, new, f1, mdeb, 0, IF_BFP) F(0xb30c, MDEBR, RRE, Z, f1, e2, new, f1, mdeb, 0, IF_BFP)
F(0xb307, MXDBR, RRE, Z, 0, f2, x1, x1, mxdb, 0, IF_BFP) F(0xb307, MXDBR, RRE, Z, f1, f2, new_x, x1, mxdb, 0, IF_BFP)
F(0xed17, MEEB, RXE, Z, e1, m2_32u, new, e1, meeb, 0, IF_BFP) F(0xed17, MEEB, RXE, Z, e1, m2_32u, new, e1, meeb, 0, IF_BFP)
F(0xed1c, MDB, RXE, Z, f1, m2_64, new, f1, mdb, 0, IF_BFP) F(0xed1c, MDB, RXE, Z, f1, m2_64, new, f1, mdb, 0, IF_BFP)
F(0xed0c, MDEB, RXE, Z, f1, m2_32u, new, f1, mdeb, 0, IF_BFP) F(0xed0c, MDEB, RXE, Z, f1, m2_32u, new, f1, mdeb, 0, IF_BFP)
F(0xed07, MXDB, RXE, Z, 0, m2_64, x1, x1, mxdb, 0, IF_BFP) F(0xed07, MXDB, RXE, Z, f1, m2_64, new_x, x1, mxdb, 0, IF_BFP)
/* MULTIPLY HALFWORD */ /* MULTIPLY HALFWORD */
C(0x4c00, MH, RX_a, Z, r1_o, m2_16s, new, r1_32, mul, 0) C(0x4c00, MH, RX_a, Z, r1_o, m2_16s, new, r1_32, mul, 0)
C(0xe37c, MHY, RXY_a, GIE, r1_o, m2_16s, new, r1_32, mul, 0) C(0xe37c, MHY, RXY_a, GIE, r1_o, m2_16s, new, r1_32, mul, 0)

View file

@ -3424,7 +3424,7 @@ static DisasJumpType op_mxb(DisasContext *s, DisasOps *o)
static DisasJumpType op_mxdb(DisasContext *s, DisasOps *o) static DisasJumpType op_mxdb(DisasContext *s, DisasOps *o)
{ {
gen_helper_mxdb(o->out_128, cpu_env, o->in1_128, o->in2); gen_helper_mxdb(o->out_128, cpu_env, o->in1, o->in2);
return DISAS_NEXT; return DISAS_NEXT;
} }
@ -5186,12 +5186,6 @@ static void prep_r1_P(DisasContext *s, DisasOps *o)
} }
#define SPEC_prep_r1_P SPEC_r1_even #define SPEC_prep_r1_P SPEC_r1_even
static void prep_x1(DisasContext *s, DisasOps *o)
{
o->out_128 = load_freg_128(get_field(s, r1));
}
#define SPEC_prep_x1 SPEC_r1_f128
/* ====================================================================== */ /* ====================================================================== */
/* The "Write OUTput" generators. These generally perform some non-trivial /* The "Write OUTput" generators. These generally perform some non-trivial
copy of data to TCG globals, or to main memory. The trivial cases are copy of data to TCG globals, or to main memory. The trivial cases are

View file

@ -49,7 +49,8 @@ qtests_i386 = \
(config_all_devices.has_key('CONFIG_SGA') ? ['boot-serial-test'] : []) + \ (config_all_devices.has_key('CONFIG_SGA') ? ['boot-serial-test'] : []) + \
(config_all_devices.has_key('CONFIG_ISA_IPMI_KCS') ? ['ipmi-kcs-test'] : []) + \ (config_all_devices.has_key('CONFIG_ISA_IPMI_KCS') ? ['ipmi-kcs-test'] : []) + \
(config_host.has_key('CONFIG_LINUX') and \ (config_host.has_key('CONFIG_LINUX') and \
config_all_devices.has_key('CONFIG_ISA_IPMI_BT') ? ['ipmi-bt-test'] : []) + \ config_all_devices.has_key('CONFIG_ISA_IPMI_BT') and
config_all_devices.has_key('CONFIG_IPMI_EXTERN') ? ['ipmi-bt-test'] : []) + \
(config_all_devices.has_key('CONFIG_WDT_IB700') ? ['wdt_ib700-test'] : []) + \ (config_all_devices.has_key('CONFIG_WDT_IB700') ? ['wdt_ib700-test'] : []) + \
(config_all_devices.has_key('CONFIG_PVPANIC_ISA') ? ['pvpanic-test'] : []) + \ (config_all_devices.has_key('CONFIG_PVPANIC_ISA') ? ['pvpanic-test'] : []) + \
(config_all_devices.has_key('CONFIG_PVPANIC_PCI') ? ['pvpanic-pci-test'] : []) + \ (config_all_devices.has_key('CONFIG_PVPANIC_PCI') ? ['pvpanic-pci-test'] : []) + \

View file

@ -35,6 +35,7 @@ TESTS+=chrl
TESTS+=rxsbg TESTS+=rxsbg
TESTS+=ex-relative-long TESTS+=ex-relative-long
TESTS+=ex-branch TESTS+=ex-branch
TESTS+=mxdb
cdsg: CFLAGS+=-pthread cdsg: CFLAGS+=-pthread
cdsg: LDFLAGS+=-pthread cdsg: LDFLAGS+=-pthread
@ -47,6 +48,8 @@ $(PGM_SPECIFICATION_TESTS): LDFLAGS+=pgm-specification-user.o
TESTS += $(PGM_SPECIFICATION_TESTS) TESTS += $(PGM_SPECIFICATION_TESTS)
Z13_TESTS=vistr Z13_TESTS=vistr
Z13_TESTS+=lcbb
Z13_TESTS+=locfhr
$(Z13_TESTS): CFLAGS+=-march=z13 -O2 $(Z13_TESTS): CFLAGS+=-march=z13 -O2
TESTS+=$(Z13_TESTS) TESTS+=$(Z13_TESTS)
@ -75,7 +78,16 @@ run-gdbstub-signals-s390x: signals-s390x
--bin $< --test $(S390X_SRC)/gdbstub/test-signals-s390x.py, \ --bin $< --test $(S390X_SRC)/gdbstub/test-signals-s390x.py, \
mixing signals and debugging) mixing signals and debugging)
EXTRA_RUNS += run-gdbstub-signals-s390x hello-s390x-asm: CFLAGS+=-nostdlib
run-gdbstub-svc: hello-s390x-asm
$(call run-test, $@, $(GDB_SCRIPT) \
--gdb $(HAVE_GDB_BIN) \
--qemu $(QEMU) --qargs "$(QEMU_OPTS)" \
--bin $< --test $(S390X_SRC)/gdbstub/test-svc.py, \
single-stepping svc)
EXTRA_RUNS += run-gdbstub-signals-s390x run-gdbstub-svc
endif endif
# MVX versions of sha512 # MVX versions of sha512

View file

@ -0,0 +1,64 @@
"""Test single-stepping SVC.
This runs as a sourced script (via -x, via run-test.py)."""
from __future__ import print_function
import gdb
import sys
n_failures = 0
def report(cond, msg):
"""Report success/fail of a test"""
if cond:
print("PASS: {}".format(msg))
else:
print("FAIL: {}".format(msg))
global n_failures
n_failures += 1
def run_test():
"""Run through the tests one by one"""
report("lghi\t" in gdb.execute("x/i $pc", False, True), "insn #1")
gdb.execute("si")
report("larl\t" in gdb.execute("x/i $pc", False, True), "insn #2")
gdb.execute("si")
report("lghi\t" in gdb.execute("x/i $pc", False, True), "insn #3")
gdb.execute("si")
report("svc\t" in gdb.execute("x/i $pc", False, True), "insn #4")
gdb.execute("si")
report("xgr\t" in gdb.execute("x/i $pc", False, True), "insn #5")
gdb.execute("si")
report("svc\t" in gdb.execute("x/i $pc", False, True), "insn #6")
gdb.execute("si")
def main():
"""Prepare the environment and run through the tests"""
try:
inferior = gdb.selected_inferior()
print("ATTACHED: {}".format(inferior.architecture().name()))
except (gdb.error, AttributeError):
print("SKIPPING (not connected)")
exit(0)
if gdb.parse_and_eval('$pc') == 0:
print("SKIP: PC not set")
exit(0)
try:
# These are not very useful in scripts
gdb.execute("set pagination off")
gdb.execute("set confirm off")
# Run the actual tests
run_test()
except gdb.error:
report(False, "GDB Exception: {}".format(sys.exc_info()[0]))
print("All tests complete: %d failures" % n_failures)
exit(n_failures)
main()

View file

@ -0,0 +1,20 @@
/*
* Hello, World! in assembly.
*/
.globl _start
_start:
/* puts("Hello, World!"); */
lghi %r2,1
larl %r3,foo
lghi %r4,foo_end-foo
svc 4
/* exit(0); */
xgr %r2,%r2
svc 1
.align 2
foo: .asciz "Hello, World!\n"
foo_end:

51
tests/tcg/s390x/lcbb.c Normal file
View file

@ -0,0 +1,51 @@
/*
* Test the LCBB instruction.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <assert.h>
#include <stdlib.h>
static inline __attribute__((__always_inline__)) void
lcbb(long *r1, void *dxb2, int m3, int *cc)
{
asm("lcbb %[r1],%[dxb2],%[m3]\n"
"ipm %[cc]"
: [r1] "+r" (*r1), [cc] "=r" (*cc)
: [dxb2] "R" (*(char *)dxb2), [m3] "i" (m3)
: "cc");
*cc = (*cc >> 28) & 3;
}
static char buf[0x1000] __attribute__((aligned(0x1000)));
static inline __attribute__((__always_inline__)) void
test_lcbb(void *p, int m3, int exp_r1, int exp_cc)
{
long r1 = 0xfedcba9876543210;
int cc;
lcbb(&r1, p, m3, &cc);
assert(r1 == (0xfedcba9800000000 | exp_r1));
assert(cc == exp_cc);
}
int main(void)
{
test_lcbb(&buf[0], 0, 16, 0);
test_lcbb(&buf[63], 0, 1, 3);
test_lcbb(&buf[0], 1, 16, 0);
test_lcbb(&buf[127], 1, 1, 3);
test_lcbb(&buf[0], 2, 16, 0);
test_lcbb(&buf[255], 2, 1, 3);
test_lcbb(&buf[0], 3, 16, 0);
test_lcbb(&buf[511], 3, 1, 3);
test_lcbb(&buf[0], 4, 16, 0);
test_lcbb(&buf[1023], 4, 1, 3);
test_lcbb(&buf[0], 5, 16, 0);
test_lcbb(&buf[2047], 5, 1, 3);
test_lcbb(&buf[0], 6, 16, 0);
test_lcbb(&buf[4095], 6, 1, 3);
return EXIT_SUCCESS;
}

29
tests/tcg/s390x/locfhr.c Normal file
View file

@ -0,0 +1,29 @@
/*
* Test the LOCFHR instruction.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <assert.h>
#include <stdlib.h>
static inline __attribute__((__always_inline__)) long
locfhr(long r1, long r2, int m3, int cc)
{
cc <<= 28;
asm("spm %[cc]\n"
"locfhr %[r1],%[r2],%[m3]\n"
: [r1] "+r" (r1)
: [cc] "r" (cc), [r2] "r" (r2), [m3] "i" (m3)
: "cc");
return r1;
}
int main(void)
{
assert(locfhr(0x1111111122222222, 0x3333333344444444, 8, 0) ==
0x3333333322222222);
assert(locfhr(0x5555555566666666, 0x7777777788888888, 11, 1) ==
0x5555555566666666);
return EXIT_SUCCESS;
}

30
tests/tcg/s390x/mxdb.c Normal file
View file

@ -0,0 +1,30 @@
/*
* Test the MXDB and MXDBR instructions.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <assert.h>
#include <stdlib.h>
int main(void)
{
union {
double d[2];
long double ld;
} a;
double b;
a.d[0] = 1.2345;
a.d[1] = 999;
b = 6.789;
asm("mxdb %[a],%[b]" : [a] "+f" (a.ld) : [b] "R" (b));
assert(a.ld > 8.38 && a.ld < 8.39);
a.d[0] = 1.2345;
a.d[1] = 999;
b = 6.789;
asm("mxdbr %[a],%[b]" : [a] "+f" (a.ld) : [b] "f" (b));
assert(a.ld > 8.38 && a.ld < 8.39);
return EXIT_SUCCESS;
}

View file

@ -40,9 +40,9 @@ static void vncws_tls_handshake_done(QIOTask *task,
if (vs->ioc_tag) { if (vs->ioc_tag) {
g_source_remove(vs->ioc_tag); g_source_remove(vs->ioc_tag);
} }
vs->ioc_tag = qio_channel_add_watch( vs->ioc_tag = qio_channel_add_watch(vs->ioc,
QIO_CHANNEL(vs->ioc), G_IO_IN | G_IO_HUP | G_IO_ERR, G_IO_IN | G_IO_HUP | G_IO_ERR,
vncws_handshake_io, vs, NULL); vncws_handshake_io, vs, NULL);
} }
} }