* Add compat machines for QEMU 8.2

* Convert some DPRINTFs in s390x code into trace events
 * Fix VFMIN/VFMAX, VSTL, VREP and VSTRS s390x instructions
 * Fix virtio-gpu on big endian (i.e. s390x) hosts
 -----BEGIN PGP SIGNATURE-----
 
 iQJFBAABCAAvFiEEJ7iIR+7gJQEY8+q5LtnXdP5wLbUFAmTl8McRHHRodXRoQHJl
 ZGhhdC5jb20ACgkQLtnXdP5wLbVXTQ/+OLnw+5+rCA/WbVWfWwEragtmSZuo5302
 ByARdgv8BdD7AobUdSLkWbz9fgU7TAGPnv4aRXBs1K1HE77e63sg6ZfmGUJQllx8
 T/86LPB0dPHZHPt39t3zv/ZTfj+yoXF+7+MIzhSbgV9sumKRqIW/w/BsTI3Rkkwd
 yp1mpkNvYzCkO66nZWYDgKYLTvSmSJx+GUC6dgWswwXSmGP9UU+jutX62lDQS4k4
 l3VjHHhl5V9LENQAvHQ1x48tMIjR4vra8T4fhYLAr1nVsHhsBONRX9qxUHhpy0c3
 zrWA95kO0CPoJLqMNdY9CSyBRgrH/BCmM6Z5+GvBI0RWo+bdgYzF5QpNW6Sbfb/L
 NfE7PK0EYRFk8Q1LK+pYQ0wCjw/a5tOj3NtwZQUUMqqiNL6zmaQpOXujw3PTtIDN
 6qS9aiAVlL+taIsk9av1So5Mgrr97BsptPKhe22BCYxv832Vj8mPOhjkbiTs8OYD
 PCr+sfJvpwcDBdDhQ1xi4M5tkxg26CPtntVDJdl/pXM3dmpxQ/D8ciok+f2/EeWU
 VeiJ4/tbelm3u0zfGqYfRGSxvPYZM9aJJCLloXuffeT+UEJXUVze6MgMbSuf4vji
 f+hWxA38WUAaoZjoBguMgwLOp/hvBtbHF+Hdk+iT0yE5uc3Ajo619YRVAspJbNi4
 qSYIMAJoGqM=
 =cIfC
 -----END PGP SIGNATURE-----

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

* Add compat machines for QEMU 8.2
* Convert some DPRINTFs in s390x code into trace events
* Fix VFMIN/VFMAX, VSTL, VREP and VSTRS s390x instructions
* Fix virtio-gpu on big endian (i.e. s390x) hosts

# -----BEGIN PGP SIGNATURE-----
#
# iQJFBAABCAAvFiEEJ7iIR+7gJQEY8+q5LtnXdP5wLbUFAmTl8McRHHRodXRoQHJl
# ZGhhdC5jb20ACgkQLtnXdP5wLbVXTQ/+OLnw+5+rCA/WbVWfWwEragtmSZuo5302
# ByARdgv8BdD7AobUdSLkWbz9fgU7TAGPnv4aRXBs1K1HE77e63sg6ZfmGUJQllx8
# T/86LPB0dPHZHPt39t3zv/ZTfj+yoXF+7+MIzhSbgV9sumKRqIW/w/BsTI3Rkkwd
# yp1mpkNvYzCkO66nZWYDgKYLTvSmSJx+GUC6dgWswwXSmGP9UU+jutX62lDQS4k4
# l3VjHHhl5V9LENQAvHQ1x48tMIjR4vra8T4fhYLAr1nVsHhsBONRX9qxUHhpy0c3
# zrWA95kO0CPoJLqMNdY9CSyBRgrH/BCmM6Z5+GvBI0RWo+bdgYzF5QpNW6Sbfb/L
# NfE7PK0EYRFk8Q1LK+pYQ0wCjw/a5tOj3NtwZQUUMqqiNL6zmaQpOXujw3PTtIDN
# 6qS9aiAVlL+taIsk9av1So5Mgrr97BsptPKhe22BCYxv832Vj8mPOhjkbiTs8OYD
# PCr+sfJvpwcDBdDhQ1xi4M5tkxg26CPtntVDJdl/pXM3dmpxQ/D8ciok+f2/EeWU
# VeiJ4/tbelm3u0zfGqYfRGSxvPYZM9aJJCLloXuffeT+UEJXUVze6MgMbSuf4vji
# f+hWxA38WUAaoZjoBguMgwLOp/hvBtbHF+Hdk+iT0yE5uc3Ajo619YRVAspJbNi4
# qSYIMAJoGqM=
# =cIfC
# -----END PGP SIGNATURE-----
# gpg: Signature made Wed 23 Aug 2023 07:43:03 EDT
# gpg:                using RSA key 27B88847EEE0250118F3EAB92ED9D774FE702DB5
# gpg:                issuer "thuth@redhat.com"
# gpg: Good signature from "Thomas Huth <th.huth@gmx.de>" [full]
# gpg:                 aka "Thomas Huth <thuth@redhat.com>" [full]
# gpg:                 aka "Thomas Huth <huth@tuxfamily.org>" [full]
# gpg:                 aka "Thomas Huth <th.huth@posteo.de>" [unknown]
# Primary key fingerprint: 27B8 8847 EEE0 2501 18F3  EAB9 2ED9 D774 FE70 2DB5

* tag 'pull-request-2023-08-23' of https://gitlab.com/thuth/qemu:
  tests/tcg/s390x: Test VSTRS
  target/s390x: Fix the "ignored match" case in VSTRS
  linux-user/elfload: Enable vxe2 on s390x
  include/hw/virtio/virtio-gpu: Fix virtio-gpu with blob on big endian hosts
  hw/s390x/s390-virtio-ccw: Remove superfluous code to set the NIC model
  tests/tcg/s390x: Test VREP
  target/s390x: Use a 16-bit immediate in VREP
  tests/tcg/s390x: Test VSTL
  target/s390x: Fix VSTL with a large length
  target/s390x: Check reserved bits of VFMIN/VFMAX's M5
  s390x: Convert DPRINTF to trace events
  hw: Add compat machines for 8.2

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Stefan Hajnoczi 2023-08-23 09:17:41 -04:00
commit 92e1d39f98
24 changed files with 378 additions and 126 deletions

View File

@ -3170,10 +3170,17 @@ static void machvirt_machine_init(void)
}
type_init(machvirt_machine_init);
static void virt_machine_8_1_options(MachineClass *mc)
static void virt_machine_8_2_options(MachineClass *mc)
{
}
DEFINE_VIRT_MACHINE_AS_LATEST(8, 1)
DEFINE_VIRT_MACHINE_AS_LATEST(8, 2)
static void virt_machine_8_1_options(MachineClass *mc)
{
virt_machine_8_2_options(mc);
compat_props_add(mc->compat_props, hw_compat_8_1, hw_compat_8_1_len);
}
DEFINE_VIRT_MACHINE(8, 1)
static void virt_machine_8_0_options(MachineClass *mc)
{

View File

@ -39,6 +39,9 @@
#include "hw/virtio/virtio.h"
#include "hw/virtio/virtio-pci.h"
GlobalProperty hw_compat_8_1[] = {};
const size_t hw_compat_8_1_len = G_N_ELEMENTS(hw_compat_8_1);
GlobalProperty hw_compat_8_0[] = {
{ "migration", "multifd-flush-after-each-section", "on"},
{ TYPE_PCI_DEVICE, "x-pcie-ari-nextfn-1", "on" },

View File

@ -114,6 +114,9 @@
{ "qemu64-" TYPE_X86_CPU, "model-id", "QEMU Virtual CPU version " v, },\
{ "athlon-" TYPE_X86_CPU, "model-id", "QEMU Virtual CPU version " v, },
GlobalProperty pc_compat_8_1[] = {};
const size_t pc_compat_8_1_len = G_N_ELEMENTS(pc_compat_8_1);
GlobalProperty pc_compat_8_0[] = {
{ "virtio-mem", "unplugged-inaccessible", "auto" },
};

View File

@ -504,13 +504,25 @@ static void pc_i440fx_machine_options(MachineClass *m)
machine_class_allow_dynamic_sysbus_dev(m, TYPE_VMBUS_BRIDGE);
}
static void pc_i440fx_8_1_machine_options(MachineClass *m)
static void pc_i440fx_8_2_machine_options(MachineClass *m)
{
pc_i440fx_machine_options(m);
m->alias = "pc";
m->is_default = true;
}
DEFINE_I440FX_MACHINE(v8_2, "pc-i440fx-8.2", NULL,
pc_i440fx_8_2_machine_options);
static void pc_i440fx_8_1_machine_options(MachineClass *m)
{
pc_i440fx_8_2_machine_options(m);
m->alias = NULL;
m->is_default = false;
compat_props_add(m->compat_props, hw_compat_8_1, hw_compat_8_1_len);
compat_props_add(m->compat_props, pc_compat_8_1, pc_compat_8_1_len);
}
DEFINE_I440FX_MACHINE(v8_1, "pc-i440fx-8.1", NULL,
pc_i440fx_8_1_machine_options);
@ -519,8 +531,6 @@ static void pc_i440fx_8_0_machine_options(MachineClass *m)
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
pc_i440fx_8_1_machine_options(m);
m->alias = NULL;
m->is_default = false;
compat_props_add(m->compat_props, hw_compat_8_0, hw_compat_8_0_len);
compat_props_add(m->compat_props, pc_compat_8_0, pc_compat_8_0_len);

View File

@ -379,12 +379,23 @@ static void pc_q35_machine_options(MachineClass *m)
machine_class_allow_dynamic_sysbus_dev(m, TYPE_VMBUS_BRIDGE);
}
static void pc_q35_8_1_machine_options(MachineClass *m)
static void pc_q35_8_2_machine_options(MachineClass *m)
{
pc_q35_machine_options(m);
m->alias = "q35";
}
DEFINE_Q35_MACHINE(v8_2, "pc-q35-8.2", NULL,
pc_q35_8_2_machine_options);
static void pc_q35_8_1_machine_options(MachineClass *m)
{
pc_q35_8_2_machine_options(m);
m->alias = NULL;
compat_props_add(m->compat_props, hw_compat_8_1, hw_compat_8_1_len);
compat_props_add(m->compat_props, pc_compat_8_1, pc_compat_8_1_len);
}
DEFINE_Q35_MACHINE(v8_1, "pc-q35-8.1", NULL,
pc_q35_8_1_machine_options);
@ -393,7 +404,6 @@ static void pc_q35_8_0_machine_options(MachineClass *m)
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
pc_q35_8_1_machine_options(m);
m->alias = NULL;
compat_props_add(m->compat_props, hw_compat_8_0, hw_compat_8_0_len);
compat_props_add(m->compat_props, pc_compat_8_0, pc_compat_8_0_len);

View File

@ -347,10 +347,17 @@ type_init(virt_machine_register_types)
} \
type_init(machvirt_machine_##major##_##minor##_init);
static void virt_machine_8_1_options(MachineClass *mc)
static void virt_machine_8_2_options(MachineClass *mc)
{
}
DEFINE_VIRT_MACHINE(8, 1, true)
DEFINE_VIRT_MACHINE(8, 2, true)
static void virt_machine_8_1_options(MachineClass *mc)
{
virt_machine_8_2_options(mc);
compat_props_add(mc->compat_props, hw_compat_8_1, hw_compat_8_1_len);
}
DEFINE_VIRT_MACHINE(8, 1, false)
static void virt_machine_8_0_options(MachineClass *mc)
{

View File

@ -4753,14 +4753,25 @@ static void spapr_machine_latest_class_options(MachineClass *mc)
type_init(spapr_machine_register_##suffix)
/*
* pseries-8.1
* pseries-8.2
*/
static void spapr_machine_8_1_class_options(MachineClass *mc)
static void spapr_machine_8_2_class_options(MachineClass *mc)
{
/* Defaults for the latest behaviour inherited from the base class */
}
DEFINE_SPAPR_MACHINE(8_1, "8.1", true);
DEFINE_SPAPR_MACHINE(8_2, "8.2", true);
/*
* pseries-8.1
*/
static void spapr_machine_8_1_class_options(MachineClass *mc)
{
spapr_machine_8_2_class_options(mc);
compat_props_add(mc->compat_props, hw_compat_8_1, hw_compat_8_1_len);
}
DEFINE_SPAPR_MACHINE(8_1, "8.1", false);
/*
* pseries-8.0

View File

@ -27,16 +27,7 @@
#include "sysemu/reset.h"
#include "sysemu/runstate.h"
#ifndef DEBUG_S390PCI_BUS
#define DEBUG_S390PCI_BUS 0
#endif
#define DPRINTF(fmt, ...) \
do { \
if (DEBUG_S390PCI_BUS) { \
fprintf(stderr, "S390pci-bus: " fmt, ## __VA_ARGS__); \
} \
} while (0)
#include "trace.h"
S390pciState *s390_get_phb(void)
{
@ -132,7 +123,7 @@ void s390_pci_sclp_configure(SCCB *sccb)
uint16_t rc;
if (!pbdev) {
DPRINTF("sclp config no dev found\n");
trace_s390_pci_sclp_nodev("configure", be32_to_cpu(psccb->aid));
rc = SCLP_RC_ADAPTER_ID_NOT_RECOGNIZED;
goto out;
}
@ -199,7 +190,7 @@ void s390_pci_sclp_deconfigure(SCCB *sccb)
uint16_t rc;
if (!pbdev) {
DPRINTF("sclp deconfig no dev found\n");
trace_s390_pci_sclp_nodev("deconfigure", be32_to_cpu(psccb->aid));
rc = SCLP_RC_ADAPTER_ID_NOT_RECOGNIZED;
goto out;
}
@ -573,7 +564,7 @@ static IOMMUTLBEntry s390_translate_iommu(IOMMUMemoryRegion *mr, hwaddr addr,
return ret;
}
DPRINTF("iommu trans addr 0x%" PRIx64 "\n", addr);
trace_s390_pci_iommu_xlate(addr);
if (addr < iommu->pba || addr > iommu->pal) {
error = ERR_EVENT_OORANGE;
@ -692,8 +683,8 @@ static void s390_msi_ctrl_write(void *opaque, hwaddr addr, uint64_t data,
uint32_t sum_bit;
assert(pbdev);
DPRINTF("write_msix data 0x%" PRIx64 " idx %d vec 0x%x\n", data,
pbdev->idx, vec);
trace_s390_pci_msi_ctrl_write(data, pbdev->idx, vec);
if (pbdev->state != ZPCI_FS_ENABLED) {
return;
@ -843,7 +834,7 @@ static void s390_pcihost_realize(DeviceState *dev, Error **errp)
PCIHostState *phb = PCI_HOST_BRIDGE(dev);
S390pciState *s = S390_PCI_HOST_BRIDGE(dev);
DPRINTF("host_init\n");
trace_s390_pcihost("realize");
b = pci_register_root_bus(dev, NULL, s390_pci_set_irq, s390_pci_map_irq,
NULL, get_system_memory(), get_system_io(), 0,
@ -1120,7 +1111,7 @@ static void s390_pcihost_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
return;
}
} else {
DPRINTF("zPCI interpretation facilities missing.\n");
trace_s390_pcihost("zPCI interpretation missing");
pbdev->interp = false;
pbdev->forwarding_assist = false;
}

View File

@ -23,16 +23,7 @@
#include "hw/s390x/s390-pci-vfio.h"
#include "hw/s390x/tod.h"
#ifndef DEBUG_S390PCI_INST
#define DEBUG_S390PCI_INST 0
#endif
#define DPRINTF(fmt, ...) \
do { \
if (DEBUG_S390PCI_INST) { \
fprintf(stderr, "s390pci-inst: " fmt, ## __VA_ARGS__); \
} \
} while (0)
#include "trace.h"
static inline void inc_dma_avail(S390PCIIOMMU *iommu)
{
@ -133,8 +124,7 @@ static int list_pci(ClpReqRspListPci *rrb, uint8_t *cc)
g_l2 += sizeof(ClpFhListEntry);
/* Add endian check for DPRINTF? */
DPRINTF("g_l2 %d vendor id 0x%x device id 0x%x fid 0x%x fh 0x%x\n",
g_l2,
trace_s390_pci_list_entry(g_l2,
lduw_p(&rrb->response.fh_list[i].vendor_id),
lduw_p(&rrb->response.fh_list[i].device_id),
ldl_p(&rrb->response.fh_list[i].fid),
@ -153,7 +143,7 @@ static int list_pci(ClpReqRspListPci *rrb, uint8_t *cc)
stw_p(&rrb->response.hdr.rsp, CLP_RC_OK);
out:
if (rc) {
DPRINTF("list pci failed rc 0x%x\n", rc);
trace_s390_pci_list(rc);
stw_p(&rrb->response.hdr.rsp, res_code);
}
return rc;
@ -280,7 +270,7 @@ int clp_service_call(S390CPU *cpu, uint8_t r2, uintptr_t ra)
stw_p(&ressetpci->hdr.rsp, CLP_RC_OK);
break;
default:
DPRINTF("unknown set pci command\n");
trace_s390_pci_unknown("set-pci", reqsetpci->oc);
stw_p(&ressetpci->hdr.rsp, CLP_RC_SETPCIFN_FHOP);
break;
}
@ -292,7 +282,7 @@ int clp_service_call(S390CPU *cpu, uint8_t r2, uintptr_t ra)
pbdev = s390_pci_find_dev_by_fh(s, ldl_p(&reqquery->fh));
if (!pbdev) {
DPRINTF("query pci no pci dev\n");
trace_s390_pci_nodev("query", ldl_p(&reqquery->fh));
stw_p(&resquery->hdr.rsp, CLP_RC_SETPCIFN_FH);
goto out;
}
@ -317,7 +307,7 @@ int clp_service_call(S390CPU *cpu, uint8_t r2, uintptr_t ra)
stl_p(&resquery->bar[i], data);
resquery->bar_size[i] = pbdev->pdev->io_regions[i].size ?
ctz64(pbdev->pdev->io_regions[i].size) : 0;
DPRINTF("bar %d addr 0x%x size 0x%" PRIx64 "barsize 0x%x\n", i,
trace_s390_pci_bar(i,
ldl_p(&resquery->bar[i]),
pbdev->pdev->io_regions[i].size,
resquery->bar_size[i]);
@ -351,7 +341,7 @@ int clp_service_call(S390CPU *cpu, uint8_t r2, uintptr_t ra)
break;
}
default:
DPRINTF("unknown clp command\n");
trace_s390_pci_unknown("clp", lduw_p(&reqh->cmd));
stw_p(&resh->rsp, CLP_RC_CMD);
break;
}
@ -459,7 +449,7 @@ int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
pbdev = s390_pci_find_dev_by_fh(s390_get_phb(), fh);
if (!pbdev) {
DPRINTF("pcilg no pci dev\n");
trace_s390_pci_nodev("pcilg", fh);
setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
return 0;
}
@ -500,7 +490,7 @@ int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
}
break;
default:
DPRINTF("pcilg invalid space\n");
trace_s390_pci_invalid("pcilg", fh);
setcc(cpu, ZPCI_PCI_LS_ERR);
s390_set_status_code(env, r2, ZPCI_PCI_ST_INVAL_AS);
return 0;
@ -559,7 +549,7 @@ int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
pbdev = s390_pci_find_dev_by_fh(s390_get_phb(), fh);
if (!pbdev) {
DPRINTF("pcistg no pci dev\n");
trace_s390_pci_nodev("pcistg", fh);
setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
return 0;
}
@ -608,7 +598,7 @@ int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
data, len);
break;
default:
DPRINTF("pcistg invalid space\n");
trace_s390_pci_invalid("pcistg", fh);
setcc(cpu, ZPCI_PCI_LS_ERR);
s390_set_status_code(env, r2, ZPCI_PCI_ST_INVAL_AS);
return 0;
@ -729,7 +719,7 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
pbdev = s390_pci_find_dev_by_fh(s390_get_phb(), fh);
if (!pbdev) {
DPRINTF("rpcit no pci dev\n");
trace_s390_pci_nodev("rpcit", fh);
setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
return 0;
}
@ -863,7 +853,7 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr,
pbdev = s390_pci_find_dev_by_fh(s390_get_phb(), fh);
if (!pbdev) {
DPRINTF("pcistb no pci dev fh 0x%x\n", fh);
trace_s390_pci_nodev("pcistb", fh);
setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
return 0;
}
@ -879,7 +869,7 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr,
}
if (pcias > ZPCI_IO_BAR_MAX) {
DPRINTF("pcistb invalid space\n");
trace_s390_pci_invalid("pcistb", fh);
setcc(cpu, ZPCI_PCI_LS_ERR);
s390_set_status_code(env, r1, ZPCI_PCI_ST_INVAL_AS);
return 0;
@ -971,7 +961,7 @@ static int reg_irqs(CPUS390XState *env, S390PCIBusDevice *pbdev, ZpciFib fib)
pbdev->noi = FIB_DATA_NOI(ldl_p(&fib.data));
pbdev->sum = FIB_DATA_SUM(ldl_p(&fib.data));
DPRINTF("reg_irqs adapter id %d\n", pbdev->routes.adapter.adapter_id);
trace_s390_pci_irqs("register", pbdev->routes.adapter.adapter_id);
return 0;
out:
release_indicator(&pbdev->routes.adapter, pbdev->summary_ind);
@ -996,7 +986,7 @@ int pci_dereg_irqs(S390PCIBusDevice *pbdev)
pbdev->noi = 0;
pbdev->sum = 0;
DPRINTF("dereg_irqs adapter id %d\n", pbdev->routes.adapter.adapter_id);
trace_s390_pci_irqs("unregister", pbdev->routes.adapter.adapter_id);
return 0;
}
@ -1139,7 +1129,7 @@ static int mpcifc_reg_int_interp(S390PCIBusDevice *pbdev, ZpciFib *fib)
rc = s390_pci_kvm_aif_enable(pbdev, fib, pbdev->forwarding_assist);
if (rc) {
DPRINTF("Failed to enable interrupt forwarding\n");
trace_s390_pci_kvm_aif("enable");
return rc;
}
@ -1152,7 +1142,7 @@ static int mpcifc_dereg_int_interp(S390PCIBusDevice *pbdev, ZpciFib *fib)
rc = s390_pci_kvm_aif_disable(pbdev);
if (rc) {
DPRINTF("Failed to disable interrupt forwarding\n");
trace_s390_pci_kvm_aif("disable");
return rc;
}
@ -1185,7 +1175,7 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar,
pbdev = s390_pci_find_dev_by_fh(s390_get_phb(), fh);
if (!pbdev) {
DPRINTF("mpcifc no pci dev fh 0x%x\n", fh);
trace_s390_pci_nodev("mpcifc", fh);
setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);
return 0;
}

View File

@ -222,10 +222,6 @@ static void s390_create_virtio_net(BusState *bus, const char *name)
NICInfo *nd = &nd_table[i];
DeviceState *dev;
if (!nd->model) {
nd->model = g_strdup("virtio");
}
qemu_check_nic_model(nd, "virtio");
dev = qdev_new(name);
@ -828,14 +824,26 @@ bool css_migration_enabled(void)
} \
type_init(ccw_machine_register_##suffix)
static void ccw_machine_8_2_instance_options(MachineState *machine)
{
}
static void ccw_machine_8_2_class_options(MachineClass *mc)
{
}
DEFINE_CCW_MACHINE(8_2, "8.2", true);
static void ccw_machine_8_1_instance_options(MachineState *machine)
{
ccw_machine_8_2_instance_options(machine);
}
static void ccw_machine_8_1_class_options(MachineClass *mc)
{
ccw_machine_8_2_class_options(mc);
compat_props_add(mc->compat_props, hw_compat_8_1, hw_compat_8_1_len);
}
DEFINE_CCW_MACHINE(8_1, "8.1", true);
DEFINE_CCW_MACHINE(8_1, "8.1", false);
static void ccw_machine_8_0_instance_options(MachineState *machine)
{

View File

@ -19,3 +19,20 @@ virtio_ccw_set_ind(uint64_t ind_loc, uint8_t ind_old, uint8_t ind_new) "VIRTIO-C
s390_pci_clp_cap(const char *id, uint32_t cap) "PCI: %s: missing expected CLP capability %u"
s390_pci_clp_cap_size(const char *id, uint32_t size, uint32_t cap) "PCI: %s: bad size (%u) for CLP capability %u"
s390_pci_clp_dev_info(const char *id) "PCI: %s: cannot read vfio device info"
# s390-pci-bus.c
s390_pci_sclp_nodev(const char *str, uint32_t aid) "%s no dev found aid 0x%x"
s390_pci_iommu_xlate(uint64_t addr) "iommu trans addr 0x%" PRIx64
s390_pci_msi_ctrl_write(uint64_t data, uint32_t idx, uint32_t vec) "write_msix data 0x%" PRIx64 " idx %d vec 0x%x"
s390_pcihost(const char *msg) "%s"
# s390-pci-inst.c
s390_pci_irqs(const char *str, uint32_t id) "%s irqs for adapter id %d"
s390_pci_kvm_aif(const char *str) "Failed to %s interrupt forwarding"
s390_pci_list_entry(uint32_t g_l2, uint32_t vid, uint32_t did, uint32_t fid, uint32_t fh) "g_l2 %d vendor id 0x%x device id 0x%x fid 0x%x fh 0x%x"
s390_pci_list(uint32_t rc) "failed rc 0x%x"
s390_pci_unknown(const char *msg, uint32_t cmd) "%s unknown command 0x%x"
s390_pci_bar(uint32_t bar, uint32_t addr, uint64_t size, uint32_t barsize) "bar %d addr 0x%x size 0x%" PRIx64 "barsize 0x%x"
s390_pci_nodev(const char *cmd, uint32_t fh) "%s no pci dev fh 0x%x"
s390_pci_invalid(const char *cmd, uint32_t fh) "%s invalid space fh 0x%x"

View File

@ -390,6 +390,9 @@ struct MachineState {
} \
type_init(machine_initfn##_register_types)
extern GlobalProperty hw_compat_8_1[];
extern const size_t hw_compat_8_1_len;
extern GlobalProperty hw_compat_8_0[];
extern const size_t hw_compat_8_0_len;

View File

@ -200,6 +200,9 @@ void pc_madt_cpu_entry(int uid, const CPUArchIdList *apic_ids,
/* sgx.c */
void pc_machine_init_sgx_epc(PCMachineState *pcms);
extern GlobalProperty pc_compat_8_1[];
extern const size_t pc_compat_8_1_len;
extern GlobalProperty pc_compat_8_0[];
extern const size_t pc_compat_8_0_len;

View File

@ -63,7 +63,10 @@ virtio_gpu_create_blob_bswap(struct virtio_gpu_resource_create_blob *cblob)
{
virtio_gpu_ctrl_hdr_bswap(&cblob->hdr);
le32_to_cpus(&cblob->resource_id);
le32_to_cpus(&cblob->blob_mem);
le32_to_cpus(&cblob->blob_flags);
le32_to_cpus(&cblob->nr_entries);
le64_to_cpus(&cblob->blob_id);
le64_to_cpus(&cblob->size);
}

View File

@ -1614,6 +1614,7 @@ uint32_t get_elf_hwcap(void)
}
GET_FEATURE(S390_FEAT_VECTOR, HWCAP_S390_VXRS);
GET_FEATURE(S390_FEAT_VECTOR_ENH, HWCAP_S390_VXRS_EXT);
GET_FEATURE(S390_FEAT_VECTOR_ENH2, HWCAP_S390_VXRS_EXT2);
return hwcap;
}

View File

@ -52,16 +52,6 @@
#include "hw/s390x/s390-virtio-hcall.h"
#include "target/s390x/kvm/pv.h"
#ifndef DEBUG_KVM
#define DEBUG_KVM 0
#endif
#define DPRINTF(fmt, ...) do { \
if (DEBUG_KVM) { \
fprintf(stderr, fmt, ## __VA_ARGS__); \
} \
} while (0)
#define kvm_vm_check_mem_attr(s, attr) \
kvm_vm_check_attr(s, KVM_S390_VM_MEM_CTRL, attr)
@ -912,11 +902,11 @@ static void determine_sw_breakpoint_instr(void)
if (kvm_vm_enable_cap(kvm_state, KVM_CAP_S390_USER_INSTR0, 0)) {
sw_bp_inst = diag_501;
sw_bp_ilen = sizeof(diag_501);
DPRINTF("KVM: will use 4-byte sw breakpoints.\n");
trace_kvm_sw_breakpoint(4);
} else {
sw_bp_inst = instr_0x0000;
sw_bp_ilen = sizeof(instr_0x0000);
DPRINTF("KVM: will use 2-byte sw breakpoints.\n");
trace_kvm_sw_breakpoint(2);
}
}
@ -1307,7 +1297,7 @@ static int handle_b2(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1)
break;
default:
rc = -1;
DPRINTF("KVM: unhandled PRIV: 0xb2%x\n", ipa1);
trace_kvm_insn_unhandled_priv(ipa1);
break;
}
@ -1487,7 +1477,7 @@ static int handle_b9(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1)
break;
default:
r = -1;
DPRINTF("KVM: unhandled PRIV: 0xb9%x\n", ipa1);
trace_kvm_insn_unhandled_priv(ipa1);
break;
}
@ -1511,7 +1501,7 @@ static int handle_eb(S390CPU *cpu, struct kvm_run *run, uint8_t ipbl)
break;
default:
r = -1;
DPRINTF("KVM: unhandled PRIV: 0xeb%x\n", ipbl);
trace_kvm_insn_unhandled_priv(ipbl);
break;
}
@ -1531,7 +1521,7 @@ static int handle_e3(S390CPU *cpu, struct kvm_run *run, uint8_t ipbl)
break;
default:
r = -1;
DPRINTF("KVM: unhandled PRIV: 0xe3%x\n", ipbl);
trace_kvm_insn_unhandled_priv(ipbl);
break;
}
@ -1654,7 +1644,7 @@ static int handle_diag(S390CPU *cpu, struct kvm_run *run, uint32_t ipb)
r = handle_sw_breakpoint(cpu, run);
break;
default:
DPRINTF("KVM: unknown DIAG: 0x%x\n", func_code);
trace_kvm_insn_diag(func_code);
kvm_s390_program_interrupt(cpu, PGM_SPECIFICATION);
break;
}
@ -1684,8 +1674,7 @@ static int handle_instruction(S390CPU *cpu, struct kvm_run *run)
uint8_t ipa1 = run->s390_sieic.ipa & 0x00ff;
int r = -1;
DPRINTF("handle_instruction 0x%x 0x%x\n",
run->s390_sieic.ipa, run->s390_sieic.ipb);
trace_kvm_insn(run->s390_sieic.ipa, run->s390_sieic.ipb);
switch (ipa0) {
case IPA0_B2:
r = handle_b2(cpu, run, ipa1);
@ -1765,7 +1754,7 @@ static int handle_intercept(S390CPU *cpu)
int icpt_code = run->s390_sieic.icptcode;
int r = 0;
DPRINTF("intercept: 0x%x (at 0x%lx)\n", icpt_code, (long)run->psw_addr);
trace_kvm_intercept(icpt_code, (long)run->psw_addr);
switch (icpt_code) {
case ICPT_INSTRUCTION:
case ICPT_PV_INSTR:
@ -2150,13 +2139,13 @@ int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
uint32_t vec = data & ZPCI_MSI_VEC_MASK;
if (!dev) {
DPRINTF("add_msi_route no pci device\n");
trace_kvm_msi_route_fixup("no pci device");
return -ENODEV;
}
pbdev = s390_pci_find_dev_by_target(s390_get_phb(), DEVICE(dev)->id);
if (!pbdev) {
DPRINTF("add_msi_route no zpci device\n");
trace_kvm_msi_route_fixup("no zpci device");
return -ENODEV;
}

View File

@ -5,3 +5,10 @@ kvm_enable_cmma(int rc) "CMMA: enabling with result code %d"
kvm_clear_cmma(int rc) "CMMA: clearing with result code %d"
kvm_failed_cpu_state_set(int cpu_index, uint8_t state, const char *msg) "Warning: Unable to set cpu %d state %" PRIu8 " to KVM: %s"
kvm_assign_subch_ioeventfd(int fd, uint32_t addr, bool assign, int datamatch) "fd: %d sch: @0x%x assign: %d vq: %d"
kvm_sw_breakpoint(uint32_t n) "KVM: will use %d-byte sw breakpoints"
kvm_insn_unhandled_priv(uint32_t x) "KVM: unhandled PRIV: 0x%x"
kvm_insn_diag(uint32_t x) "KVM: unknown DIAG: 0x%x"
kvm_insn(uint32_t ipa, uint32_t ipb) "handle_instruction 0x%x 0x%x"
kvm_intercept(uint32_t icpt_code, uint64_t psw_addr) "intercept: 0x%x (at 0x%"PRIx64"lx)"
kvm_msi_route_fixup(const char* msg) "%s"

View File

@ -57,7 +57,7 @@
#define FPF_LONG 3
#define FPF_EXT 4
static inline bool valid_vec_element(uint8_t enr, MemOp es)
static inline bool valid_vec_element(uint16_t enr, MemOp es)
{
return !(enr & ~(NUM_VEC_ELEMENTS(es) - 1));
}
@ -964,7 +964,7 @@ static DisasJumpType op_vpdi(DisasContext *s, DisasOps *o)
static DisasJumpType op_vrep(DisasContext *s, DisasOps *o)
{
const uint8_t enr = get_field(s, i2);
const uint16_t enr = get_field(s, i2);
const uint8_t es = get_field(s, m4);
if (es > ES_64 || !valid_vec_element(enr, es)) {
@ -3047,7 +3047,7 @@ static DisasJumpType op_vfmax(DisasContext *s, DisasOps *o)
const uint8_t m5 = get_field(s, m5);
gen_helper_gvec_3_ptr *fn;
if (m6 == 5 || m6 == 6 || m6 == 7 || m6 >= 13) {
if (m6 == 5 || m6 == 6 || m6 == 7 || m6 >= 13 || (m5 & 7)) {
gen_program_exception(s, PGM_SPECIFICATION);
return DISAS_NORETURN;
}

View File

@ -193,7 +193,7 @@ void HELPER(vstl)(CPUS390XState *env, const void *v1, uint64_t addr,
uint64_t bytes)
{
/* Probe write access before actually modifying memory */
probe_write_access(env, addr, bytes, GETPC());
probe_write_access(env, addr, MIN(bytes, 16), GETPC());
if (likely(bytes >= 16)) {
cpu_stq_data_ra(env, addr, s390_vec_read_element64(v1, 0), GETPC());

View File

@ -474,9 +474,9 @@ DEF_VSTRC_CC_RT_HELPER(32)
static int vstrs(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
const S390Vector *v4, uint8_t es, bool zs)
{
int substr_elen, substr_0, str_elen, i, j, k, cc;
int substr_elen, i, j, k, cc;
int nelem = 16 >> es;
bool eos = false;
int str_leftmost_0;
substr_elen = s390_vec_read_element8(v4, 7) >> es;
@ -498,47 +498,20 @@ static int vstrs(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
}
/* If ZS, look for eos in the searched string. */
str_leftmost_0 = nelem;
if (zs) {
for (k = 0; k < nelem; k++) {
if (s390_vec_read_element(v2, k, es) == 0) {
eos = true;
str_leftmost_0 = k;
break;
}
}
str_elen = k;
} else {
str_elen = nelem;
}
substr_0 = s390_vec_read_element(v3, 0, es);
for (k = 0; ; k++) {
for (; k < str_elen; k++) {
if (s390_vec_read_element(v2, k, es) == substr_0) {
break;
}
}
/* If we reached the end of the string, no match. */
if (k == str_elen) {
cc = eos; /* no match (with or without zero char) */
goto done;
}
/* If the substring is only one char, match. */
if (substr_elen == 1) {
cc = 2; /* full match */
goto done;
}
/* If the match begins at the last char, we have a partial match. */
if (k == str_elen - 1) {
cc = 3; /* partial match */
goto done;
}
cc = str_leftmost_0 == nelem ? 0 : 1; /* No match. */
for (k = 0; k < nelem; k++) {
i = MIN(nelem, k + substr_elen);
for (j = k + 1; j < i; j++) {
for (j = k; j < i; j++) {
uint32_t e2 = s390_vec_read_element(v2, j, es);
uint32_t e3 = s390_vec_read_element(v3, j - k, es);
if (e2 != e3) {
@ -546,9 +519,16 @@ static int vstrs(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
}
}
if (j == i) {
/* Matched up until "end". */
cc = i - k == substr_elen ? 2 : 3; /* full or partial match */
goto done;
/* All elements matched. */
if (k > str_leftmost_0) {
cc = 1; /* Ignored match. */
k = nelem;
} else if (i - k == substr_elen) {
cc = 2; /* Full match. */
} else {
cc = 3; /* Partial match. */
}
break;
}
}

View File

@ -59,6 +59,8 @@ Z13_TESTS=vistr
Z13_TESTS+=lcbb
Z13_TESTS+=locfhr
Z13_TESTS+=vcksm
Z13_TESTS+=vstl
Z13_TESTS+=vrep
$(Z13_TESTS): CFLAGS+=-march=z13 -O2
TESTS+=$(Z13_TESTS)
@ -73,6 +75,7 @@ ifneq ($(CROSS_CC_HAS_Z15),)
Z15_TESTS=vxeh2_vs
Z15_TESTS+=vxeh2_vcvt
Z15_TESTS+=vxeh2_vlstr
Z15_TESTS+=vxeh2_vstrs
$(Z15_TESTS): CFLAGS+=-march=z15 -O2
TESTS+=$(Z15_TESTS)
endif

81
tests/tcg/s390x/vrep.c Normal file
View File

@ -0,0 +1,81 @@
/*
* Test the VREP instruction.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <assert.h>
#include <signal.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "vx.h"
static void handle_sigill(int sig, siginfo_t *info, void *ucontext)
{
mcontext_t *mcontext = &((ucontext_t *)ucontext)->uc_mcontext;
char *insn = (char *)info->si_addr;
if (insn[0] != 0xe7 || insn[5] != 0x4d) {
_exit(EXIT_FAILURE);
}
mcontext->gregs[2] = SIGILL;
}
static inline __attribute__((__always_inline__)) unsigned long
vrep(S390Vector *v1, const S390Vector *v3, const uint16_t i2, const uint8_t m4)
{
register unsigned long sig asm("r2") = -1;
asm("vrep %[v1],%[v3],%[i2],%[m4]\n"
: [v1] "=v" (v1->v)
, [sig] "+r" (sig)
: [v3] "v" (v3->v)
, [i2] "i" (i2)
, [m4] "i" (m4));
return sig;
}
int main(int argc, char *argv[])
{
S390Vector v3 = {.d[0] = 1, .d[1] = 2};
struct sigaction act;
S390Vector v1;
int err;
memset(&act, 0, sizeof(act));
act.sa_sigaction = handle_sigill;
act.sa_flags = SA_SIGINFO;
err = sigaction(SIGILL, &act, NULL);
assert(err == 0);
assert(vrep(&v1, &v3, 7, 0) == -1);
assert(v1.d[0] == 0x0101010101010101ULL);
assert(v1.d[1] == 0x0101010101010101ULL);
assert(vrep(&v1, &v3, 7, 1) == -1);
assert(v1.d[0] == 0x0002000200020002ULL);
assert(v1.d[1] == 0x0002000200020002ULL);
assert(vrep(&v1, &v3, 1, 2) == -1);
assert(v1.d[0] == 0x0000000100000001ULL);
assert(v1.d[1] == 0x0000000100000001ULL);
assert(vrep(&v1, &v3, 1, 3) == -1);
assert(v1.d[0] == 2);
assert(v1.d[1] == 2);
assert(vrep(&v1, &v3, 0x10, 0) == SIGILL);
assert(vrep(&v1, &v3, 0x101, 0) == SIGILL);
assert(vrep(&v1, &v3, 0x8, 1) == SIGILL);
assert(vrep(&v1, &v3, 0x108, 1) == SIGILL);
assert(vrep(&v1, &v3, 0x4, 2) == SIGILL);
assert(vrep(&v1, &v3, 0x104, 2) == SIGILL);
assert(vrep(&v1, &v3, 0x2, 3) == SIGILL);
assert(vrep(&v1, &v3, 0x102, 3) == SIGILL);
return EXIT_SUCCESS;
}

37
tests/tcg/s390x/vstl.c Normal file
View File

@ -0,0 +1,37 @@
/*
* Test the VSTL instruction.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <assert.h>
#include <stdlib.h>
#include "vx.h"
static inline void vstl(S390Vector *v1, void *db2, size_t r3)
{
asm("vstl %[v1],%[r3],%[db2]"
: [db2] "=Q" (*(char *)db2)
: [v1] "v" (v1->v), [r3] "r" (r3)
: "memory");
}
int main(void)
{
uint64_t buf[3] = {0x1122334455667788ULL, 0x99aabbccddeeffULL,
0x5a5a5a5a5a5a5a5aULL};
S390Vector v = {.d[0] = 0x1234567887654321ULL,
.d[1] = 0x9abcdef00fedcba9ULL};
vstl(&v, buf, 0);
assert(buf[0] == 0x1222334455667788ULL);
vstl(&v, buf, 1);
assert(buf[0] == 0x1234334455667788ULL);
vstl(&v, buf, -1);
assert(buf[0] == 0x1234567887654321ULL);
assert(buf[1] == 0x9abcdef00fedcba9ULL);
assert(buf[2] == 0x5a5a5a5a5a5a5a5aULL);
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,88 @@
/*
* Test the VSTRS instruction.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "vx.h"
static inline __attribute__((__always_inline__)) int
vstrs(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
const S390Vector *v4, const uint8_t m5, const uint8_t m6)
{
int cc;
asm("vstrs %[v1],%[v2],%[v3],%[v4],%[m5],%[m6]\n"
"ipm %[cc]"
: [v1] "=v" (v1->v)
, [cc] "=r" (cc)
: [v2] "v" (v2->v)
, [v3] "v" (v3->v)
, [v4] "v" (v4->v)
, [m5] "i" (m5)
, [m6] "i" (m6)
: "cc");
return (cc >> 28) & 3;
}
static void test_ignored_match(void)
{
S390Vector v1;
S390Vector v2 = {.d[0] = 0x222000205e410000ULL, .d[1] = 0};
S390Vector v3 = {.d[0] = 0x205e410000000000ULL, .d[1] = 0};
S390Vector v4 = {.d[0] = 3, .d[1] = 0};
assert(vstrs(&v1, &v2, &v3, &v4, 0, 2) == 1);
assert(v1.d[0] == 16);
assert(v1.d[1] == 0);
}
static void test_empty_needle(void)
{
S390Vector v1;
S390Vector v2 = {.d[0] = 0x5300000000000000ULL, .d[1] = 0};
S390Vector v3 = {.d[0] = 0, .d[1] = 0};
S390Vector v4 = {.d[0] = 0, .d[1] = 0};
assert(vstrs(&v1, &v2, &v3, &v4, 0, 0) == 2);
assert(v1.d[0] == 0);
assert(v1.d[1] == 0);
}
static void test_max_length(void)
{
S390Vector v1;
S390Vector v2 = {.d[0] = 0x1122334455667700ULL, .d[1] = 0};
S390Vector v3 = {.d[0] = 0, .d[1] = 0};
S390Vector v4 = {.d[0] = 16, .d[1] = 0};
assert(vstrs(&v1, &v2, &v3, &v4, 0, 0) == 3);
assert(v1.d[0] == 7);
assert(v1.d[1] == 0);
}
static void test_no_match(void)
{
S390Vector v1;
S390Vector v2 = {.d[0] = 0xffffff000fffff00ULL, .d[1] = 0x82b};
S390Vector v3 = {.d[0] = 0xfffffffeffffffffULL,
.d[1] = 0xffffffff00000000ULL};
S390Vector v4 = {.d[0] = 11, .d[1] = 0};
assert(vstrs(&v1, &v2, &v3, &v4, 0, 2) == 1);
assert(v1.d[0] == 16);
assert(v1.d[1] == 0);
}
int main(void)
{
test_ignored_match();
test_empty_needle();
test_max_length();
test_no_match();
return EXIT_SUCCESS;
}