First (big) chunk of s390x updates:

- cpumodel support for s390x
 - various fixes and improvements
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJXztxBAAoJEN7Pa5PG8C+vMScP/3AjIhWHy1h5iTZhjAOz+vIX
 1JzCj3/vWf+1JxEYbKO7ySLXG4KbwMPHyWfGvlEyeYpt+ICXE9V0wXU1+t/y7SCr
 zTDVBjpWJlVm26/Dix2Ejvk5Dqe1E485GSnxfQfFTglafaZqt2cQ4sSOL+M3VChZ
 MJtFpDRils4QOqxk3RrHAv+L7D0mKgBIDutSpojkY/B9z7pGr/lZVpgjam4wB+6S
 f2KmzKJ1u0U00f1dE5BN/wf5cd1pr+N3FyXshKxZOZ4v9AfYolZ9tcruqHmgXWYS
 Z708D4SgoOshmEzztzmjyoDgaOUxpOiA2NUuOS4PlElJMKob/8b1+XDVxv9qfC5p
 NRSmmzne9UdsEHy6fz+/URJgM+qf9IadcusL94ocbtYLfEYUFaQ5ja81qQ1NM0Uo
 TLuRknFknc0cotq1+UVQsfyOPyKEypt2XNPkPpgV15+XZG1WlElCTZfMPOuP7zYU
 YG3FBDqBj4JidkEYpg/w+ARH6fzaRAOISLclJFgFa4poyutbbr88AF1NzHmMyjDM
 Kvj7NFRfhBgm+vGs4s9ZNgGGfxaHBdzd5xV1u+xYaeW25VCFlOGk/7d5jXDCvnvm
 Juv8SMai3fgFfEis5eZmZEz3Sq1Zja3jCqq0tJmFkJMC3tmFniDzh+9KQso2mMZo
 ezRdgCkmdOm/OyVwhNy6
 =hiH2
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20160906-v2' into staging

First (big) chunk of s390x updates:
- cpumodel support for s390x
- various fixes and improvements

# gpg: Signature made Tue 06 Sep 2016 16:09:53 BST
# gpg:                using RSA key 0xDECF6B93C6F02FAF
# gpg: Good signature from "Cornelia Huck <huckc@linux.vnet.ibm.com>"
# gpg:                 aka "Cornelia Huck <cornelia.huck@de.ibm.com>"
# Primary key fingerprint: C3D0 D66D C362 4FF6 A8C0  18CE DECF 6B93 C6F0 2FAF

* remotes/cohuck/tags/s390x-20160906-v2: (38 commits)
  s390x/cpumodel: implement QMP interface "query-cpu-model-baseline"
  s390x/cpumodel: implement QMP interface "query-cpu-model-comparison"
  s390x/cpumodel: implement QMP interface "query-cpu-model-expansion"
  qmp: add QMP interface "query-cpu-model-baseline"
  qmp: add QMP interface "query-cpu-model-comparison"
  qmp: add QMP interface "query-cpu-model-expansion"
  s390x/kvm: don't enable key wrapping if msa3 is disabled
  s390x/kvm: let the CPU model control CMM(A)
  s390x/kvm: disable host model for problematic compat machines
  s390x/kvm: implement CPU model support
  s390x/kvm: allow runtime-instrumentation for "none" machine
  s390x/sclp: propagate hmfai
  s390x/sclp: propagate the mha via sclp
  s390x/sclp: propagate the ibc val (lowest and unblocked ibc)
  s390x/sclp: indicate sclp features
  s390x/sclp: introduce sclp feature blocks
  s390x/sclp: factor out preparation of cpu entries
  s390x/cpumodel: check and apply the CPU model
  s390x/cpumodel: let the CPU model handle feature checks
  s390x/cpumodel: expose features and feature groups as properties
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2016-09-06 16:17:19 +01:00
commit f9ae6bcf1d
45 changed files with 3672 additions and 121 deletions

View file

@ -212,7 +212,7 @@ hmp-commands-info.h: $(SRC_PATH)/hmp-commands-info.hx $(SRC_PATH)/scripts/hxtool
qmp-commands-old.h: $(SRC_PATH)/qmp-commands.hx $(SRC_PATH)/scripts/hxtool
$(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@," GEN $(TARGET_DIR)$@")
clean:
clean: clean-target
rm -f *.a *~ $(PROGS)
rm -f $(shell find . -name '*.[od]')
rm -f hmp-commands.h qmp-commands-old.h gdbstub-xml.c

View file

@ -280,12 +280,13 @@ static void kvm_s390_release_adapter_routes(S390FLICState *fs,
* kvm_flic_save - Save pending floating interrupts
* @f: QEMUFile containing migration state
* @opaque: pointer to flic device state
* @size: ignored
*
* Note: Pass buf and len to kernel. Start with one page and
* increase until buffer is sufficient or maxium size is
* reached
*/
static void kvm_flic_save(QEMUFile *f, void *opaque)
static void kvm_flic_save(QEMUFile *f, void *opaque, size_t size)
{
KVMS390FLICState *flic = opaque;
int len = FLIC_SAVE_INITIAL_SIZE;
@ -324,24 +325,19 @@ static void kvm_flic_save(QEMUFile *f, void *opaque)
* kvm_flic_load - Load pending floating interrupts
* @f: QEMUFile containing migration state
* @opaque: pointer to flic device state
* @version_id: version id for migration
* @size: ignored
*
* Returns: value of flic_enqueue_irqs, -EINVAL on error
* Note: Do nothing when no interrupts where stored
* in QEMUFile
*/
static int kvm_flic_load(QEMUFile *f, void *opaque, int version_id)
static int kvm_flic_load(QEMUFile *f, void *opaque, size_t size)
{
uint64_t len = 0;
uint64_t count = 0;
void *buf = NULL;
int r = 0;
if (version_id != FLIC_SAVEVM_VERSION) {
r = -EINVAL;
goto out;
}
flic_enable_pfault((struct KVMS390FLICState *) opaque);
count = qemu_get_be64(f);
@ -372,6 +368,24 @@ out:
return r;
}
static const VMStateDescription kvm_s390_flic_vmstate = {
.name = "s390-flic",
.version_id = FLIC_SAVEVM_VERSION,
.minimum_version_id = FLIC_SAVEVM_VERSION,
.fields = (VMStateField[]) {
{
.name = "irqs",
.info = &(const VMStateInfo) {
.name = "irqs",
.get = kvm_flic_load,
.put = kvm_flic_save,
},
.flags = VMS_SINGLE,
},
VMSTATE_END_OF_LIST()
}
};
static void kvm_s390_flic_realize(DeviceState *dev, Error **errp)
{
KVMS390FLICState *flic_state = KVM_S390_FLIC(dev);
@ -398,16 +412,6 @@ static void kvm_s390_flic_realize(DeviceState *dev, Error **errp)
flic_state->clear_io_supported = !ioctl(flic_state->fd,
KVM_HAS_DEVICE_ATTR, test_attr);
/* Register savevm handler for floating interrupts */
register_savevm(NULL, "s390-flic", 0, 1, kvm_flic_save,
kvm_flic_load, (void *) flic_state);
}
static void kvm_s390_flic_unrealize(DeviceState *dev, Error **errp)
{
KVMS390FLICState *flic_state = KVM_S390_FLIC(dev);
unregister_savevm(DEVICE(flic_state), "s390-flic", flic_state);
}
static void kvm_s390_flic_reset(DeviceState *dev)
@ -438,7 +442,7 @@ static void kvm_s390_flic_class_init(ObjectClass *oc, void *data)
S390FLICStateClass *fsc = S390_FLIC_COMMON_CLASS(oc);
dc->realize = kvm_s390_flic_realize;
dc->unrealize = kvm_s390_flic_unrealize;
dc->vmsd = &kvm_s390_flic_vmstate;
dc->reset = kvm_s390_flic_reset;
fsc->register_io_adapter = kvm_s390_register_io_adapter;
fsc->io_adapter_map = kvm_s390_io_adapter_map;

View file

@ -141,7 +141,8 @@ out_err:
int css_create_css_image(uint8_t cssid, bool default_image)
{
trace_css_new_image(cssid, default_image ? "(default)" : "");
if (cssid > MAX_CSSID) {
/* 255 is reserved */
if (cssid == 255) {
return -EINVAL;
}
if (channel_subsys.css[cssid]) {
@ -1267,7 +1268,7 @@ bool css_schid_final(int m, uint8_t cssid, uint8_t ssid, uint16_t schid)
uint8_t real_cssid;
real_cssid = (!m && (cssid == 0)) ? channel_subsys.default_cssid : cssid;
if (real_cssid > MAX_CSSID || ssid > MAX_SSID ||
if (ssid > MAX_SSID ||
!channel_subsys.css[real_cssid] ||
!channel_subsys.css[real_cssid]->sch_set[ssid]) {
return true;
@ -1282,9 +1283,6 @@ static int css_add_virtual_chpid(uint8_t cssid, uint8_t chpid, uint8_t type)
CssImage *css;
trace_css_chpid_add(cssid, chpid, type);
if (cssid > MAX_CSSID) {
return -EINVAL;
}
css = channel_subsys.css[cssid];
if (!css) {
return -EINVAL;

View file

@ -649,6 +649,7 @@ static void s390_pcihost_hot_plug(HotplugHandler *hotplug_dev,
pbdev = s390_pci_device_new(dev->id);
if (!pbdev) {
error_setg(errp, "create zpci device failed");
return;
}
}
@ -717,11 +718,7 @@ static void s390_pcihost_hot_unplug(HotplugHandler *hotplug_dev,
break;
}
}
if (!pbdev) {
object_unparent(OBJECT(pci_dev));
return;
}
assert(pbdev != NULL);
} else if (object_dynamic_cast(OBJECT(dev), TYPE_S390_PCI_DEVICE)) {
pbdev = S390_PCI_DEVICE(dev);
pci_dev = pbdev->pdev;

View file

@ -249,6 +249,11 @@ bool ri_allowed(void)
return s390mc->ri_allowed;
}
/*
* Make sure the "none" machine can have ri, otherwise it won't * be
* unlocked in KVM and therefore the host CPU model might be wrong.
*/
return true;
}
return 0;
}
@ -316,7 +321,11 @@ static const TypeInfo ccw_machine_info = {
} \
type_init(ccw_machine_register_##suffix)
#define CCW_COMPAT_2_7 \
HW_COMPAT_2_7
#define CCW_COMPAT_2_6 \
CCW_COMPAT_2_7 \
HW_COMPAT_2_6 \
{\
.driver = TYPE_S390_IPL,\
@ -372,14 +381,26 @@ static const TypeInfo ccw_machine_info = {
.value = "0",\
},
static void ccw_machine_2_8_instance_options(MachineState *machine)
{
}
static void ccw_machine_2_8_class_options(MachineClass *mc)
{
}
DEFINE_CCW_MACHINE(2_8, "2.8", true);
static void ccw_machine_2_7_instance_options(MachineState *machine)
{
ccw_machine_2_8_instance_options(machine);
}
static void ccw_machine_2_7_class_options(MachineClass *mc)
{
ccw_machine_2_8_class_options(mc);
SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_7);
}
DEFINE_CCW_MACHINE(2_7, "2.7", true);
DEFINE_CCW_MACHINE(2_7, "2.7", false);
static void ccw_machine_2_6_instance_options(MachineState *machine)
{

View file

@ -101,7 +101,11 @@ void s390_init_cpus(MachineState *machine)
gchar *name;
if (machine->cpu_model == NULL) {
machine->cpu_model = "host";
if (kvm_enabled()) {
machine->cpu_model = "host";
} else {
machine->cpu_model = "qemu";
}
}
cpu_states = g_new0(S390CPU *, max_cpus);

View file

@ -26,7 +26,25 @@
static inline SCLPDevice *get_sclp_device(void)
{
return SCLP(object_resolve_path_type("", TYPE_SCLP, NULL));
static SCLPDevice *sclp;
if (!sclp) {
sclp = SCLP(object_resolve_path_type("", TYPE_SCLP, NULL));
}
return sclp;
}
static void prepare_cpu_entries(SCLPDevice *sclp, CPUEntry *entry, int count)
{
uint8_t features[SCCB_CPU_FEATURE_LEN] = { 0 };
int i;
s390_get_feat_block(S390_FEAT_TYPE_SCLP_CPU, features);
for (i = 0; i < count; i++) {
entry[i].address = i;
entry[i].type = 0;
memcpy(entry[i].features, features, sizeof(entry[i].features));
}
}
/* Provide information about the configuration, CPUs and storage */
@ -37,7 +55,6 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
sclpMemoryHotplugDev *mhd = get_sclp_memory_hotplug_dev();
CPUState *cpu;
int cpu_count = 0;
int i = 0;
int rnsize, rnmax;
int slots = MIN(machine->ram_slots, s390_get_memslot_count(kvm_state));
@ -50,10 +67,15 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
read_info->offset_cpu = cpu_to_be16(offsetof(ReadInfo, entries));
read_info->highest_cpu = cpu_to_be16(max_cpus);
for (i = 0; i < cpu_count; i++) {
read_info->entries[i].address = i;
read_info->entries[i].type = 0;
}
read_info->ibc_val = cpu_to_be32(s390_get_ibc_val());
/* Configuration Characteristic (Extension) */
s390_get_feat_block(S390_FEAT_TYPE_SCLP_CONF_CHAR,
read_info->conf_char);
s390_get_feat_block(S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT,
read_info->conf_char_ext);
prepare_cpu_entries(sclp, read_info->entries, cpu_count);
read_info->facilities = cpu_to_be64(SCLP_HAS_CPU_INFO |
SCLP_HAS_PCI_RECONFIG);
@ -88,6 +110,8 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
read_info->facilities |= cpu_to_be64(SCLP_FC_ASSIGN_ATTACH_READ_STOR);
}
read_info->mha_pow = s390_get_mha_pow();
read_info->hmfai = cpu_to_be32(s390_get_hmfai());
rnsize = 1 << (sclp->increment_size - 20);
if (rnsize <= 128) {
@ -304,7 +328,6 @@ static void sclp_read_cpu_info(SCLPDevice *sclp, SCCB *sccb)
ReadCpuInfo *cpu_info = (ReadCpuInfo *) sccb;
CPUState *cpu;
int cpu_count = 0;
int i = 0;
CPU_FOREACH(cpu) {
cpu_count++;
@ -318,10 +341,7 @@ static void sclp_read_cpu_info(SCLPDevice *sclp, SCCB *sccb)
cpu_info->offset_standby = cpu_to_be16(cpu_info->offset_configured
+ cpu_info->nr_configured*sizeof(CPUEntry));
for (i = 0; i < cpu_count; i++) {
cpu_info->entries[i].address = i;
cpu_info->entries[i].type = 0;
}
prepare_cpu_entries(sclp, cpu_info->entries, cpu_count);
sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_READ_COMPLETION);
}

View file

@ -1,6 +1,9 @@
#ifndef HW_COMPAT_H
#define HW_COMPAT_H
#define HW_COMPAT_2_7 \
/* empty */
#define HW_COMPAT_2_6 \
{\
.driver = "virtio-mmio",\

View file

@ -20,7 +20,7 @@
#define MAX_DEVNO 65535
#define MAX_SCHID 65535
#define MAX_SSID 3
#define MAX_CSSID 254 /* 255 is reserved */
#define MAX_CSSID 255
#define MAX_CHPID 255
#define MAX_CIWS 62

View file

@ -98,11 +98,14 @@ typedef struct SCCBHeader {
} QEMU_PACKED SCCBHeader;
#define SCCB_DATA_LEN (SCCB_SIZE - sizeof(SCCBHeader))
#define SCCB_CPU_FEATURE_LEN 6
/* CPU information */
typedef struct CPUEntry {
uint8_t address;
uint8_t reserved0[13];
uint8_t reserved0;
uint8_t features[SCCB_CPU_FEATURE_LEN];
uint8_t reserved2[6];
uint8_t type;
uint8_t reserved1;
} QEMU_PACKED CPUEntry;
@ -118,12 +121,18 @@ typedef struct ReadInfo {
uint8_t loadparm[8]; /* 24-31 */
uint8_t _reserved3[48 - 32]; /* 32-47 */
uint64_t facilities; /* 48-55 */
uint8_t _reserved0[100 - 56];
uint8_t _reserved0[76 - 56]; /* 56-75 */
uint32_t ibc_val;
uint8_t conf_char[96 - 80]; /* 80-95 */
uint8_t _reserved4[99 - 96]; /* 96-98 */
uint8_t mha_pow;
uint32_t rnsize2;
uint64_t rnmax2;
uint8_t _reserved4[120-112]; /* 112-119 */
uint8_t _reserved6[116 - 112]; /* 112-115 */
uint8_t conf_char_ext[120 - 116]; /* 116-119 */
uint16_t highest_cpu;
uint8_t _reserved5[128 - 122]; /* 122-127 */
uint8_t _reserved5[124 - 122]; /* 122-123 */
uint32_t hmfai;
struct CPUEntry entries[0];
} QEMU_PACKED ReadInfo;

View file

@ -611,6 +611,37 @@
#define KEY_KBDINPUTASSIST_ACCEPT 0x264
#define KEY_KBDINPUTASSIST_CANCEL 0x265
/* Diagonal movement keys */
#define KEY_RIGHT_UP 0x266
#define KEY_RIGHT_DOWN 0x267
#define KEY_LEFT_UP 0x268
#define KEY_LEFT_DOWN 0x269
#define KEY_ROOT_MENU 0x26a /* Show Device's Root Menu */
/* Show Top Menu of the Media (e.g. DVD) */
#define KEY_MEDIA_TOP_MENU 0x26b
#define KEY_NUMERIC_11 0x26c
#define KEY_NUMERIC_12 0x26d
/*
* Toggle Audio Description: refers to an audio service that helps blind and
* visually impaired consumers understand the action in a program. Note: in
* some countries this is referred to as "Video Description".
*/
#define KEY_AUDIO_DESC 0x26e
#define KEY_3D_MODE 0x26f
#define KEY_NEXT_FAVORITE 0x270
#define KEY_STOP_RECORD 0x271
#define KEY_PAUSE_RECORD 0x272
#define KEY_VOD 0x273 /* Video on Demand */
#define KEY_UNMUTE 0x274
#define KEY_FASTREVERSE 0x275
#define KEY_SLOWREVERSE 0x276
/*
* Control a data application associated with the currently viewed channel,
* e.g. teletext or data broadcast application (MHEG, MHP, HbbTV, etc.)
*/
#define KEY_DATA 0x275
#define BTN_TRIGGER_HAPPY 0x2c0
#define BTN_TRIGGER_HAPPY1 0x2c0
#define BTN_TRIGGER_HAPPY2 0x2c1
@ -749,6 +780,7 @@
#define SW_ROTATE_LOCK 0x0c /* set = rotate locked/disabled */
#define SW_LINEIN_INSERT 0x0d /* set = inserted */
#define SW_MUTE_DEVICE 0x0e /* set = device disabled */
#define SW_PEN_INSERTED 0x0f /* set = pen inserted */
#define SW_MAX_ 0x0f
#define SW_CNT (SW_MAX_+1)

View file

@ -244,6 +244,7 @@ struct input_mask {
#define BUS_ATARI 0x1B
#define BUS_SPI 0x1C
#define BUS_RMI 0x1D
#define BUS_CEC 0x1E
/*
* MT_TOOL types

View file

@ -49,7 +49,7 @@
* transport being used (eg. virtio_ring), the rest are per-device feature
* bits. */
#define VIRTIO_TRANSPORT_F_START 28
#define VIRTIO_TRANSPORT_F_END 33
#define VIRTIO_TRANSPORT_F_END 34
#ifndef VIRTIO_CONFIG_NO_LEGACY
/* Do we get callbacks when the ring is completely used, even if we've
@ -63,4 +63,12 @@
/* v1.0 compliant. */
#define VIRTIO_F_VERSION_1 32
/*
* If clear - device has the IOMMU bypass quirk feature.
* If set - use platform tools to detect the IOMMU.
*
* Note the reverse polarity (compared to most other features),
* this is for compatibility with legacy systems.
*/
#define VIRTIO_F_IOMMU_PLATFORM 33
#endif /* _LINUX_VIRTIO_CONFIG_H */

View file

@ -41,5 +41,6 @@
#define VIRTIO_ID_CAIF 12 /* Virtio caif */
#define VIRTIO_ID_GPU 16 /* virtio GPU */
#define VIRTIO_ID_INPUT 18 /* virtio input */
#define VIRTIO_ID_VSOCK 19 /* virtio vsock transport */
#endif /* _LINUX_VIRTIO_IDS_H */

View file

@ -35,6 +35,7 @@
#define VIRTIO_NET_F_CSUM 0 /* Host handles pkts w/ partial csum */
#define VIRTIO_NET_F_GUEST_CSUM 1 /* Guest handles pkts w/ partial csum */
#define VIRTIO_NET_F_CTRL_GUEST_OFFLOADS 2 /* Dynamic offload configuration. */
#define VIRTIO_NET_F_MTU 3 /* Initial MTU advice */
#define VIRTIO_NET_F_MAC 5 /* Host has given MAC address. */
#define VIRTIO_NET_F_GUEST_TSO4 7 /* Guest can handle TSOv4 in. */
#define VIRTIO_NET_F_GUEST_TSO6 8 /* Guest can handle TSOv6 in. */
@ -73,6 +74,8 @@ struct virtio_net_config {
* Legal values are between 1 and 0x8000
*/
uint16_t max_virtqueue_pairs;
/* Default maximum transmit unit advice */
uint16_t mtu;
} QEMU_PACKED;
/*

View file

@ -0,0 +1,94 @@
/*
* This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so
* anyone can use the definitions to implement compatible drivers/servers:
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of IBM nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Copyright (C) Red Hat, Inc., 2013-2015
* Copyright (C) Asias He <asias@redhat.com>, 2013
* Copyright (C) Stefan Hajnoczi <stefanha@redhat.com>, 2015
*/
#ifndef _LINUX_VIRTIO_VSOCK_H
#define _LINUX_VIRTIO_VSOCK_H
#include "standard-headers/linux/types.h"
#include "standard-headers/linux/virtio_ids.h"
#include "standard-headers/linux/virtio_config.h"
struct virtio_vsock_config {
uint64_t guest_cid;
} QEMU_PACKED;
enum virtio_vsock_event_id {
VIRTIO_VSOCK_EVENT_TRANSPORT_RESET = 0,
};
struct virtio_vsock_event {
uint32_t id;
} QEMU_PACKED;
struct virtio_vsock_hdr {
uint64_t src_cid;
uint64_t dst_cid;
uint32_t src_port;
uint32_t dst_port;
uint32_t len;
uint16_t type; /* enum virtio_vsock_type */
uint16_t op; /* enum virtio_vsock_op */
uint32_t flags;
uint32_t buf_alloc;
uint32_t fwd_cnt;
} QEMU_PACKED;
enum virtio_vsock_type {
VIRTIO_VSOCK_TYPE_STREAM = 1,
};
enum virtio_vsock_op {
VIRTIO_VSOCK_OP_INVALID = 0,
/* Connect operations */
VIRTIO_VSOCK_OP_REQUEST = 1,
VIRTIO_VSOCK_OP_RESPONSE = 2,
VIRTIO_VSOCK_OP_RST = 3,
VIRTIO_VSOCK_OP_SHUTDOWN = 4,
/* To send payload */
VIRTIO_VSOCK_OP_RW = 5,
/* Tell the peer our credit info */
VIRTIO_VSOCK_OP_CREDIT_UPDATE = 6,
/* Request the peer to send the credit info to us */
VIRTIO_VSOCK_OP_CREDIT_REQUEST = 7,
};
/* VIRTIO_VSOCK_OP_SHUTDOWN flags values */
enum virtio_vsock_shutdown {
VIRTIO_VSOCK_SHUTDOWN_RCV = 1,
VIRTIO_VSOCK_SHUTDOWN_SEND = 2,
};
#endif /* _LINUX_VIRTIO_VSOCK_H */

View file

@ -35,5 +35,14 @@ int kvm_available(void);
int xen_available(void);
CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp);
CpuModelExpansionInfo *arch_query_cpu_model_expansion(CpuModelExpansionType type,
CpuModelInfo *mode,
Error **errp);
CpuModelCompareInfo *arch_query_cpu_model_comparison(CpuModelInfo *modela,
CpuModelInfo *modelb,
Error **errp);
CpuModelBaselineInfo *arch_query_cpu_model_baseline(CpuModelInfo *modela,
CpuModelInfo *modelb,
Error **errp);
#endif

View file

@ -139,8 +139,8 @@ struct kvm_arch_memory_slot {
#define ARM_CP15_REG64(...) __ARM_CP15_REG64(__VA_ARGS__)
#define KVM_REG_ARM_TIMER_CTL ARM_CP15_REG32(0, 14, 3, 1)
#define KVM_REG_ARM_TIMER_CNT ARM_CP15_REG64(1, 14)
#define KVM_REG_ARM_TIMER_CVAL ARM_CP15_REG64(3, 14)
#define KVM_REG_ARM_TIMER_CNT ARM_CP15_REG64(1, 14)
#define KVM_REG_ARM_TIMER_CVAL ARM_CP15_REG64(3, 14)
/* Normal registers are mapped as coprocessor 16. */
#define KVM_REG_ARM_CORE (0x0010 << KVM_REG_ARM_COPROC_SHIFT)

View file

@ -87,9 +87,11 @@ struct kvm_regs {
/* Supported VGICv3 address types */
#define KVM_VGIC_V3_ADDR_TYPE_DIST 2
#define KVM_VGIC_V3_ADDR_TYPE_REDIST 3
#define KVM_VGIC_ITS_ADDR_TYPE 4
#define KVM_VGIC_V3_DIST_SIZE SZ_64K
#define KVM_VGIC_V3_REDIST_SIZE (2 * SZ_64K)
#define KVM_VGIC_V3_ITS_SIZE (2 * SZ_64K)
#define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
#define KVM_ARM_VCPU_EL1_32BIT 1 /* CPU running a 32bit VM */

View file

@ -93,6 +93,47 @@ struct kvm_s390_vm_cpu_machine {
__u64 fac_list[256];
};
#define KVM_S390_VM_CPU_PROCESSOR_FEAT 2
#define KVM_S390_VM_CPU_MACHINE_FEAT 3
#define KVM_S390_VM_CPU_FEAT_NR_BITS 1024
#define KVM_S390_VM_CPU_FEAT_ESOP 0
#define KVM_S390_VM_CPU_FEAT_SIEF2 1
#define KVM_S390_VM_CPU_FEAT_64BSCAO 2
#define KVM_S390_VM_CPU_FEAT_SIIF 3
#define KVM_S390_VM_CPU_FEAT_GPERE 4
#define KVM_S390_VM_CPU_FEAT_GSLS 5
#define KVM_S390_VM_CPU_FEAT_IB 6
#define KVM_S390_VM_CPU_FEAT_CEI 7
#define KVM_S390_VM_CPU_FEAT_IBS 8
#define KVM_S390_VM_CPU_FEAT_SKEY 9
#define KVM_S390_VM_CPU_FEAT_CMMA 10
#define KVM_S390_VM_CPU_FEAT_PFMFI 11
#define KVM_S390_VM_CPU_FEAT_SIGPIF 12
struct kvm_s390_vm_cpu_feat {
__u64 feat[16];
};
#define KVM_S390_VM_CPU_PROCESSOR_SUBFUNC 4
#define KVM_S390_VM_CPU_MACHINE_SUBFUNC 5
/* for "test bit" instructions MSB 0 bit ordering, for "query" raw blocks */
struct kvm_s390_vm_cpu_subfunc {
__u8 plo[32]; /* always */
__u8 ptff[16]; /* with TOD-clock steering */
__u8 kmac[16]; /* with MSA */
__u8 kmc[16]; /* with MSA */
__u8 km[16]; /* with MSA */
__u8 kimd[16]; /* with MSA */
__u8 klmd[16]; /* with MSA */
__u8 pckmo[16]; /* with MSA3 */
__u8 kmctr[16]; /* with MSA4 */
__u8 kmf[16]; /* with MSA4 */
__u8 kmo[16]; /* with MSA4 */
__u8 pcc[16]; /* with MSA4 */
__u8 ppno[16]; /* with MSA5 */
__u8 reserved[1824];
};
/* kvm attributes for crypto */
#define KVM_S390_VM_CRYPTO_ENABLE_AES_KW 0
#define KVM_S390_VM_CRYPTO_ENABLE_DEA_KW 1

View file

@ -306,9 +306,7 @@
#define __NR_vmsplice (__X32_SYSCALL_BIT + 532)
#define __NR_move_pages (__X32_SYSCALL_BIT + 533)
#define __NR_preadv (__X32_SYSCALL_BIT + 534)
#define __NR_preadv2 (__X32_SYSCALL_BIT + 534)
#define __NR_pwritev (__X32_SYSCALL_BIT + 535)
#define __NR_pwritev2 (__X32_SYSCALL_BIT + 535)
#define __NR_rt_tgsigqueueinfo (__X32_SYSCALL_BIT + 536)
#define __NR_recvmmsg (__X32_SYSCALL_BIT + 537)
#define __NR_sendmmsg (__X32_SYSCALL_BIT + 538)
@ -319,5 +317,7 @@
#define __NR_io_setup (__X32_SYSCALL_BIT + 543)
#define __NR_io_submit (__X32_SYSCALL_BIT + 544)
#define __NR_execveat (__X32_SYSCALL_BIT + 545)
#define __NR_preadv2 (__X32_SYSCALL_BIT + 546)
#define __NR_pwritev2 (__X32_SYSCALL_BIT + 547)
#endif /* _ASM_X86_UNISTD_X32_H */

View file

@ -866,6 +866,10 @@ struct kvm_ppc_smmu_info {
#define KVM_CAP_ARM_PMU_V3 126
#define KVM_CAP_VCPU_ATTRIBUTES 127
#define KVM_CAP_MAX_VCPU_ID 128
#define KVM_CAP_X2APIC_API 129
#define KVM_CAP_S390_USER_INSTR0 130
#define KVM_CAP_MSI_DEVID 131
#define KVM_CAP_PPC_HTM 132
#ifdef KVM_CAP_IRQ_ROUTING
@ -878,7 +882,10 @@ struct kvm_irq_routing_msi {
__u32 address_lo;
__u32 address_hi;
__u32 data;
__u32 pad;
union {
__u32 pad;
__u32 devid;
};
};
struct kvm_irq_routing_s390_adapter {
@ -1024,12 +1031,14 @@ struct kvm_one_reg {
__u64 addr;
};
#define KVM_MSI_VALID_DEVID (1U << 0)
struct kvm_msi {
__u32 address_lo;
__u32 address_hi;
__u32 data;
__u32 flags;
__u8 pad[16];
__u32 devid;
__u8 pad[12];
};
struct kvm_arm_device_addr {
@ -1074,6 +1083,8 @@ enum kvm_device_type {
#define KVM_DEV_TYPE_FLIC KVM_DEV_TYPE_FLIC
KVM_DEV_TYPE_ARM_VGIC_V3,
#define KVM_DEV_TYPE_ARM_VGIC_V3 KVM_DEV_TYPE_ARM_VGIC_V3
KVM_DEV_TYPE_ARM_VGIC_ITS,
#define KVM_DEV_TYPE_ARM_VGIC_ITS KVM_DEV_TYPE_ARM_VGIC_ITS
KVM_DEV_TYPE_MAX,
};
@ -1313,4 +1324,7 @@ struct kvm_assigned_msix_entry {
__u16 padding[3];
};
#define KVM_X2APIC_API_USE_32BIT_IDS (1ULL << 0)
#define KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK (1ULL << 1)
#endif /* __LINUX_KVM_H */

View file

@ -47,6 +47,32 @@ struct vhost_vring_addr {
__u64 log_guest_addr;
};
/* no alignment requirement */
struct vhost_iotlb_msg {
__u64 iova;
__u64 size;
__u64 uaddr;
#define VHOST_ACCESS_RO 0x1
#define VHOST_ACCESS_WO 0x2
#define VHOST_ACCESS_RW 0x3
__u8 perm;
#define VHOST_IOTLB_MISS 1
#define VHOST_IOTLB_UPDATE 2
#define VHOST_IOTLB_INVALIDATE 3
#define VHOST_IOTLB_ACCESS_FAIL 4
__u8 type;
};
#define VHOST_IOTLB_MSG 0x1
struct vhost_msg {
int type;
union {
struct vhost_iotlb_msg iotlb;
__u8 padding[64];
};
};
struct vhost_memory_region {
__u64 guest_phys_addr;
__u64 memory_size; /* bytes */
@ -146,6 +172,8 @@ struct vhost_memory {
#define VHOST_F_LOG_ALL 26
/* vhost-net should add virtio_net_hdr for RX, and strip for TX packets. */
#define VHOST_NET_F_VIRTIO_NET_HDR 27
/* Vhost have device IOTLB */
#define VHOST_F_DEVICE_IOTLB 63
/* VHOST_SCSI specific definitions */
@ -175,4 +203,9 @@ struct vhost_scsi_target {
#define VHOST_SCSI_SET_EVENTS_MISSED _IOW(VHOST_VIRTIO, 0x43, __u32)
#define VHOST_SCSI_GET_EVENTS_MISSED _IOW(VHOST_VIRTIO, 0x44, __u32)
/* VHOST_VSOCK specific defines */
#define VHOST_VSOCK_SET_GUEST_CID _IOW(VHOST_VIRTIO, 0x60, __u64)
#define VHOST_VSOCK_SET_RUNNING _IOW(VHOST_VIRTIO, 0x61, int)
#endif

View file

@ -3038,10 +3038,22 @@
#
# @name: the name of the CPU definition
#
# @migration-safe: #optional whether a CPU definition can be safely used for
# migration in combination with a QEMU compatibility machine
# when migrating between different QMU versions and between
# hosts with different sets of (hardware or software)
# capabilities. If not provided, information is not available
# and callers should not assume the CPU definition to be
# migration-safe. (since 2.8)
#
# @static: whether a CPU definition is static and will not change depending on
# QEMU version, machine type, machine options and accelerator options.
# A static model is always migration-safe. (since 2.8)
#
# Since: 1.2.0
##
{ 'struct': 'CpuDefinitionInfo',
'data': { 'name': 'str' } }
'data': { 'name': 'str', '*migration-safe': 'bool', 'static': 'bool' } }
##
# @query-cpu-definitions:
@ -3054,6 +3066,238 @@
##
{ 'command': 'query-cpu-definitions', 'returns': ['CpuDefinitionInfo'] }
##
# @CpuModelInfo:
#
# Virtual CPU model.
#
# A CPU model consists of the name of a CPU definition, to which
# delta changes are applied (e.g. features added/removed). Most magic values
# that an architecture might require should be hidden behind the name.
# However, if required, architectures can expose relevant properties.
#
# @name: the name of the CPU definition the model is based on
# @props: #optional a dictionary of QOM properties to be applied
#
# Since: 2.8.0
##
{ 'struct': 'CpuModelInfo',
'data': { 'name': 'str',
'*props': 'any' } }
##
# @CpuModelExpansionType
#
# An enumeration of CPU model expansion types.
#
# @static: Expand to a static CPU model, a combination of a static base
# model name and property delta changes. As the static base model will
# never change, the expanded CPU model will be the same, independant of
# independent of QEMU version, machine type, machine options, and
# accelerator options. Therefore, the resulting model can be used by
# tooling without having to specify a compatibility machine - e.g. when
# displaying the "host" model. static CPU models are migration-safe.
#
# @full: Expand all properties. The produced model is not guaranteed to be
# migration-safe, but allows tooling to get an insight and work with
# model details.
#
# Since: 2.8.0
##
{ 'enum': 'CpuModelExpansionType',
'data': [ 'static', 'full' ] }
##
# @CpuModelExpansionInfo
#
# The result of a cpu model expansion.
#
# @model: the expanded CpuModelInfo.
#
# Since: 2.8.0
##
{ 'struct': 'CpuModelExpansionInfo',
'data': { 'model': 'CpuModelInfo' } }
##
# @query-cpu-model-expansion:
#
# Expands a given CPU model (or a combination of CPU model + additional options)
# to different granularities, allowing tooling to get an understanding what a
# specific CPU model looks like in QEMU under a certain configuration.
#
# This interface can be used to query the "host" CPU model.
#
# The data returned by this command may be affected by:
#
# * QEMU version: CPU models may look different depending on the QEMU version.
# (Except for CPU models reported as "static" in query-cpu-definitions.)
# * machine-type: CPU model may look different depending on the machine-type.
# (Except for CPU models reported as "static" in query-cpu-definitions.)
# * machine options (including accelerator): in some architectures, CPU models
# may look different depending on machine and accelerator options. (Except for
# CPU models reported as "static" in query-cpu-definitions.)
# * "-cpu" arguments and global properties: arguments to the -cpu option and
# global properties may affect expansion of CPU models. Using
# query-cpu-model-expansion while using these is not advised.
#
# Some architectures may not support all expansion types. s390x supports
# "full" and "static".
#
# Returns: a CpuModelExpansionInfo. Returns an error if expanding CPU models is
# not supported, if the model cannot be expanded, if the model contains
# an unknown CPU definition name, unknown properties or properties
# with a wrong type. Also returns an error if an expansion type is
# not supported.
#
# Since: 2.8.0
##
{ 'command': 'query-cpu-model-expansion',
'data': { 'type': 'CpuModelExpansionType',
'model': 'CpuModelInfo' },
'returns': 'CpuModelExpansionInfo' }
##
# @CpuModelCompareResult:
#
# An enumeration of CPU model comparation results. The result is usually
# calcualted using e.g. CPU features or CPU generations.
#
# @incompatible: If model A is incompatible to model B, model A is not
# guaranteed to run where model B runs and the other way around.
#
# @identical: If model A is identical to model B, model A is guaranteed to run
# where model B runs and the other way around.
#
# @superset: If model A is a superset of model B, model B is guaranteed to run
# where model A runs. There are no guarantees about the other way.
#
# @subset: If model A is a subset of model B, model A is guaranteed to run
# where model B runs. There are no guarantees about the other way.
#
# Since: 2.8.0
##
{ 'enum': 'CpuModelCompareResult',
'data': [ 'incompatible', 'identical', 'superset', 'subset' ] }
##
# @CpuModelCompareInfo
#
# The result of a CPU model comparison.
#
# @result: The result of the compare operation.
# @responsible-properties: List of properties that led to the comparison result
# not being identical.
#
# @responsible-properties is a list of QOM property names that led to
# both CPUs not being detected as identical. For identical models, this
# list is empty.
# If a QOM property is read-only, that means there's no known way to make the
# CPU models identical. If the special property name "type" is included, the
# models are by definition not identical and cannot be made identical.
#
# Since: 2.8.0
##
{ 'struct': 'CpuModelCompareInfo',
'data': {'result': 'CpuModelCompareResult',
'responsible-properties': ['str']
}
}
##
# @query-cpu-model-comparison:
#
# Compares two CPU models, returning how they compare in a specific
# configuration. The results indicates how both models compare regarding
# runnability. This result can be used by tooling to make decisions if a
# certain CPU model will run in a certain configuration or if a compatible
# CPU model has to be created by baselining.
#
# Usually, a CPU model is compared against the maximum possible CPU model
# of a ceratin configuration (e.g. the "host" model for KVM). If that CPU
# model is identical or a subset, it will run in that configuration.
#
# The result returned by this command may be affected by:
#
# * QEMU version: CPU models may look different depending on the QEMU version.
# (Except for CPU models reported as "static" in query-cpu-definitions.)
# * machine-type: CPU model may look different depending on the machine-type.
# (Except for CPU models reported as "static" in query-cpu-definitions.)
# * machine options (including accelerator): in some architectures, CPU models
# may look different depending on machine and accelerator options. (Except for
# CPU models reported as "static" in query-cpu-definitions.)
# * "-cpu" arguments and global properties: arguments to the -cpu option and
# global properties may affect expansion of CPU models. Using
# query-cpu-model-expansion while using these is not advised.
#
# Some architectures may not support comparing CPU models. s390x supports
# comparing CPU models.
#
# Returns: a CpuModelBaselineInfo. Returns an error if comparing CPU models is
# not supported, if a model cannot be used, if a model contains
# an unknown cpu definition name, unknown properties or properties
# with wrong types.
#
# Since: 2.8.0
##
{ 'command': 'query-cpu-model-comparison',
'data': { 'modela': 'CpuModelInfo', 'modelb': 'CpuModelInfo' },
'returns': 'CpuModelCompareInfo' }
##
# @CpuModelBaselineInfo
#
# The result of a CPU model baseline.
#
# @model: the baselined CpuModelInfo.
#
# Since: 2.8.0
##
{ 'struct': 'CpuModelBaselineInfo',
'data': { 'model': 'CpuModelInfo' } }
##
# @query-cpu-model-baseline:
#
# Baseline two CPU models, creating a compatible third model. The created
# model will always be a static, migration-safe CPU model (see "static"
# CPU model expansion for details).
#
# This interface can be used by tooling to create a compatible CPU model out
# two CPU models. The created CPU model will be identical to or a subset of
# both CPU models when comparing them. Therefore, the created CPU model is
# guaranteed to run where the given CPU models run.
#
# The result returned by this command may be affected by:
#
# * QEMU version: CPU models may look different depending on the QEMU version.
# (Except for CPU models reported as "static" in query-cpu-definitions.)
# * machine-type: CPU model may look different depending on the machine-type.
# (Except for CPU models reported as "static" in query-cpu-definitions.)
# * machine options (including accelerator): in some architectures, CPU models
# may look different depending on machine and accelerator options. (Except for
# CPU models reported as "static" in query-cpu-definitions.)
# * "-cpu" arguments and global properties: arguments to the -cpu option and
# global properties may affect expansion of CPU models. Using
# query-cpu-model-expansion while using these is not advised.
#
# Some architectures may not support baselining CPU models. s390x supports
# baselining CPU models.
#
# Returns: a CpuModelBaselineInfo. Returns an error if baselining CPU models is
# not supported, if a model cannot be used, if a model contains
# an unknown cpu definition name, unknown properties or properties
# with wrong types.
#
# Since: 2.8.0
##
{ 'command': 'query-cpu-model-baseline',
'data': { 'modela': 'CpuModelInfo',
'modelb': 'CpuModelInfo' },
'returns': 'CpuModelBaselineInfo' }
# @AddfdInfo:
#
# Information about a file descriptor that was added to an fd set.

View file

@ -3941,6 +3941,24 @@ EQMP
.mhandler.cmd_new = qmp_marshal_query_cpu_definitions,
},
{
.name = "query-cpu-model-expansion",
.args_type = "type:s,model:q",
.mhandler.cmd_new = qmp_marshal_query_cpu_model_expansion,
},
{
.name = "query-cpu-model-comparison",
.args_type = "modela:q,modelb:q",
.mhandler.cmd_new = qmp_marshal_query_cpu_model_comparison,
},
{
.name = "query-cpu-model-baseline",
.args_type = "modela:q,modelb:q",
.mhandler.cmd_new = qmp_marshal_query_cpu_model_baseline,
},
{
.name = "query-target",
.args_type = "",

21
qmp.c
View file

@ -607,6 +607,27 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
return arch_query_cpu_definitions(errp);
}
CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
CpuModelInfo *model,
Error **errp)
{
return arch_query_cpu_model_expansion(type, model, errp);
}
CpuModelCompareInfo *qmp_query_cpu_model_comparison(CpuModelInfo *modela,
CpuModelInfo *modelb,
Error **errp)
{
return arch_query_cpu_model_comparison(modela, modelb, errp);
}
CpuModelBaselineInfo *qmp_query_cpu_model_baseline(CpuModelInfo *modela,
CpuModelInfo *modelb,
Error **errp)
{
return arch_query_cpu_model_baseline(modela, modelb, errp);
}
void qmp_add_client(const char *protocol, const char *fdname,
bool has_skipauth, bool skipauth, bool has_tls, bool tls,
Error **errp)

View file

@ -14,6 +14,7 @@ MAKEFLAGS += -rR
%.cpp:
%.m:
%.mak:
clean-target:
# Flags for C++ compilation
QEMU_CXXFLAGS = -D__STDC_LIMIT_MACROS $(filter-out -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Wold-style-declaration -Wold-style-definition -Wredundant-decls, $(QEMU_CFLAGS))

View file

@ -1,4 +1,7 @@
stub-obj-y += arch-query-cpu-def.o
stub-obj-y += arch-query-cpu-model-expansion.o
stub-obj-y += arch-query-cpu-model-comparison.o
stub-obj-y += arch-query-cpu-model-baseline.o
stub-obj-y += bdrv-next-monitor-owned.o
stub-obj-y += blk-commit-all.o
stub-obj-y += blockdev-close-all-bdrv-states.o

View file

@ -0,0 +1,12 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "sysemu/arch_init.h"
#include "qapi/qmp/qerror.h"
CpuModelBaselineInfo *arch_query_cpu_model_baseline(CpuModelInfo *modela,
CpuModelInfo *modelb,
Error **errp)
{
error_setg(errp, QERR_UNSUPPORTED);
return NULL;
}

View file

@ -0,0 +1,12 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "sysemu/arch_init.h"
#include "qapi/qmp/qerror.h"
CpuModelCompareInfo *arch_query_cpu_model_comparison(CpuModelInfo *modela,
CpuModelInfo *modelb,
Error **errp)
{
error_setg(errp, QERR_UNSUPPORTED);
return NULL;
}

View file

@ -0,0 +1,12 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "sysemu/arch_init.h"
#include "qapi/qmp/qerror.h"
CpuModelExpansionInfo *arch_query_cpu_model_expansion(CpuModelExpansionType type,
CpuModelInfo *mode,
Error **errp)
{
error_setg(errp, QERR_UNSUPPORTED);
return NULL;
}

View file

@ -1,5 +1,25 @@
obj-y += translate.o helper.o cpu.o interrupt.o
obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o misc_helper.o
obj-y += gdbstub.o
obj-y += gdbstub.o cpu_models.o cpu_features.o
obj-$(CONFIG_SOFTMMU) += machine.o ioinst.o arch_dump.o mmu_helper.o
obj-$(CONFIG_KVM) += kvm.o
# build and run feature list generator
feat-src = $(SRC_PATH)/target-$(TARGET_BASE_ARCH)/
feat-dst = $(BUILD_DIR)/$(TARGET_DIR)
ifneq ($(MAKECMDGOALS),clean)
GENERATED_HEADERS += $(feat-dst)gen-features.h
endif
$(feat-dst)gen-features.h: $(feat-dst)gen-features.h-timestamp
@cmp $< $@ >/dev/null 2>&1 || cp $< $@
$(feat-dst)gen-features.h-timestamp: $(feat-dst)gen-features
$(call quiet-command,$< >$@," GEN $(TARGET_DIR)gen-features.h")
$(feat-dst)gen-features: $(feat-src)gen-features.c
$(call quiet-command,$(HOST_CC) $(QEMU_INCLUDES) -o $@ $<," CC $(TARGET_DIR)gen-features")
clean-target:
rm -f gen-features.h-timestamp
rm -f gen-features.h
rm -f gen-features

View file

@ -21,6 +21,7 @@
#define QEMU_S390_CPU_QOM_H
#include "qom/cpu.h"
#include "cpu_models.h"
#define TYPE_S390_CPU "s390-cpu"
@ -45,6 +46,11 @@ typedef struct S390CPUClass {
/*< private >*/
CPUClass parent_class;
/*< public >*/
const S390CPUDef *cpu_def;
bool kvm_required;
bool is_static;
bool is_migration_safe;
const char *desc;
int64_t next_cpu_id;

View file

@ -44,30 +44,6 @@
#define CR0_RESET 0xE0UL
#define CR14_RESET 0xC2000000UL;
/* generate CPU information for cpu -? */
void s390_cpu_list(FILE *f, fprintf_function cpu_fprintf)
{
#ifdef CONFIG_KVM
(*cpu_fprintf)(f, "s390 %16s\n", "host");
#endif
}
#ifndef CONFIG_USER_ONLY
CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
{
CpuDefinitionInfoList *entry;
CpuDefinitionInfo *info;
info = g_malloc0(sizeof(*info));
info->name = g_strdup("host");
entry = g_malloc0(sizeof(*entry));
entry->value = info;
return entry;
}
#endif
static void s390_cpu_set_pc(CPUState *cs, vaddr value)
{
S390CPU *cpu = S390_CPU(cs);
@ -206,6 +182,12 @@ static void s390_cpu_realizefn(DeviceState *dev, Error **errp)
CPUS390XState *env = &cpu->env;
Error *err = NULL;
/* the model has to be realized before qemu_init_vcpu() due to kvm */
s390_realize_cpu_model(cs, &err);
if (err) {
goto out;
}
#if !defined(CONFIG_USER_ONLY)
if (cpu->id >= max_cpus) {
error_setg(&err, "Unable to add CPU: %" PRIi64
@ -309,6 +291,7 @@ static void s390_cpu_initfn(Object *obj)
cs->exception_index = EXCP_HLT;
object_property_add(OBJECT(cpu), "id", "int64_t", s390x_cpu_get_id,
s390x_cpu_set_id, NULL, NULL, NULL);
s390_cpu_model_register_props(obj);
#if !defined(CONFIG_USER_ONLY)
qemu_get_timedate(&tm, 0);
env->tod_offset = TOD_UNIX_EPOCH +
@ -435,6 +418,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
scc->cpu_reset = s390_cpu_reset;
scc->initial_cpu_reset = s390_cpu_initial_reset;
cc->reset = s390_cpu_full_reset;
cc->class_by_name = s390_cpu_class_by_name,
cc->has_work = s390_cpu_has_work;
cc->do_interrupt = s390_cpu_do_interrupt;
cc->dump_state = s390_cpu_dump_state;
@ -462,6 +446,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
* object_unref().
*/
dc->cannot_destroy_with_object_finalize_yet = true;
s390_cpu_model_class_register_props(oc);
}
static const TypeInfo s390_cpu_type_info = {
@ -470,7 +455,7 @@ static const TypeInfo s390_cpu_type_info = {
.instance_size = sizeof(S390CPU),
.instance_init = s390_cpu_initfn,
.instance_finalize = s390_cpu_finalize,
.abstract = false,
.abstract = true,
.class_size = sizeof(S390CPUClass),
.class_init = s390_cpu_class_init,
};

View file

@ -188,6 +188,7 @@ struct S390CPU {
CPUS390XState env;
int64_t id;
S390CPUModel *model;
/* needed for live migration */
void *irqstate;
uint32_t irqstate_saved_size;
@ -394,6 +395,8 @@ static inline void cpu_get_tb_cpu_state(CPUS390XState* env, target_ulong *pc,
((env->psw.mask & PSW_MASK_32) ? FLAG_MASK_32 : 0);
}
#define MAX_ILEN 6
/* While the PoO talks about ILC (a number between 1-3) what is actually
stored in LowCore is shifted left one bit (an even between 2-6). As
this is the actual length of the insn and therefore more useful, that
@ -631,6 +634,10 @@ extern void subsystem_reset(void);
void s390_cpu_list(FILE *f, fprintf_function cpu_fprintf);
#define cpu_list s390_cpu_list
void s390_cpu_model_register_props(Object *obj);
void s390_cpu_model_class_register_props(ObjectClass *oc);
void s390_realize_cpu_model(CPUState *cs, Error **errp);
ObjectClass *s390_cpu_class_by_name(const char *name);
#define EXCP_EXT 1 /* external interrupt */
#define EXCP_SVC 2 /* supervisor call (syscall) */

404
target-s390x/cpu_features.c Normal file
View file

@ -0,0 +1,404 @@
/*
* CPU features/facilities for s390x
*
* Copyright 2016 IBM Corp.
*
* Author(s): David Hildenbrand <dahi@linux.vnet.ibm.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or (at
* your option) any later version. See the COPYING file in the top-level
* directory.
*/
#include "qemu/osdep.h"
#include "qemu/module.h"
#include "cpu_features.h"
#include "gen-features.h"
#define FEAT_INIT(_name, _type, _bit, _desc) \
{ \
.name = _name, \
.type = _type, \
.bit = _bit, \
.desc = _desc, \
}
/* indexed by feature number for easy lookup */
static const S390FeatDef s390_features[] = {
FEAT_INIT("esan3", S390_FEAT_TYPE_STFL, 0, "Instructions marked as n3"),
FEAT_INIT("zarch", S390_FEAT_TYPE_STFL, 1, "z/Architecture architectural mode"),
FEAT_INIT("dateh", S390_FEAT_TYPE_STFL, 3, "DAT-enhancement facility"),
FEAT_INIT("idtes", S390_FEAT_TYPE_STFL, 4, "IDTE selective TLB segment-table clearing"),
FEAT_INIT("idter", S390_FEAT_TYPE_STFL, 5, "IDTE selective TLB region-table clearing"),
FEAT_INIT("asnlxr", S390_FEAT_TYPE_STFL, 6, "ASN-and-LX reuse facility"),
FEAT_INIT("stfle", S390_FEAT_TYPE_STFL, 7, "Store-facility-list-extended facility"),
FEAT_INIT("edat", S390_FEAT_TYPE_STFL, 8, "Enhanced-DAT facility"),
FEAT_INIT("srs", S390_FEAT_TYPE_STFL, 9, "Sense-running-status facility"),
FEAT_INIT("csske", S390_FEAT_TYPE_STFL, 10, "Conditional-SSKE facility"),
FEAT_INIT("ctop", S390_FEAT_TYPE_STFL, 11, "Configuration-topology facility"),
FEAT_INIT("ipter", S390_FEAT_TYPE_STFL, 13, "IPTE-range facility"),
FEAT_INIT("nonqks", S390_FEAT_TYPE_STFL, 14, "Nonquiescing key-setting facility"),
FEAT_INIT("etf2", S390_FEAT_TYPE_STFL, 16, "Extended-translation facility 2"),
FEAT_INIT("msa-base", S390_FEAT_TYPE_STFL, 17, "Message-security-assist facility (excluding subfunctions)"),
FEAT_INIT("ldisp", S390_FEAT_TYPE_STFL, 18, "Long-displacement facility"),
FEAT_INIT("ldisphp", S390_FEAT_TYPE_STFL, 19, "Long-displacement facility has high performance"),
FEAT_INIT("hfpm", S390_FEAT_TYPE_STFL, 20, "HFP-multiply-add/subtract facility"),
FEAT_INIT("eimm", S390_FEAT_TYPE_STFL, 21, "Extended-immediate facility"),
FEAT_INIT("etf3", S390_FEAT_TYPE_STFL, 22, "Extended-translation facility 3"),
FEAT_INIT("hfpue", S390_FEAT_TYPE_STFL, 23, "HFP-unnormalized-extension facility"),
FEAT_INIT("etf2eh", S390_FEAT_TYPE_STFL, 24, "ETF2-enhancement facility"),
FEAT_INIT("stckf", S390_FEAT_TYPE_STFL, 25, "Store-clock-fast facility"),
FEAT_INIT("parseh", S390_FEAT_TYPE_STFL, 26, "Parsing-enhancement facility"),
FEAT_INIT("mvcos", S390_FEAT_TYPE_STFL, 27, "Move-with-optional-specification facility"),
FEAT_INIT("tods-base", S390_FEAT_TYPE_STFL, 28, "TOD-clock-steering facility (excluding subfunctions)"),
FEAT_INIT("etf3eh", S390_FEAT_TYPE_STFL, 30, "ETF3-enhancement facility"),
FEAT_INIT("ectg", S390_FEAT_TYPE_STFL, 31, "Extract-CPU-time facility"),
FEAT_INIT("csst", S390_FEAT_TYPE_STFL, 32, "Compare-and-swap-and-store facility"),
FEAT_INIT("csst2", S390_FEAT_TYPE_STFL, 33, "Compare-and-swap-and-store facility 2"),
FEAT_INIT("ginste", S390_FEAT_TYPE_STFL, 34, "General-instructions-extension facility"),
FEAT_INIT("exrl", S390_FEAT_TYPE_STFL, 35, "Execute-extensions facility"),
FEAT_INIT("emon", S390_FEAT_TYPE_STFL, 36, "Enhanced-monitor facility"),
FEAT_INIT("fpe", S390_FEAT_TYPE_STFL, 37, "Floating-point extension facility"),
FEAT_INIT("sprogp", S390_FEAT_TYPE_STFL, 40, "Set-program-parameters facility"),
FEAT_INIT("fpseh", S390_FEAT_TYPE_STFL, 41, "Floating-point-support-enhancement facilities"),
FEAT_INIT("dfp", S390_FEAT_TYPE_STFL, 42, "DFP (decimal-floating-point) facility"),
FEAT_INIT("dfphp", S390_FEAT_TYPE_STFL, 43, "DFP (decimal-floating-point) facility has high performance"),
FEAT_INIT("pfpo", S390_FEAT_TYPE_STFL, 44, "PFPO instruction"),
FEAT_INIT("stfle45", S390_FEAT_TYPE_STFL, 45, "Various facilities introduced with z196"),
FEAT_INIT("cmpsceh", S390_FEAT_TYPE_STFL, 47, "CMPSC-enhancement facility"),
FEAT_INIT("dfpzc", S390_FEAT_TYPE_STFL, 48, "Decimal-floating-point zoned-conversion facility"),
FEAT_INIT("stfle49", S390_FEAT_TYPE_STFL, 49, "Various facilities introduced with zEC12"),
FEAT_INIT("cte", S390_FEAT_TYPE_STFL, 50, "Constrained transactional-execution facility"),
FEAT_INIT("ltlbc", S390_FEAT_TYPE_STFL, 51, "Local-TLB-clearing facility"),
FEAT_INIT("iacc2", S390_FEAT_TYPE_STFL, 52, "Interlocked-access facility 2"),
FEAT_INIT("stfle53", S390_FEAT_TYPE_STFL, 53, "Various facilities introduced with z13"),
FEAT_INIT("msa5-base", S390_FEAT_TYPE_STFL, 57, "Message-security-assist-extension-5 facility (excluding subfunctions)"),
FEAT_INIT("ri", S390_FEAT_TYPE_STFL, 64, "CPU runtime-instrumentation facility"),
FEAT_INIT("te", S390_FEAT_TYPE_STFL, 73, "Transactional-execution facility"),
FEAT_INIT("sthyi", S390_FEAT_TYPE_STFL, 74, "Store-hypervisor-information facility"),
FEAT_INIT("aefsi", S390_FEAT_TYPE_STFL, 75, "Access-exception-fetch/store-indication facility"),
FEAT_INIT("msa3-base", S390_FEAT_TYPE_STFL, 76, "Message-security-assist-extension-3 facility (excluding subfunctions)"),
FEAT_INIT("msa4-base", S390_FEAT_TYPE_STFL, 77, "Message-security-assist-extension-4 facility (excluding subfunctions)"),
FEAT_INIT("edat2", S390_FEAT_TYPE_STFL, 78, "Enhanced-DAT facility 2"),
FEAT_INIT("dfppc", S390_FEAT_TYPE_STFL, 80, "Decimal-floating-point packed-conversion facility"),
FEAT_INIT("vx", S390_FEAT_TYPE_STFL, 129, "Vector facility"),
FEAT_INIT("gsls", S390_FEAT_TYPE_SCLP_CONF_CHAR, 40, "SIE: Guest-storage-limit-suppression facility"),
FEAT_INIT("esop", S390_FEAT_TYPE_SCLP_CONF_CHAR, 46, "Enhanced-suppression-on-protection facility"),
FEAT_INIT("64bscao", S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT, 0, "SIE: 64-bit-SCAO facility"),
FEAT_INIT("cmma", S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT, 1, "SIE: Collaborative-memory-management assist"),
FEAT_INIT("pfmfi", S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT, 9, "SIE: PFMF interpretation facility"),
FEAT_INIT("ibs", S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT, 10, "SIE: Interlock-and-broadcast-suppression facility"),
FEAT_INIT("sief2", S390_FEAT_TYPE_SCLP_CPU, 4, "SIE: interception format 2 (Virtual SIE)"),
FEAT_INIT("skey", S390_FEAT_TYPE_SCLP_CPU, 5, "SIE: Storage-key facility"),
FEAT_INIT("gpereh", S390_FEAT_TYPE_SCLP_CPU, 10, "SIE: Guest-PER enhancement facility"),
FEAT_INIT("siif", S390_FEAT_TYPE_SCLP_CPU, 11, "SIE: Shared IPTE-interlock facility"),
FEAT_INIT("sigpif", S390_FEAT_TYPE_SCLP_CPU, 12, "SIE: SIGP interpretation facility"),
FEAT_INIT("ib", S390_FEAT_TYPE_SCLP_CPU, 42, "SIE: Intervention bypass facility"),
FEAT_INIT("cei", S390_FEAT_TYPE_SCLP_CPU, 43, "SIE: Conditional-external-interception facility"),
FEAT_INIT("dateh2", S390_FEAT_TYPE_MISC, 0, "DAT-enhancement facility 2"),
FEAT_INIT("cmm", S390_FEAT_TYPE_MISC, 0, "Collaborative-memory-management facility"),
FEAT_INIT("plo-cl", S390_FEAT_TYPE_PLO, 0, "PLO Compare and load (32 bit in general registers)"),
FEAT_INIT("plo-clg", S390_FEAT_TYPE_PLO, 1, "PLO Compare and load (64 bit in parameter list)"),
FEAT_INIT("plo-clgr", S390_FEAT_TYPE_PLO, 2, "PLO Compare and load (32 bit in general registers)"),
FEAT_INIT("plo-clx", S390_FEAT_TYPE_PLO, 3, "PLO Compare and load (128 bit in parameter list)"),
FEAT_INIT("plo-cs", S390_FEAT_TYPE_PLO, 4, "PLO Compare and swap (32 bit in general registers)"),
FEAT_INIT("plo-csg", S390_FEAT_TYPE_PLO, 5, "PLO Compare and swap (64 bit in parameter list)"),
FEAT_INIT("plo-csgr", S390_FEAT_TYPE_PLO, 6, "PLO Compare and swap (32 bit in general registers)"),
FEAT_INIT("plo-csx", S390_FEAT_TYPE_PLO, 7, "PLO Compare and swap (128 bit in parameter list)"),
FEAT_INIT("plo-dcs", S390_FEAT_TYPE_PLO, 8, "PLO Double compare and swap (32 bit in general registers)"),
FEAT_INIT("plo-dcsg", S390_FEAT_TYPE_PLO, 9, "PLO Double compare and swap (64 bit in parameter list)"),
FEAT_INIT("plo-dcsgr", S390_FEAT_TYPE_PLO, 10, "PLO Double compare and swap (32 bit in general registers)"),
FEAT_INIT("plo-dcsx", S390_FEAT_TYPE_PLO, 11, "PLO Double compare and swap (128 bit in parameter list)"),
FEAT_INIT("plo-csst", S390_FEAT_TYPE_PLO, 12, "PLO Compare and swap and store (32 bit in general registers)"),
FEAT_INIT("plo-csstg", S390_FEAT_TYPE_PLO, 13, "PLO Compare and swap and store (64 bit in parameter list)"),
FEAT_INIT("plo-csstgr", S390_FEAT_TYPE_PLO, 14, "PLO Compare and swap and store (32 bit in general registers)"),
FEAT_INIT("plo-csstx", S390_FEAT_TYPE_PLO, 15, "PLO Compare and swap and store (128 bit in parameter list)"),
FEAT_INIT("plo-csdst", S390_FEAT_TYPE_PLO, 16, "PLO Compare and swap and double store (32 bit in general registers)"),
FEAT_INIT("plo-csdstg", S390_FEAT_TYPE_PLO, 17, "PLO Compare and swap and double store (64 bit in parameter list)"),
FEAT_INIT("plo-csdstgr", S390_FEAT_TYPE_PLO, 18, "PLO Compare and swap and double store (32 bit in general registers)"),
FEAT_INIT("plo-csdstx", S390_FEAT_TYPE_PLO, 19, "PLO Compare and swap and double store (128 bit in parameter list)"),
FEAT_INIT("plo-cstst", S390_FEAT_TYPE_PLO, 20, "PLO Compare and swap and triple store (32 bit in general registers)"),
FEAT_INIT("plo-cststg", S390_FEAT_TYPE_PLO, 21, "PLO Compare and swap and triple store (64 bit in parameter list)"),
FEAT_INIT("plo-cststgr", S390_FEAT_TYPE_PLO, 22, "PLO Compare and swap and triple store (32 bit in general registers)"),
FEAT_INIT("plo-cststx", S390_FEAT_TYPE_PLO, 23, "PLO Compare and swap and triple store (128 bit in parameter list)"),
FEAT_INIT("ptff-qto", S390_FEAT_TYPE_PTFF, 1, "PTFF Query TOD Offset"),
FEAT_INIT("ptff-qsi", S390_FEAT_TYPE_PTFF, 2, "PTFF Query Steering Information"),
FEAT_INIT("ptff-qpc", S390_FEAT_TYPE_PTFF, 3, "PTFF Query Physical Clock"),
FEAT_INIT("ptff-qui", S390_FEAT_TYPE_PTFF, 4, "PTFF Query UTC Information"),
FEAT_INIT("ptff-qtou", S390_FEAT_TYPE_PTFF, 5, "PTFF Query TOD Offset User"),
FEAT_INIT("ptff-sto", S390_FEAT_TYPE_PTFF, 65, "PTFF Set TOD Offset"),
FEAT_INIT("ptff-stou", S390_FEAT_TYPE_PTFF, 69, "PTFF Set TOD Offset User"),
FEAT_INIT("kmac-dea", S390_FEAT_TYPE_KMAC, 1, "KMAC DEA"),
FEAT_INIT("kmac-tdea-128", S390_FEAT_TYPE_KMAC, 2, "KMAC TDEA-128"),
FEAT_INIT("kmac-tdea-192", S390_FEAT_TYPE_KMAC, 3, "KMAC TDEA-192"),
FEAT_INIT("kmac-edea", S390_FEAT_TYPE_KMAC, 9, "KMAC Encrypted-DEA"),
FEAT_INIT("kmac-etdea-128", S390_FEAT_TYPE_KMAC, 10, "KMAC Encrypted-TDEA-128"),
FEAT_INIT("kmac-etdea-192", S390_FEAT_TYPE_KMAC, 11, "KMAC Encrypted-TDEA-192"),
FEAT_INIT("kmac-aes-128", S390_FEAT_TYPE_KMAC, 18, "KMAC AES-128"),
FEAT_INIT("kmac-aes-192", S390_FEAT_TYPE_KMAC, 19, "KMAC AES-192"),
FEAT_INIT("kmac-aes-256", S390_FEAT_TYPE_KMAC, 20, "KMAC AES-256"),
FEAT_INIT("kmac-eaes-128", S390_FEAT_TYPE_KMAC, 26, "KMAC Encrypted-AES-128"),
FEAT_INIT("kmac-eaes-192", S390_FEAT_TYPE_KMAC, 27, "KMAC Encrypted-AES-192"),
FEAT_INIT("kmac-eaes-256", S390_FEAT_TYPE_KMAC, 28, "KMAC Encrypted-AES-256"),
FEAT_INIT("kmc-dea", S390_FEAT_TYPE_KMC, 1, "KMC DEA"),
FEAT_INIT("kmc-tdea-128", S390_FEAT_TYPE_KMC, 2, "KMC TDEA-128"),
FEAT_INIT("kmc-tdea-192", S390_FEAT_TYPE_KMC, 3, "KMC TDEA-192"),
FEAT_INIT("kmc-edea", S390_FEAT_TYPE_KMC, 9, "KMC Encrypted-DEA"),
FEAT_INIT("kmc-etdea-128", S390_FEAT_TYPE_KMC, 10, "KMC Encrypted-TDEA-128"),
FEAT_INIT("kmc-etdea-192", S390_FEAT_TYPE_KMC, 11, "KMC Encrypted-TDEA-192"),
FEAT_INIT("kmc-aes-128", S390_FEAT_TYPE_KMC, 18, "KMC AES-128"),
FEAT_INIT("kmc-aes-192", S390_FEAT_TYPE_KMC, 19, "KMC AES-192"),
FEAT_INIT("kmc-aes-256", S390_FEAT_TYPE_KMC, 20, "KMC AES-256"),
FEAT_INIT("kmc-eaes-128", S390_FEAT_TYPE_KMC, 26, "KMC Encrypted-AES-128"),
FEAT_INIT("kmc-eaes-192", S390_FEAT_TYPE_KMC, 27, "KMC Encrypted-AES-192"),
FEAT_INIT("kmc-eaes-256", S390_FEAT_TYPE_KMC, 28, "KMC Encrypted-AES-256"),
FEAT_INIT("kmc-prng", S390_FEAT_TYPE_KMC, 67, "KMC PRNG"),
FEAT_INIT("km-dea", S390_FEAT_TYPE_KM, 1, "KM DEA"),
FEAT_INIT("km-tdea-128", S390_FEAT_TYPE_KM, 2, "KM TDEA-128"),
FEAT_INIT("km-tdea-192", S390_FEAT_TYPE_KM, 3, "KM TDEA-192"),
FEAT_INIT("km-edea", S390_FEAT_TYPE_KM, 9, "KM Encrypted-DEA"),
FEAT_INIT("km-etdea-128", S390_FEAT_TYPE_KM, 10, "KM Encrypted-TDEA-128"),
FEAT_INIT("km-etdea-192", S390_FEAT_TYPE_KM, 11, "KM Encrypted-TDEA-192"),
FEAT_INIT("km-aes-128", S390_FEAT_TYPE_KM, 18, "KM AES-128"),
FEAT_INIT("km-aes-192", S390_FEAT_TYPE_KM, 19, "KM AES-192"),
FEAT_INIT("km-aes-256", S390_FEAT_TYPE_KM, 20, "KM AES-256"),
FEAT_INIT("km-eaes-128", S390_FEAT_TYPE_KM, 26, "KM Encrypted-AES-128"),
FEAT_INIT("km-eaes-192", S390_FEAT_TYPE_KM, 27, "KM Encrypted-AES-192"),
FEAT_INIT("km-eaes-256", S390_FEAT_TYPE_KM, 28, "KM Encrypted-AES-256"),
FEAT_INIT("km-xts-aes-128", S390_FEAT_TYPE_KM, 50, "KM XTS-AES-128"),
FEAT_INIT("km-xts-aes-256", S390_FEAT_TYPE_KM, 52, "KM XTS-AES-256"),
FEAT_INIT("km-xts-eaes-128", S390_FEAT_TYPE_KM, 58, "KM XTS-Encrypted-AES-128"),
FEAT_INIT("km-xts-eaes-256", S390_FEAT_TYPE_KM, 60, "KM XTS-Encrypted-AES-256"),
FEAT_INIT("kimd-sha-1", S390_FEAT_TYPE_KIMD, 1, "KIMD SHA-1"),
FEAT_INIT("kimd-sha-256", S390_FEAT_TYPE_KIMD, 2, "KIMD SHA-256"),
FEAT_INIT("kimd-sha-512", S390_FEAT_TYPE_KIMD, 3, "KIMD SHA-512"),
FEAT_INIT("kimd-ghash", S390_FEAT_TYPE_KIMD, 65, "KIMD GHASH"),
FEAT_INIT("klmd-sha-1", S390_FEAT_TYPE_KLMD, 1, "KLMD SHA-1"),
FEAT_INIT("klmd-sha-256", S390_FEAT_TYPE_KLMD, 2, "KLMD SHA-256"),
FEAT_INIT("klmd-sha-512", S390_FEAT_TYPE_KLMD, 3, "KLMD SHA-512"),
FEAT_INIT("pckmo-edea", S390_FEAT_TYPE_PCKMO, 1, "PCKMO Encrypted-DEA-Key"),
FEAT_INIT("pckmo-etdea-128", S390_FEAT_TYPE_PCKMO, 2, "PCKMO Encrypted-TDEA-128-Key"),
FEAT_INIT("pckmo-etdea-192", S390_FEAT_TYPE_PCKMO, 3, "PCKMO Encrypted-TDEA-192-Key"),
FEAT_INIT("pckmo-aes-128", S390_FEAT_TYPE_PCKMO, 18, "PCKMO Encrypted-AES-128-Key"),
FEAT_INIT("pckmo-aes-192", S390_FEAT_TYPE_PCKMO, 19, "PCKMO Encrypted-AES-192-Key"),
FEAT_INIT("pckmo-aes-256", S390_FEAT_TYPE_PCKMO, 20, "PCKMO Encrypted-AES-256-Key"),
FEAT_INIT("kmctr-dea", S390_FEAT_TYPE_KMCTR, 1, "KMCTR DEA"),
FEAT_INIT("kmctr-tdea-128", S390_FEAT_TYPE_KMCTR, 2, "KMCTR TDEA-128"),
FEAT_INIT("kmctr-tdea-192", S390_FEAT_TYPE_KMCTR, 3, "KMCTR TDEA-192"),
FEAT_INIT("kmctr-edea", S390_FEAT_TYPE_KMCTR, 9, "KMCTR Encrypted-DEA"),
FEAT_INIT("kmctr-etdea-128", S390_FEAT_TYPE_KMCTR, 10, "KMCTR Encrypted-TDEA-128"),
FEAT_INIT("kmctr-etdea-192", S390_FEAT_TYPE_KMCTR, 11, "KMCTR Encrypted-TDEA-192"),
FEAT_INIT("kmctr-aes-128", S390_FEAT_TYPE_KMCTR, 18, "KMCTR AES-128"),
FEAT_INIT("kmctr-aes-192", S390_FEAT_TYPE_KMCTR, 19, "KMCTR AES-192"),
FEAT_INIT("kmctr-aes-256", S390_FEAT_TYPE_KMCTR, 20, "KMCTR AES-256"),
FEAT_INIT("kmctr-eaes-128", S390_FEAT_TYPE_KMCTR, 26, "KMCTR Encrypted-AES-128"),
FEAT_INIT("kmctr-eaes-192", S390_FEAT_TYPE_KMCTR, 27, "KMCTR Encrypted-AES-192"),
FEAT_INIT("kmctr-eaes-256", S390_FEAT_TYPE_KMCTR, 28, "KMCTR Encrypted-AES-256"),
FEAT_INIT("kmf-dea", S390_FEAT_TYPE_KMF, 1, "KMF DEA"),
FEAT_INIT("kmf-tdea-128", S390_FEAT_TYPE_KMF, 2, "KMF TDEA-128"),
FEAT_INIT("kmf-tdea-192", S390_FEAT_TYPE_KMF, 3, "KMF TDEA-192"),
FEAT_INIT("kmf-edea", S390_FEAT_TYPE_KMF, 9, "KMF Encrypted-DEA"),
FEAT_INIT("kmf-etdea-128", S390_FEAT_TYPE_KMF, 10, "KMF Encrypted-TDEA-128"),
FEAT_INIT("kmf-etdea-192", S390_FEAT_TYPE_KMF, 11, "KMF Encrypted-TDEA-192"),
FEAT_INIT("kmf-aes-128", S390_FEAT_TYPE_KMF, 18, "KMF AES-128"),
FEAT_INIT("kmf-aes-192", S390_FEAT_TYPE_KMF, 19, "KMF AES-192"),
FEAT_INIT("kmf-aes-256", S390_FEAT_TYPE_KMF, 20, "KMF AES-256"),
FEAT_INIT("kmf-eaes-128", S390_FEAT_TYPE_KMF, 26, "KMF Encrypted-AES-128"),
FEAT_INIT("kmf-eaes-192", S390_FEAT_TYPE_KMF, 27, "KMF Encrypted-AES-192"),
FEAT_INIT("kmf-eaes-256", S390_FEAT_TYPE_KMF, 28, "KMF Encrypted-AES-256"),
FEAT_INIT("kmo-dea", S390_FEAT_TYPE_KMO, 1, "KMO DEA"),
FEAT_INIT("kmo-tdea-128", S390_FEAT_TYPE_KMO, 2, "KMO TDEA-128"),
FEAT_INIT("kmo-tdea-192", S390_FEAT_TYPE_KMO, 3, "KMO TDEA-192"),
FEAT_INIT("kmo-edea", S390_FEAT_TYPE_KMO, 9, "KMO Encrypted-DEA"),
FEAT_INIT("kmo-etdea-128", S390_FEAT_TYPE_KMO, 10, "KMO Encrypted-TDEA-128"),
FEAT_INIT("kmo-etdea-192", S390_FEAT_TYPE_KMO, 11, "KMO Encrypted-TDEA-192"),
FEAT_INIT("kmo-aes-128", S390_FEAT_TYPE_KMO, 18, "KMO AES-128"),
FEAT_INIT("kmo-aes-192", S390_FEAT_TYPE_KMO, 19, "KMO AES-192"),
FEAT_INIT("kmo-aes-256", S390_FEAT_TYPE_KMO, 20, "KMO AES-256"),
FEAT_INIT("kmo-eaes-128", S390_FEAT_TYPE_KMO, 26, "KMO Encrypted-AES-128"),
FEAT_INIT("kmo-eaes-192", S390_FEAT_TYPE_KMO, 27, "KMO Encrypted-AES-192"),
FEAT_INIT("kmo-eaes-256", S390_FEAT_TYPE_KMO, 28, "KMO Encrypted-AES-256"),
FEAT_INIT("pcc-cmac-dea", S390_FEAT_TYPE_PCC, 1, "PCC Compute-Last-Block-CMAC-Using-DEA"),
FEAT_INIT("pcc-cmac-tdea-128", S390_FEAT_TYPE_PCC, 2, "PCC Compute-Last-Block-CMAC-Using-TDEA-128"),
FEAT_INIT("pcc-cmac-tdea-192", S390_FEAT_TYPE_PCC, 3, "PCC Compute-Last-Block-CMAC-Using-TDEA-192"),
FEAT_INIT("pcc-cmac-edea", S390_FEAT_TYPE_PCC, 9, "PCC Compute-Last-Block-CMAC-Using-Encrypted-DEA"),
FEAT_INIT("pcc-cmac-etdea-128", S390_FEAT_TYPE_PCC, 10, "PCC Compute-Last-Block-CMAC-Using-Encrypted-TDEA-128"),
FEAT_INIT("pcc-cmac-etdea-192", S390_FEAT_TYPE_PCC, 11, "PCC Compute-Last-Block-CMAC-Using-EncryptedTDEA-192"),
FEAT_INIT("pcc-cmac-aes-128", S390_FEAT_TYPE_PCC, 18, "PCC Compute-Last-Block-CMAC-Using-AES-128"),
FEAT_INIT("pcc-cmac-aes-192", S390_FEAT_TYPE_PCC, 19, "PCC Compute-Last-Block-CMAC-Using-AES-192"),
FEAT_INIT("pcc-cmac-eaes-256", S390_FEAT_TYPE_PCC, 20, "PCC Compute-Last-Block-CMAC-Using-AES-256"),
FEAT_INIT("pcc-cmac-eaes-128", S390_FEAT_TYPE_PCC, 26, "PCC Compute-Last-Block-CMAC-Using-Encrypted-AES-128"),
FEAT_INIT("pcc-cmac-eaes-192", S390_FEAT_TYPE_PCC, 27, "PCC Compute-Last-Block-CMAC-Using-Encrypted-AES-192"),
FEAT_INIT("pcc-cmac-eaes-256", S390_FEAT_TYPE_PCC, 28, "PCC Compute-Last-Block-CMAC-Using-Encrypted-AES-256"),
FEAT_INIT("pcc-xts-aes-128", S390_FEAT_TYPE_PCC, 50, "PCC Compute-XTS-Parameter-Using-AES-128"),
FEAT_INIT("pcc-xts-aes-256", S390_FEAT_TYPE_PCC, 52, "PCC Compute-XTS-Parameter-Using-AES-256"),
FEAT_INIT("pcc-xts-eaes-128", S390_FEAT_TYPE_PCC, 58, "PCC Compute-XTS-Parameter-Using-Encrypted-AES-128"),
FEAT_INIT("pcc-xts-eaes-256", S390_FEAT_TYPE_PCC, 60, "PCC Compute-XTS-Parameter-Using-Encrypted-AES-256"),
FEAT_INIT("ppno-sha-512-drng", S390_FEAT_TYPE_PPNO, 3, "PPNO SHA-512-DRNG"),
};
const S390FeatDef *s390_feat_def(S390Feat feat)
{
return &s390_features[feat];
}
S390Feat s390_feat_by_type_and_bit(S390FeatType type, int bit)
{
S390Feat feat;
for (feat = 0; feat < ARRAY_SIZE(s390_features); feat++) {
if (s390_features[feat].type == type &&
s390_features[feat].bit == bit) {
return feat;
}
}
return S390_FEAT_MAX;
}
void s390_init_feat_bitmap(const S390FeatInit init, S390FeatBitmap bitmap)
{
int i, j;
for (i = 0; i < (S390_FEAT_MAX / 64 + 1); i++) {
if (init[i]) {
for (j = 0; j < 64; j++) {
if (init[i] & 1ULL << j) {
set_bit(i * 64 + j, bitmap);
}
}
}
}
}
void s390_fill_feat_block(const S390FeatBitmap features, S390FeatType type,
uint8_t *data)
{
S390Feat feat;
int bit_nr;
if (type == S390_FEAT_TYPE_STFL && test_bit(S390_FEAT_ZARCH, features)) {
/* z/Architecture is always active if around */
data[0] |= 0x20;
}
feat = find_first_bit(features, S390_FEAT_MAX);
while (feat < S390_FEAT_MAX) {
if (s390_features[feat].type == type) {
bit_nr = s390_features[feat].bit;
/* big endian on uint8_t array */
data[bit_nr / 8] |= 0x80 >> (bit_nr % 8);
}
feat = find_next_bit(features, S390_FEAT_MAX, feat + 1);
}
}
void s390_add_from_feat_block(S390FeatBitmap features, S390FeatType type,
uint8_t *data)
{
int nr_bits, le_bit;
switch (type) {
case S390_FEAT_TYPE_STFL:
nr_bits = 2048;
break;
case S390_FEAT_TYPE_PLO:
nr_bits = 256;
break;
default:
/* all cpu subfunctions have 128 bit */
nr_bits = 128;
};
le_bit = find_first_bit((unsigned long *) data, nr_bits);
while (le_bit < nr_bits) {
/* convert the bit number to a big endian bit nr */
S390Feat feat = s390_feat_by_type_and_bit(type, BE_BIT_NR(le_bit));
/* ignore unknown bits */
if (feat < S390_FEAT_MAX) {
set_bit(feat, features);
}
le_bit = find_next_bit((unsigned long *) data, nr_bits, le_bit + 1);
}
}
void s390_feat_bitmap_to_ascii(const S390FeatBitmap features, void *opaque,
void (*fn)(const char *name, void *opaque))
{
S390FeatBitmap bitmap, tmp;
S390FeatGroup group;
S390Feat feat;
bitmap_copy(bitmap, features, S390_FEAT_MAX);
/* process whole groups first */
for (group = 0; group < S390_FEAT_GROUP_MAX; group++) {
const S390FeatGroupDef *def = s390_feat_group_def(group);
bitmap_and(tmp, bitmap, def->feat, S390_FEAT_MAX);
if (bitmap_equal(tmp, def->feat, S390_FEAT_MAX)) {
bitmap_andnot(bitmap, bitmap, def->feat, S390_FEAT_MAX);
fn(def->name, opaque);
}
}
/* report leftovers as separate features */
feat = find_first_bit(bitmap, S390_FEAT_MAX);
while (feat < S390_FEAT_MAX) {
fn(s390_feat_def(feat)->name, opaque);
feat = find_next_bit(bitmap, S390_FEAT_MAX, feat + 1);
};
}
#define FEAT_GROUP_INIT(_name, _group, _desc) \
{ \
.name = _name, \
.desc = _desc, \
.init = { S390_FEAT_GROUP_LIST_ ## _group }, \
}
/* indexed by feature group number for easy lookup */
static S390FeatGroupDef s390_feature_groups[] = {
FEAT_GROUP_INIT("plo", PLO, "Perform-locked-operation facility"),
FEAT_GROUP_INIT("tods", TOD_CLOCK_STEERING, "Tod-clock-steering facility"),
FEAT_GROUP_INIT("gen13ptff", GEN13_PTFF, "PTFF enhancements introduced with z13"),
FEAT_GROUP_INIT("msa", MSA, "Message-security-assist facility"),
FEAT_GROUP_INIT("msa1", MSA_EXT_1, "Message-security-assist-extension 1 facility"),
FEAT_GROUP_INIT("msa2", MSA_EXT_2, "Message-security-assist-extension 2 facility"),
FEAT_GROUP_INIT("msa3", MSA_EXT_3, "Message-security-assist-extension 3 facility"),
FEAT_GROUP_INIT("msa4", MSA_EXT_4, "Message-security-assist-extension 4 facility"),
FEAT_GROUP_INIT("msa5", MSA_EXT_5, "Message-security-assist-extension 5 facility"),
};
const S390FeatGroupDef *s390_feat_group_def(S390FeatGroup group)
{
return &s390_feature_groups[group];
}
static void init_groups(void)
{
int i;
/* init all bitmaps from gnerated data initially */
for (i = 0; i < ARRAY_SIZE(s390_feature_groups); i++) {
s390_init_feat_bitmap(s390_feature_groups[i].init,
s390_feature_groups[i].feat);
}
}
type_init(init_groups)

View file

@ -0,0 +1,93 @@
/*
* CPU features/facilities helper structs and utility functions for s390
*
* Copyright 2016 IBM Corp.
*
* Author(s): Michael Mueller <mimu@linux.vnet.ibm.com>
* David Hildenbrand <dahi@linux.vnet.ibm.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or (at
* your option) any later version. See the COPYING file in the top-level
* directory.
*/
#ifndef TARGET_S390X_CPU_FEATURES_H
#define TARGET_S390X_CPU_FEATURES_H
#include "qemu/bitmap.h"
#include "cpu_features_def.h"
/* CPU features are announced via different ways */
typedef enum {
S390_FEAT_TYPE_STFL,
S390_FEAT_TYPE_SCLP_CONF_CHAR,
S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT,
S390_FEAT_TYPE_SCLP_CPU,
S390_FEAT_TYPE_MISC,
S390_FEAT_TYPE_PLO,
S390_FEAT_TYPE_PTFF,
S390_FEAT_TYPE_KMAC,
S390_FEAT_TYPE_KMC,
S390_FEAT_TYPE_KM,
S390_FEAT_TYPE_KIMD,
S390_FEAT_TYPE_KLMD,
S390_FEAT_TYPE_PCKMO,
S390_FEAT_TYPE_KMCTR,
S390_FEAT_TYPE_KMF,
S390_FEAT_TYPE_KMO,
S390_FEAT_TYPE_PCC,
S390_FEAT_TYPE_PPNO,
} S390FeatType;
/* Definition of a CPU feature */
typedef struct {
const char *name; /* name exposed to the user */
const char *desc; /* description exposed to the user */
S390FeatType type; /* feature type (way of indication)*/
int bit; /* bit within the feature type area (fixed) */
} S390FeatDef;
/* use ordinary bitmap operations to work with features */
typedef unsigned long S390FeatBitmap[BITS_TO_LONGS(S390_FEAT_MAX)];
/* 64bit based bitmap used to init S390FeatBitmap from generated data */
typedef uint64_t S390FeatInit[S390_FEAT_MAX / 64 + 1];
const S390FeatDef *s390_feat_def(S390Feat feat);
S390Feat s390_feat_by_type_and_bit(S390FeatType type, int bit);
void s390_init_feat_bitmap(const S390FeatInit init, S390FeatBitmap bitmap);
void s390_fill_feat_block(const S390FeatBitmap features, S390FeatType type,
uint8_t *data);
void s390_add_from_feat_block(S390FeatBitmap features, S390FeatType type,
uint8_t *data);
void s390_feat_bitmap_to_ascii(const S390FeatBitmap features, void *opaque,
void (*fn)(const char *name, void *opaque));
/* static groups that will never change */
typedef enum {
S390_FEAT_GROUP_PLO,
S390_FEAT_GROUP_TOD_CLOCK_STEERING,
S390_FEAT_GROUP_GEN13_PTFF_ENH,
S390_FEAT_GROUP_MSA,
S390_FEAT_GROUP_MSA_EXT_1,
S390_FEAT_GROUP_MSA_EXT_2,
S390_FEAT_GROUP_MSA_EXT_3,
S390_FEAT_GROUP_MSA_EXT_4,
S390_FEAT_GROUP_MSA_EXT_5,
S390_FEAT_GROUP_MAX,
} S390FeatGroup;
/* Definition of a CPU feature group */
typedef struct {
const char *name; /* name exposed to the user */
const char *desc; /* description exposed to the user */
S390FeatBitmap feat; /* features contained in the group */
S390FeatInit init; /* used to init feat from generated data */
} S390FeatGroupDef;
const S390FeatGroupDef *s390_feat_group_def(S390FeatGroup group);
#define BE_BIT_NR(BIT) (BIT ^ (BITS_PER_LONG - 1))
#define BE_BIT(BIT) (1ULL < BE_BIT_NR(BIT))
#endif /* TARGET_S390X_CPU_FEATURES_H */

View file

@ -0,0 +1,231 @@
/*
* CPU features/facilities for s390
*
* Copyright 2016 IBM Corp.
*
* Author(s): Michael Mueller <mimu@linux.vnet.ibm.com>
* David Hildenbrand <dahi@linux.vnet.ibm.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or (at
* your option) any later version. See the COPYING file in the top-level
* directory.
*/
#ifndef TARGET_S390X_CPU_FEATURES_DEF_H
#define TARGET_S390X_CPU_FEATURES_DEF_H
typedef enum {
S390_FEAT_ESAN3 = 0,
S390_FEAT_ZARCH,
S390_FEAT_DAT_ENH,
S390_FEAT_IDTE_SEGMENT,
S390_FEAT_IDTE_REGION,
S390_FEAT_ASN_LX_REUSE,
S390_FEAT_STFLE,
S390_FEAT_EDAT,
S390_FEAT_SENSE_RUNNING_STATUS,
S390_FEAT_CONDITIONAL_SSKE,
S390_FEAT_CONFIGURATION_TOPOLOGY,
S390_FEAT_IPTE_RANGE,
S390_FEAT_NONQ_KEY_SETTING,
S390_FEAT_EXTENDED_TRANSLATION_2,
S390_FEAT_MSA,
S390_FEAT_LONG_DISPLACEMENT,
S390_FEAT_LONG_DISPLACEMENT_FAST,
S390_FEAT_HFP_MADDSUB,
S390_FEAT_EXTENDED_IMMEDIATE,
S390_FEAT_EXTENDED_TRANSLATION_3,
S390_FEAT_HFP_UNNORMALIZED_EXT,
S390_FEAT_ETF2_ENH,
S390_FEAT_STORE_CLOCK_FAST,
S390_FEAT_PARSING_ENH,
S390_FEAT_MOVE_WITH_OPTIONAL_SPEC,
S390_FEAT_TOD_CLOCK_STEERING,
S390_FEAT_ETF3_ENH,
S390_FEAT_EXTRACT_CPU_TIME,
S390_FEAT_COMPARE_AND_SWAP_AND_STORE,
S390_FEAT_COMPARE_AND_SWAP_AND_STORE_2,
S390_FEAT_GENERAL_INSTRUCTIONS_EXT,
S390_FEAT_EXECUTE_EXT,
S390_FEAT_ENHANCED_MONITOR,
S390_FEAT_FLOATING_POINT_EXT,
S390_FEAT_SET_PROGRAM_PARAMETERS,
S390_FEAT_FLOATING_POINT_SUPPPORT_ENH,
S390_FEAT_DFP,
S390_FEAT_DFP_FAST,
S390_FEAT_PFPO,
S390_FEAT_STFLE_45,
S390_FEAT_CMPSC_ENH,
S390_FEAT_DFP_ZONED_CONVERSION,
S390_FEAT_STFLE_49,
S390_FEAT_CONSTRAINT_TRANSACTIONAL_EXE,
S390_FEAT_LOCAL_TLB_CLEARING,
S390_FEAT_INTERLOCKED_ACCESS_2,
S390_FEAT_STFLE_53,
S390_FEAT_MSA_EXT_5,
S390_FEAT_RUNTIME_INSTRUMENTATION,
S390_FEAT_TRANSACTIONAL_EXE,
S390_FEAT_STORE_HYPERVISOR_INFO,
S390_FEAT_ACCESS_EXCEPTION_FS_INDICATION,
S390_FEAT_MSA_EXT_3,
S390_FEAT_MSA_EXT_4,
S390_FEAT_EDAT_2,
S390_FEAT_DFP_PACKED_CONVERSION,
S390_FEAT_VECTOR,
S390_FEAT_SIE_GSLS,
S390_FEAT_ESOP,
S390_FEAT_SIE_64BSCAO,
S390_FEAT_SIE_CMMA,
S390_FEAT_SIE_PFMFI,
S390_FEAT_SIE_IBS,
S390_FEAT_SIE_F2,
S390_FEAT_SIE_SKEY,
S390_FEAT_SIE_GPERE,
S390_FEAT_SIE_SIIF,
S390_FEAT_SIE_SIGPIF,
S390_FEAT_SIE_IB,
S390_FEAT_SIE_CEI,
S390_FEAT_DAT_ENH_2,
S390_FEAT_CMM,
S390_FEAT_PLO_CL,
S390_FEAT_PLO_CLG,
S390_FEAT_PLO_CLGR,
S390_FEAT_PLO_CLX,
S390_FEAT_PLO_CS,
S390_FEAT_PLO_CSG,
S390_FEAT_PLO_CSGR,
S390_FEAT_PLO_CSX,
S390_FEAT_PLO_DCS,
S390_FEAT_PLO_DCSG,
S390_FEAT_PLO_DCSGR,
S390_FEAT_PLO_DCSX,
S390_FEAT_PLO_CSST,
S390_FEAT_PLO_CSSTG,
S390_FEAT_PLO_CSSTGR,
S390_FEAT_PLO_CSSTX,
S390_FEAT_PLO_CSDST,
S390_FEAT_PLO_CSDSTG,
S390_FEAT_PLO_CSDSTGR,
S390_FEAT_PLO_CSDSTX,
S390_FEAT_PLO_CSTST,
S390_FEAT_PLO_CSTSTG,
S390_FEAT_PLO_CSTSTGR,
S390_FEAT_PLO_CSTSTX,
S390_FEAT_PTFF_QTO,
S390_FEAT_PTFF_QSI,
S390_FEAT_PTFF_QPT,
S390_FEAT_PTFF_QUI,
S390_FEAT_PTFF_QTOU,
S390_FEAT_PTFF_STO,
S390_FEAT_PTFF_STOU,
S390_FEAT_KMAC_DEA,
S390_FEAT_KMAC_TDEA_128,
S390_FEAT_KMAC_TDEA_192,
S390_FEAT_KMAC_EDEA,
S390_FEAT_KMAC_ETDEA_128,
S390_FEAT_KMAC_ETDEA_192,
S390_FEAT_KMAC_AES_128,
S390_FEAT_KMAC_AES_192,
S390_FEAT_KMAC_AES_256,
S390_FEAT_KMAC_EAES_128,
S390_FEAT_KMAC_EAES_192,
S390_FEAT_KMAC_EAES_256,
S390_FEAT_KMC_DEA,
S390_FEAT_KMC_TDEA_128,
S390_FEAT_KMC_TDEA_192,
S390_FEAT_KMC_EDEA,
S390_FEAT_KMC_ETDEA_128,
S390_FEAT_KMC_ETDEA_192,
S390_FEAT_KMC_AES_128,
S390_FEAT_KMC_AES_192,
S390_FEAT_KMC_AES_256,
S390_FEAT_KMC_EAES_128,
S390_FEAT_KMC_EAES_192,
S390_FEAT_KMC_EAES_256,
S390_FEAT_KMC_PRNG,
S390_FEAT_KM_DEA,
S390_FEAT_KM_TDEA_128,
S390_FEAT_KM_TDEA_192,
S390_FEAT_KM_EDEA,
S390_FEAT_KM_ETDEA_128,
S390_FEAT_KM_ETDEA_192,
S390_FEAT_KM_AES_128,
S390_FEAT_KM_AES_192,
S390_FEAT_KM_AES_256,
S390_FEAT_KM_EAES_128,
S390_FEAT_KM_EAES_192,
S390_FEAT_KM_EAES_256,
S390_FEAT_KM_XTS_AES_128,
S390_FEAT_KM_XTS_AES_256,
S390_FEAT_KM_XTS_EAES_128,
S390_FEAT_KM_XTS_EAES_256,
S390_FEAT_KIMD_SHA_1,
S390_FEAT_KIMD_SHA_256,
S390_FEAT_KIMD_SHA_512,
S390_FEAT_KIMD_GHASH,
S390_FEAT_KLMD_SHA_1,
S390_FEAT_KLMD_SHA_256,
S390_FEAT_KLMD_SHA_512,
S390_FEAT_PCKMO_EDEA,
S390_FEAT_PCKMO_ETDEA_128,
S390_FEAT_PCKMO_ETDEA_256,
S390_FEAT_PCKMO_AES_128,
S390_FEAT_PCKMO_AES_192,
S390_FEAT_PCKMO_AES_256,
S390_FEAT_KMCTR_DEA,
S390_FEAT_KMCTR_TDEA_128,
S390_FEAT_KMCTR_TDEA_192,
S390_FEAT_KMCTR_EDEA,
S390_FEAT_KMCTR_ETDEA_128,
S390_FEAT_KMCTR_ETDEA_192,
S390_FEAT_KMCTR_AES_128,
S390_FEAT_KMCTR_AES_192,
S390_FEAT_KMCTR_AES_256,
S390_FEAT_KMCTR_EAES_128,
S390_FEAT_KMCTR_EAES_192,
S390_FEAT_KMCTR_EAES_256,
S390_FEAT_KMF_DEA,
S390_FEAT_KMF_TDEA_128,
S390_FEAT_KMF_TDEA_192,
S390_FEAT_KMF_EDEA,
S390_FEAT_KMF_ETDEA_128,
S390_FEAT_KMF_ETDEA_192,
S390_FEAT_KMF_AES_128,
S390_FEAT_KMF_AES_192,
S390_FEAT_KMF_AES_256,
S390_FEAT_KMF_EAES_128,
S390_FEAT_KMF_EAES_192,
S390_FEAT_KMF_EAES_256,
S390_FEAT_KMO_DEA,
S390_FEAT_KMO_TDEA_128,
S390_FEAT_KMO_TDEA_192,
S390_FEAT_KMO_EDEA,
S390_FEAT_KMO_ETDEA_128,
S390_FEAT_KMO_ETDEA_192,
S390_FEAT_KMO_AES_128,
S390_FEAT_KMO_AES_192,
S390_FEAT_KMO_AES_256,
S390_FEAT_KMO_EAES_128,
S390_FEAT_KMO_EAES_192,
S390_FEAT_KMO_EAES_256,
S390_FEAT_PCC_CMAC_DEA,
S390_FEAT_PCC_CMAC_TDEA_128,
S390_FEAT_PCC_CMAC_TDEA_192,
S390_FEAT_PCC_CMAC_ETDEA_128,
S390_FEAT_PCC_CMAC_ETDEA_192,
S390_FEAT_PCC_CMAC_TDEA,
S390_FEAT_PCC_CMAC_AES_128,
S390_FEAT_PCC_CMAC_AES_192,
S390_FEAT_PCC_CMAC_AES_256,
S390_FEAT_PCC_CMAC_EAES_128,
S390_FEAT_PCC_CMAC_EAES_192,
S390_FEAT_PCC_CMAC_EAES_256,
S390_FEAT_PCC_XTS_AES_128,
S390_FEAT_PCC_XTS_AES_256,
S390_FEAT_PCC_XTS_EAES_128,
S390_FEAT_PCC_XTS_EAES_256,
S390_FEAT_PPNO_SHA_512_DRNG,
S390_FEAT_MAX,
} S390Feat;
#endif /* TARGET_S390X_CPU_FEATURES_DEF_H */

1100
target-s390x/cpu_models.c Normal file

File diff suppressed because it is too large Load diff

119
target-s390x/cpu_models.h Normal file
View file

@ -0,0 +1,119 @@
/*
* CPU models for s390x
*
* Copyright 2016 IBM Corp.
*
* Author(s): David Hildenbrand <dahi@linux.vnet.ibm.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or (at
* your option) any later version. See the COPYING file in the top-level
* directory.
*/
#ifndef TARGET_S390X_CPU_MODELS_H
#define TARGET_S390X_CPU_MODELS_H
#include "cpu_features.h"
#include "qom/cpu.h"
/* static CPU definition */
typedef struct S390CPUDef {
const char *name; /* name exposed to the user */
const char *desc; /* description exposed to the user */
uint8_t gen; /* hw generation identification */
uint16_t type; /* cpu type identification */
uint8_t ec_ga; /* EC GA version (on which also the BC is based) */
uint8_t mha_pow; /* Maximum Host Adress Power, mha = 2^pow-1 */
uint32_t hmfai; /* hypervisor-managed facilities */
/* base/min features, must never be changed between QEMU versions */
S390FeatBitmap base_feat;
/* used to init base_feat from generated data */
S390FeatInit base_init;
/* deafault features, QEMU version specific */
S390FeatBitmap default_feat;
/* used to init default_feat from generated data */
S390FeatInit default_init;
/* max allowed features, QEMU version specific */
S390FeatBitmap full_feat;
/* used to init full_feat from generated data */
S390FeatInit full_init;
} S390CPUDef;
/* CPU model based on a CPU definition */
typedef struct S390CPUModel {
const S390CPUDef *def;
S390FeatBitmap features;
/* values copied from the "host" model, can change during migration */
uint16_t lowest_ibc; /* lowest IBC that the hardware supports */
uint32_t cpu_id; /* CPU id */
uint8_t cpu_ver; /* CPU version, usually "ff" for kvm */
} S390CPUModel;
/*
* CPU ID
*
* bits 0-7: Zeroes (ff for kvm)
* bits 8-31: CPU ID (serial number)
* bits 32-48: Machine type
* bits 48-63: Zeroes
*/
#define cpuid_type(x) (((x) >> 16) & 0xffff)
#define cpuid_id(x) (((x) >> 32) & 0xffffff)
#define cpuid_ver(x) (((x) >> 56) & 0xff)
#define lowest_ibc(x) (((uint32_t)(x) >> 16) & 0xfff)
#define unblocked_ibc(x) ((uint32_t)(x) & 0xfff)
#define has_ibc(x) (lowest_ibc(x) != 0)
#define S390_GEN_Z10 0xa
#define ibc_gen(x) (x == 0 ? 0 : ((x >> 4) + S390_GEN_Z10))
#define ibc_ec_ga(x) (x & 0xf)
uint32_t s390_get_hmfai(void);
uint8_t s390_get_mha_pow(void);
uint32_t s390_get_ibc_val(void);
static inline uint16_t s390_ibc_from_cpu_model(const S390CPUModel *model)
{
uint16_t ibc = 0;
if (model->def->gen >= S390_GEN_Z10) {
ibc = ((model->def->gen - S390_GEN_Z10) << 4) + model->def->ec_ga;
}
return ibc;
}
void s390_get_feat_block(S390FeatType type, uint8_t *data);
bool s390_has_feat(S390Feat feat);
uint8_t s390_get_gen_for_cpu_type(uint16_t type);
static inline bool s390_known_cpu_type(uint16_t type)
{
return s390_get_gen_for_cpu_type(type) != 0;
}
static inline uint64_t s390_cpuid_from_cpu_model(const S390CPUModel *model)
{
return ((uint64_t)model->cpu_ver << 56) |
((uint64_t)model->cpu_id << 32) |
((uint64_t)model->def->type << 16);
}
S390CPUDef const *s390_find_cpu_def(uint16_t type, uint8_t gen, uint8_t ec_ga,
S390FeatBitmap features);
#ifdef CONFIG_KVM
bool kvm_s390_cpu_models_supported(void);
void kvm_s390_get_host_cpu_model(S390CPUModel *model, Error **errp);
void kvm_s390_apply_cpu_model(const S390CPUModel *model, Error **errp);
#else
static inline void kvm_s390_get_host_cpu_model(S390CPUModel *model,
Error **errp)
{
}
static inline void kvm_s390_apply_cpu_model(const S390CPUModel *model,
Error **errp)
{
}
static inline bool kvm_s390_cpu_models_supported(void)
{
return false;
}
#endif
#endif /* TARGET_S390X_CPU_MODELS_H */

592
target-s390x/gen-features.c Normal file
View file

@ -0,0 +1,592 @@
/*
* S390 feature list generator
*
* Copyright 2016 IBM Corp.
*
* Author(s): Michael Mueller <mimu@linux.vnet.ibm.com>
* David Hildenbrand <dahi@linux.vnet.ibm.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or (at
* your option) any later version. See the COPYING file in the top-level
* directory.
*
*/
#include "inttypes.h"
#include "stdio.h"
#include "cpu_features_def.h"
#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
/***** BEGIN FEATURE DEFS *****/
#define S390_FEAT_GROUP_PLO \
S390_FEAT_PLO_CL, \
S390_FEAT_PLO_CLG, \
S390_FEAT_PLO_CLGR, \
S390_FEAT_PLO_CLX, \
S390_FEAT_PLO_CS, \
S390_FEAT_PLO_CSG, \
S390_FEAT_PLO_CSGR, \
S390_FEAT_PLO_CSX, \
S390_FEAT_PLO_DCS, \
S390_FEAT_PLO_DCSG, \
S390_FEAT_PLO_DCSGR, \
S390_FEAT_PLO_DCSX, \
S390_FEAT_PLO_CSST, \
S390_FEAT_PLO_CSSTG, \
S390_FEAT_PLO_CSSTGR, \
S390_FEAT_PLO_CSSTX, \
S390_FEAT_PLO_CSDST, \
S390_FEAT_PLO_CSDSTG, \
S390_FEAT_PLO_CSDSTGR, \
S390_FEAT_PLO_CSDSTX, \
S390_FEAT_PLO_CSTST, \
S390_FEAT_PLO_CSTSTG, \
S390_FEAT_PLO_CSTSTGR, \
S390_FEAT_PLO_CSTSTX
#define S390_FEAT_GROUP_TOD_CLOCK_STEERING \
S390_FEAT_TOD_CLOCK_STEERING, \
S390_FEAT_PTFF_QTO, \
S390_FEAT_PTFF_QSI, \
S390_FEAT_PTFF_QPT, \
S390_FEAT_PTFF_STO
#define S390_FEAT_GROUP_GEN13_PTFF \
S390_FEAT_PTFF_QUI, \
S390_FEAT_PTFF_QTOU, \
S390_FEAT_PTFF_STOU
#define S390_FEAT_GROUP_MSA \
S390_FEAT_MSA, \
S390_FEAT_KMAC_DEA, \
S390_FEAT_KMAC_TDEA_128, \
S390_FEAT_KMAC_TDEA_192, \
S390_FEAT_KMC_DEA, \
S390_FEAT_KMC_TDEA_128, \
S390_FEAT_KMC_TDEA_192, \
S390_FEAT_KM_DEA, \
S390_FEAT_KM_TDEA_128, \
S390_FEAT_KM_TDEA_192, \
S390_FEAT_KIMD_SHA_1, \
S390_FEAT_KLMD_SHA_1
#define S390_FEAT_GROUP_MSA_EXT_1 \
S390_FEAT_KMC_AES_128, \
S390_FEAT_KM_AES_128, \
S390_FEAT_KIMD_SHA_256, \
S390_FEAT_KLMD_SHA_256
#define S390_FEAT_GROUP_MSA_EXT_2 \
S390_FEAT_KMC_AES_192, \
S390_FEAT_KMC_AES_256, \
S390_FEAT_KMC_PRNG, \
S390_FEAT_KM_AES_192, \
S390_FEAT_KM_AES_256, \
S390_FEAT_KIMD_SHA_512, \
S390_FEAT_KLMD_SHA_512
#define S390_FEAT_GROUP_MSA_EXT_3 \
S390_FEAT_MSA_EXT_3, \
S390_FEAT_KMAC_EDEA, \
S390_FEAT_KMAC_ETDEA_128, \
S390_FEAT_KMAC_ETDEA_192, \
S390_FEAT_KMC_EAES_128, \
S390_FEAT_KMC_EAES_192, \
S390_FEAT_KMC_EAES_256, \
S390_FEAT_KMC_EDEA, \
S390_FEAT_KMC_ETDEA_128, \
S390_FEAT_KMC_ETDEA_192, \
S390_FEAT_KM_EDEA, \
S390_FEAT_KM_ETDEA_128, \
S390_FEAT_KM_ETDEA_192, \
S390_FEAT_KM_EAES_128, \
S390_FEAT_KM_EAES_192, \
S390_FEAT_KM_EAES_256, \
S390_FEAT_PCKMO_EDEA, \
S390_FEAT_PCKMO_ETDEA_128, \
S390_FEAT_PCKMO_ETDEA_256, \
S390_FEAT_PCKMO_AES_128, \
S390_FEAT_PCKMO_AES_192, \
S390_FEAT_PCKMO_AES_256
#define S390_FEAT_GROUP_MSA_EXT_4 \
S390_FEAT_MSA_EXT_4, \
S390_FEAT_KMAC_AES_128, \
S390_FEAT_KMAC_AES_192, \
S390_FEAT_KMAC_AES_256, \
S390_FEAT_KMAC_EAES_128, \
S390_FEAT_KMAC_EAES_192, \
S390_FEAT_KMAC_EAES_256, \
S390_FEAT_KM_XTS_AES_128, \
S390_FEAT_KM_XTS_AES_256, \
S390_FEAT_KM_XTS_EAES_128, \
S390_FEAT_KM_XTS_EAES_256, \
S390_FEAT_KIMD_GHASH, \
S390_FEAT_KMCTR_DEA, \
S390_FEAT_KMCTR_TDEA_128, \
S390_FEAT_KMCTR_TDEA_192, \
S390_FEAT_KMCTR_EDEA, \
S390_FEAT_KMCTR_ETDEA_128, \
S390_FEAT_KMCTR_ETDEA_192, \
S390_FEAT_KMCTR_AES_128, \
S390_FEAT_KMCTR_AES_192, \
S390_FEAT_KMCTR_AES_256, \
S390_FEAT_KMCTR_EAES_128, \
S390_FEAT_KMCTR_EAES_192, \
S390_FEAT_KMCTR_EAES_256, \
S390_FEAT_KMF_DEA, \
S390_FEAT_KMF_TDEA_128, \
S390_FEAT_KMF_TDEA_192, \
S390_FEAT_KMF_EDEA, \
S390_FEAT_KMF_ETDEA_128, \
S390_FEAT_KMF_ETDEA_192, \
S390_FEAT_KMF_AES_128, \
S390_FEAT_KMF_AES_192, \
S390_FEAT_KMF_AES_256, \
S390_FEAT_KMF_EAES_128, \
S390_FEAT_KMF_EAES_192, \
S390_FEAT_KMF_EAES_256, \
S390_FEAT_KMO_DEA, \
S390_FEAT_KMO_TDEA_128, \
S390_FEAT_KMO_TDEA_192, \
S390_FEAT_KMO_EDEA, \
S390_FEAT_KMO_ETDEA_128, \
S390_FEAT_KMO_ETDEA_192, \
S390_FEAT_KMO_AES_128, \
S390_FEAT_KMO_AES_192, \
S390_FEAT_KMO_AES_256, \
S390_FEAT_KMO_EAES_128, \
S390_FEAT_KMO_EAES_192, \
S390_FEAT_KMO_EAES_256, \
S390_FEAT_PCC_CMAC_DEA, \
S390_FEAT_PCC_CMAC_TDEA_128, \
S390_FEAT_PCC_CMAC_TDEA_192, \
S390_FEAT_PCC_CMAC_ETDEA_128, \
S390_FEAT_PCC_CMAC_ETDEA_192, \
S390_FEAT_PCC_CMAC_TDEA, \
S390_FEAT_PCC_CMAC_AES_128, \
S390_FEAT_PCC_CMAC_AES_192, \
S390_FEAT_PCC_CMAC_AES_256, \
S390_FEAT_PCC_CMAC_EAES_128, \
S390_FEAT_PCC_CMAC_EAES_192, \
S390_FEAT_PCC_CMAC_EAES_256, \
S390_FEAT_PCC_XTS_AES_128, \
S390_FEAT_PCC_XTS_AES_256, \
S390_FEAT_PCC_XTS_EAES_128, \
S390_FEAT_PCC_XTS_EAES_256
#define S390_FEAT_GROUP_MSA_EXT_5 \
S390_FEAT_MSA_EXT_5, \
S390_FEAT_PPNO_SHA_512_DRNG
/* cpu feature groups */
static uint16_t group_PLO[] = {
S390_FEAT_GROUP_PLO,
};
static uint16_t group_TOD_CLOCK_STEERING[] = {
S390_FEAT_GROUP_TOD_CLOCK_STEERING,
};
static uint16_t group_GEN13_PTFF[] = {
S390_FEAT_GROUP_GEN13_PTFF,
};
static uint16_t group_MSA[] = {
S390_FEAT_GROUP_MSA,
};
static uint16_t group_MSA_EXT_1[] = {
S390_FEAT_GROUP_MSA_EXT_1,
};
static uint16_t group_MSA_EXT_2[] = {
S390_FEAT_GROUP_MSA_EXT_2,
};
static uint16_t group_MSA_EXT_3[] = {
S390_FEAT_GROUP_MSA_EXT_3,
};
static uint16_t group_MSA_EXT_4[] = {
S390_FEAT_GROUP_MSA_EXT_4,
};
static uint16_t group_MSA_EXT_5[] = {
S390_FEAT_GROUP_MSA_EXT_5,
};
/* base features in order of release */
static uint16_t base_GEN7_GA1[] = {
S390_FEAT_GROUP_PLO,
S390_FEAT_ESAN3,
S390_FEAT_ZARCH,
};
#define base_GEN7_GA2 EmptyFeat
#define base_GEN7_GA3 EmptyFeat
static uint16_t base_GEN8_GA1[] = {
S390_FEAT_DAT_ENH,
S390_FEAT_EXTENDED_TRANSLATION_2,
S390_FEAT_GROUP_MSA,
S390_FEAT_LONG_DISPLACEMENT,
S390_FEAT_LONG_DISPLACEMENT_FAST,
S390_FEAT_HFP_MADDSUB,
};
#define base_GEN8_GA2 EmptyFeat
#define base_GEN8_GA3 EmptyFeat
#define base_GEN8_GA4 EmptyFeat
#define base_GEN8_GA5 EmptyFeat
static uint16_t base_GEN9_GA1[] = {
S390_FEAT_IDTE_SEGMENT,
S390_FEAT_ASN_LX_REUSE,
S390_FEAT_STFLE,
S390_FEAT_SENSE_RUNNING_STATUS,
S390_FEAT_EXTENDED_IMMEDIATE,
S390_FEAT_EXTENDED_TRANSLATION_3,
S390_FEAT_HFP_UNNORMALIZED_EXT,
S390_FEAT_ETF2_ENH,
S390_FEAT_STORE_CLOCK_FAST,
S390_FEAT_GROUP_TOD_CLOCK_STEERING,
S390_FEAT_ETF3_ENH,
S390_FEAT_DAT_ENH_2,
};
#define base_GEN9_GA2 EmptyFeat
#define base_GEN9_GA3 EmptyFeat
static uint16_t base_GEN10_GA1[] = {
S390_FEAT_CONDITIONAL_SSKE,
S390_FEAT_PARSING_ENH,
S390_FEAT_MOVE_WITH_OPTIONAL_SPEC,
S390_FEAT_EXTRACT_CPU_TIME,
S390_FEAT_COMPARE_AND_SWAP_AND_STORE,
S390_FEAT_COMPARE_AND_SWAP_AND_STORE_2,
S390_FEAT_GENERAL_INSTRUCTIONS_EXT,
S390_FEAT_EXECUTE_EXT,
S390_FEAT_FLOATING_POINT_SUPPPORT_ENH,
S390_FEAT_DFP,
S390_FEAT_DFP_FAST,
S390_FEAT_PFPO,
};
#define base_GEN10_GA2 EmptyFeat
#define base_GEN10_GA3 EmptyFeat
static uint16_t base_GEN11_GA1[] = {
S390_FEAT_NONQ_KEY_SETTING,
S390_FEAT_ENHANCED_MONITOR,
S390_FEAT_FLOATING_POINT_EXT,
S390_FEAT_SET_PROGRAM_PARAMETERS,
S390_FEAT_STFLE_45,
S390_FEAT_CMPSC_ENH,
S390_FEAT_INTERLOCKED_ACCESS_2,
};
#define base_GEN11_GA2 EmptyFeat
static uint16_t base_GEN12_GA1[] = {
S390_FEAT_DFP_ZONED_CONVERSION,
S390_FEAT_STFLE_49,
S390_FEAT_LOCAL_TLB_CLEARING,
};
#define base_GEN12_GA2 EmptyFeat
static uint16_t base_GEN13_GA1[] = {
S390_FEAT_STFLE_53,
S390_FEAT_DFP_PACKED_CONVERSION,
S390_FEAT_GROUP_GEN13_PTFF,
};
#define base_GEN13_GA2 EmptyFeat
/* full features differing to the base in order of release */
static uint16_t full_GEN7_GA1[] = {
S390_FEAT_SIE_F2,
S390_FEAT_SIE_SKEY,
S390_FEAT_SIE_GPERE,
S390_FEAT_SIE_IB,
S390_FEAT_SIE_CEI,
};
static uint16_t full_GEN7_GA2[] = {
S390_FEAT_EXTENDED_TRANSLATION_2,
};
static uint16_t full_GEN7_GA3[] = {
S390_FEAT_LONG_DISPLACEMENT,
S390_FEAT_SIE_SIIF,
};
static uint16_t full_GEN8_GA1[] = {
S390_FEAT_SIE_GSLS,
S390_FEAT_SIE_64BSCAO,
};
#define full_GEN8_GA2 EmptyFeat
static uint16_t full_GEN8_GA3[] = {
S390_FEAT_ASN_LX_REUSE,
S390_FEAT_EXTENDED_TRANSLATION_3,
};
#define full_GEN8_GA4 EmptyFeat
#define full_GEN8_GA5 EmptyFeat
static uint16_t full_GEN9_GA1[] = {
S390_FEAT_STORE_HYPERVISOR_INFO,
S390_FEAT_GROUP_MSA_EXT_1,
S390_FEAT_CMM,
S390_FEAT_SIE_CMMA,
};
static uint16_t full_GEN9_GA2[] = {
S390_FEAT_MOVE_WITH_OPTIONAL_SPEC,
S390_FEAT_EXTRACT_CPU_TIME,
S390_FEAT_COMPARE_AND_SWAP_AND_STORE,
S390_FEAT_FLOATING_POINT_SUPPPORT_ENH,
S390_FEAT_DFP,
};
static uint16_t full_GEN9_GA3[] = {
S390_FEAT_CONDITIONAL_SSKE,
S390_FEAT_PFPO,
};
static uint16_t full_GEN10_GA1[] = {
S390_FEAT_EDAT,
S390_FEAT_CONFIGURATION_TOPOLOGY,
S390_FEAT_GROUP_MSA_EXT_2,
S390_FEAT_ESOP,
S390_FEAT_SIE_PFMFI,
S390_FEAT_SIE_SIGPIF,
};
static uint16_t full_GEN10_GA2[] = {
S390_FEAT_SET_PROGRAM_PARAMETERS,
S390_FEAT_SIE_IBS,
};
static uint16_t full_GEN10_GA3[] = {
S390_FEAT_GROUP_MSA_EXT_3,
};
static uint16_t full_GEN11_GA1[] = {
S390_FEAT_IPTE_RANGE,
S390_FEAT_ACCESS_EXCEPTION_FS_INDICATION,
S390_FEAT_GROUP_MSA_EXT_4,
};
#define full_GEN11_GA2 EmptyFeat
static uint16_t full_GEN12_GA1[] = {
S390_FEAT_CONSTRAINT_TRANSACTIONAL_EXE,
S390_FEAT_TRANSACTIONAL_EXE,
S390_FEAT_RUNTIME_INSTRUMENTATION,
S390_FEAT_EDAT_2,
};
static uint16_t full_GEN12_GA2[] = {
S390_FEAT_GROUP_MSA_EXT_5,
};
static uint16_t full_GEN13_GA1[] = {
S390_FEAT_VECTOR,
};
#define full_GEN13_GA2 EmptyFeat
/* default features differing to the base in order of release */
#define default_GEN7_GA1 EmptyFeat
#define default_GEN7_GA2 EmptyFeat
#define default_GEN7_GA3 EmptyFeat
#define default_GEN8_GA1 EmptyFeat
#define default_GEN8_GA2 EmptyFeat
#define default_GEN8_GA3 EmptyFeat
#define default_GEN8_GA4 EmptyFeat
#define default_GEN8_GA5 EmptyFeat
static uint16_t default_GEN9_GA1[] = {
S390_FEAT_STORE_HYPERVISOR_INFO,
S390_FEAT_GROUP_MSA_EXT_1,
S390_FEAT_CMM,
};
#define default_GEN9_GA2 EmptyFeat
#define default_GEN9_GA3 EmptyFeat
static uint16_t default_GEN10_GA1[] = {
S390_FEAT_EDAT,
S390_FEAT_GROUP_MSA_EXT_2,
};
#define default_GEN10_GA2 EmptyFeat
#define default_GEN10_GA3 EmptyFeat
static uint16_t default_GEN11_GA1[] = {
S390_FEAT_GROUP_MSA_EXT_3,
S390_FEAT_IPTE_RANGE,
S390_FEAT_ACCESS_EXCEPTION_FS_INDICATION,
S390_FEAT_GROUP_MSA_EXT_4,
};
#define default_GEN11_GA2 EmptyFeat
static uint16_t default_GEN12_GA1[] = {
S390_FEAT_CONSTRAINT_TRANSACTIONAL_EXE,
S390_FEAT_TRANSACTIONAL_EXE,
S390_FEAT_RUNTIME_INSTRUMENTATION,
S390_FEAT_EDAT_2,
};
#define default_GEN12_GA2 EmptyFeat
static uint16_t default_GEN13_GA1[] = {
S390_FEAT_GROUP_MSA_EXT_5,
S390_FEAT_VECTOR,
};
#define default_GEN13_GA2 EmptyFeat
/****** END FEATURE DEFS ******/
#define _YEARS "2016"
#define _NAME_H "TARGET_S390X_GEN_FEATURES_H"
#define CPU_FEAT_INITIALIZER(_name) \
{ \
.name = "S390_FEAT_LIST_" #_name, \
.base_bits = \
{ .data = base_##_name, \
.len = ARRAY_SIZE(base_##_name) }, \
.default_bits = \
{ .data = default_##_name, \
.len = ARRAY_SIZE(default_##_name) }, \
.full_bits = \
{ .data = full_##_name, \
.len = ARRAY_SIZE(full_##_name) }, \
}
typedef struct BitSpec {
uint16_t *data;
uint32_t len;
} BitSpec;
typedef struct {
const char *name;
BitSpec base_bits;
BitSpec default_bits;
BitSpec full_bits;
} CpuFeatDefSpec;
static uint16_t EmptyFeat[] = {};
/*******************************
* processor GA series
*******************************/
static CpuFeatDefSpec CpuFeatDef[] = {
CPU_FEAT_INITIALIZER(GEN7_GA1),
CPU_FEAT_INITIALIZER(GEN7_GA2),
CPU_FEAT_INITIALIZER(GEN7_GA3),
CPU_FEAT_INITIALIZER(GEN8_GA1),
CPU_FEAT_INITIALIZER(GEN8_GA2),
CPU_FEAT_INITIALIZER(GEN8_GA3),
CPU_FEAT_INITIALIZER(GEN8_GA4),
CPU_FEAT_INITIALIZER(GEN8_GA5),
CPU_FEAT_INITIALIZER(GEN9_GA1),
CPU_FEAT_INITIALIZER(GEN9_GA2),
CPU_FEAT_INITIALIZER(GEN9_GA3),
CPU_FEAT_INITIALIZER(GEN10_GA1),
CPU_FEAT_INITIALIZER(GEN10_GA2),
CPU_FEAT_INITIALIZER(GEN10_GA3),
CPU_FEAT_INITIALIZER(GEN11_GA1),
CPU_FEAT_INITIALIZER(GEN11_GA2),
CPU_FEAT_INITIALIZER(GEN12_GA1),
CPU_FEAT_INITIALIZER(GEN12_GA2),
CPU_FEAT_INITIALIZER(GEN13_GA1),
CPU_FEAT_INITIALIZER(GEN13_GA2),
};
#define FEAT_GROUP_INITIALIZER(_name) \
{ \
.name = "S390_FEAT_GROUP_LIST_" #_name, \
.bits = \
{ .data = group_##_name, \
.len = ARRAY_SIZE(group_##_name) }, \
}
typedef struct {
const char *name;
BitSpec bits;
} FeatGroupDefSpec;
/*******************************
* feature groups
*******************************/
static FeatGroupDefSpec FeatGroupDef[] = {
FEAT_GROUP_INITIALIZER(PLO),
FEAT_GROUP_INITIALIZER(TOD_CLOCK_STEERING),
FEAT_GROUP_INITIALIZER(GEN13_PTFF),
FEAT_GROUP_INITIALIZER(MSA),
FEAT_GROUP_INITIALIZER(MSA_EXT_1),
FEAT_GROUP_INITIALIZER(MSA_EXT_2),
FEAT_GROUP_INITIALIZER(MSA_EXT_3),
FEAT_GROUP_INITIALIZER(MSA_EXT_4),
FEAT_GROUP_INITIALIZER(MSA_EXT_5),
};
static void set_bits(uint64_t list[], BitSpec bits)
{
uint32_t i;
for (i = 0; i < bits.len; i++) {
list[bits.data[i] / 64] |= 1ULL << (bits.data[i] % 64);
}
}
static void print_feature_defs(void)
{
uint64_t base_feat[S390_FEAT_MAX / 64 + 1] = {};
uint64_t default_feat[S390_FEAT_MAX / 64 + 1] = {};
uint64_t full_feat[S390_FEAT_MAX / 64 + 1] = {};
int i, j;
printf("\n/* CPU model feature list data */\n");
for (i = 0; i < ARRAY_SIZE(CpuFeatDef); i++) {
set_bits(base_feat, CpuFeatDef[i].base_bits);
/* add the base to the default features */
set_bits(default_feat, CpuFeatDef[i].base_bits);
set_bits(default_feat, CpuFeatDef[i].default_bits);
/* add the base to the full features */
set_bits(full_feat, CpuFeatDef[i].base_bits);
set_bits(full_feat, CpuFeatDef[i].full_bits);
printf("#define %s_BASE\t", CpuFeatDef[i].name);
for (j = 0; j < ARRAY_SIZE(base_feat); j++) {
printf("0x%016"PRIx64"ULL", base_feat[j]);
if (j < ARRAY_SIZE(base_feat) - 1) {
printf(",");
} else {
printf("\n");
}
}
printf("#define %s_DEFAULT\t", CpuFeatDef[i].name);
for (j = 0; j < ARRAY_SIZE(default_feat); j++) {
printf("0x%016"PRIx64"ULL", default_feat[j]);
if (j < ARRAY_SIZE(default_feat) - 1) {
printf(",");
} else {
printf("\n");
}
}
printf("#define %s_FULL\t\t", CpuFeatDef[i].name);
for (j = 0; j < ARRAY_SIZE(full_feat); j++) {
printf("0x%016"PRIx64"ULL", full_feat[j]);
if (j < ARRAY_SIZE(full_feat) - 1) {
printf(",");
} else {
printf("\n");
}
}
}
}
static void print_feature_group_defs(void)
{
int i, j;
printf("\n/* CPU feature group list data */\n");
for (i = 0; i < ARRAY_SIZE(FeatGroupDef); i++) {
uint64_t feat[S390_FEAT_MAX / 64 + 1] = {};
set_bits(feat, FeatGroupDef[i].bits);
printf("#define %s\t", FeatGroupDef[i].name);
for (j = 0; j < ARRAY_SIZE(feat); j++) {
printf("0x%016"PRIx64"ULL", feat[j]);
if (j < ARRAY_SIZE(feat) - 1) {
printf(",");
} else {
printf("\n");
}
}
}
}
int main(int argc, char *argv[])
{
printf("/*\n"
" * AUTOMATICALLY GENERATED, DO NOT MODIFY HERE, EDIT\n"
" * SOURCE FILE \"%s\" INSTEAD.\n"
" *\n"
" * Copyright %s IBM Corp.\n"
" *\n"
" * This work is licensed under the terms of the GNU GPL, "
"version 2 or (at\n * your option) any later version. See "
"the COPYING file in the top-level\n * directory.\n"
" */\n\n"
"#ifndef %s\n#define %s\n", __FILE__, _YEARS, _NAME_H, _NAME_H);
print_feature_defs();
print_feature_group_defs();
printf("\n#endif\n");
return 0;
}

View file

@ -70,7 +70,38 @@ void s390x_cpu_timer(void *opaque)
S390CPU *cpu_s390x_create(const char *cpu_model, Error **errp)
{
return S390_CPU(object_new(TYPE_S390_CPU));
static bool features_parsed;
char *name, *features;
const char *typename;
ObjectClass *oc;
CPUClass *cc;
name = g_strdup(cpu_model);
features = strchr(name, ',');
if (features) {
features[0] = 0;
features++;
}
oc = cpu_class_by_name(TYPE_S390_CPU, name);
if (!oc) {
error_setg(errp, "Unknown CPU definition \'%s\'", name);
g_free(name);
return NULL;
}
typename = object_class_get_name(oc);
if (!features_parsed) {
features_parsed = true;
cc = CPU_CLASS(oc);
cc->parse_features(typename, features, errp);
}
g_free(name);
if (*errp) {
return NULL;
}
return S390_CPU(CPU(object_new(typename)));
}
S390CPU *s390x_new_cpu(const char *cpu_model, int64_t id, Error **errp)

View file

@ -508,7 +508,7 @@ static void ioinst_handle_chsc_scsc(ChscReq *req, ChscResp *res)
memset(chsc_chars, 0, sizeof(chsc_chars));
general_chars[0] = cpu_to_be32(0x03000000);
general_chars[1] = cpu_to_be32(0x00059000);
general_chars[1] = cpu_to_be32(0x00079000);
general_chars[3] = cpu_to_be32(0x00080000);
chsc_chars[0] = cpu_to_be32(0x40000000);

View file

@ -109,6 +109,7 @@
#define ICPT_WAITPSW 0x1c
#define ICPT_SOFT_INTERCEPT 0x24
#define ICPT_CPU_STOP 0x28
#define ICPT_OPEREXC 0x2c
#define ICPT_IO 0x40
#define NR_LOCAL_IRQS 32
@ -174,6 +175,18 @@ int kvm_s390_set_mem_limit(KVMState *s, uint64_t new_limit, uint64_t *hw_limit)
return kvm_vm_ioctl(s, KVM_SET_DEVICE_ATTR, &attr);
}
static bool kvm_s390_cmma_available(void)
{
static bool initialized, value;
if (!initialized) {
initialized = true;
value = kvm_vm_check_mem_attr(kvm_state, KVM_S390_VM_MEM_ENABLE_CMMA) &&
kvm_vm_check_mem_attr(kvm_state, KVM_S390_VM_MEM_CLR_CMMA);
}
return value;
}
void kvm_s390_cmma_reset(void)
{
int rc;
@ -182,11 +195,15 @@ void kvm_s390_cmma_reset(void)
.attr = KVM_S390_VM_MEM_CLR_CMMA,
};
if (!mem_path || !kvm_s390_cmma_available()) {
return;
}
rc = kvm_vm_ioctl(kvm_state, KVM_SET_DEVICE_ATTR, &attr);
trace_kvm_clear_cmma(rc);
}
static void kvm_s390_enable_cmma(KVMState *s)
static void kvm_s390_enable_cmma(void)
{
int rc;
struct kvm_device_attr attr = {
@ -194,12 +211,7 @@ static void kvm_s390_enable_cmma(KVMState *s)
.attr = KVM_S390_VM_MEM_ENABLE_CMMA,
};
if (!kvm_vm_check_mem_attr(s, KVM_S390_VM_MEM_ENABLE_CMMA) ||
!kvm_vm_check_mem_attr(s, KVM_S390_VM_MEM_CLR_CMMA)) {
return;
}
rc = kvm_vm_ioctl(s, KVM_SET_DEVICE_ATTR, &attr);
rc = kvm_vm_ioctl(kvm_state, KVM_SET_DEVICE_ATTR, &attr);
trace_kvm_enable_cmma(rc);
}
@ -248,8 +260,10 @@ static void kvm_s390_init_dea_kw(void)
void kvm_s390_crypto_reset(void)
{
kvm_s390_init_aes_kw();
kvm_s390_init_dea_kw();
if (s390_has_feat(S390_FEAT_MSA_EXT_3)) {
kvm_s390_init_aes_kw();
kvm_s390_init_dea_kw();
}
}
int kvm_arch_init(MachineState *ms, KVMState *s)
@ -259,10 +273,6 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
cap_mem_op = kvm_check_extension(s, KVM_CAP_S390_MEM_OP);
cap_s390_irq = kvm_check_extension(s, KVM_CAP_S390_INJECT_IRQ);
if (!mem_path) {
kvm_s390_enable_cmma(s);
}
if (!kvm_check_extension(s, KVM_CAP_S390_GMAP)
|| !kvm_check_extension(s, KVM_CAP_S390_COW)) {
phys_mem_set_alloc(legacy_s390_alloc);
@ -665,16 +675,37 @@ static void *legacy_s390_alloc(size_t size, uint64_t *align)
return mem == MAP_FAILED ? NULL : mem;
}
/* DIAG 501 is used for sw breakpoints */
static const uint8_t diag_501[] = {0x83, 0x24, 0x05, 0x01};
static uint8_t const *sw_bp_inst;
static uint8_t sw_bp_ilen;
static void determine_sw_breakpoint_instr(void)
{
/* DIAG 501 is used for sw breakpoints with old kernels */
static const uint8_t diag_501[] = {0x83, 0x24, 0x05, 0x01};
/* Instruction 0x0000 is used for sw breakpoints with recent kernels */
static const uint8_t instr_0x0000[] = {0x00, 0x00};
if (sw_bp_inst) {
return;
}
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");
} else {
sw_bp_inst = instr_0x0000;
sw_bp_ilen = sizeof(instr_0x0000);
DPRINTF("KVM: will use 2-byte sw breakpoints.\n");
}
}
int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
{
determine_sw_breakpoint_instr();
if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn,
sizeof(diag_501), 0) ||
cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)diag_501,
sizeof(diag_501), 1)) {
sw_bp_ilen, 0) ||
cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)sw_bp_inst, sw_bp_ilen, 1)) {
return -EINVAL;
}
return 0;
@ -682,14 +713,14 @@ int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
{
uint8_t t[sizeof(diag_501)];
uint8_t t[MAX_ILEN];
if (cpu_memory_rw_debug(cs, bp->pc, t, sizeof(diag_501), 0)) {
if (cpu_memory_rw_debug(cs, bp->pc, t, sw_bp_ilen, 0)) {
return -EINVAL;
} else if (memcmp(t, diag_501, sizeof(diag_501))) {
} else if (memcmp(t, sw_bp_inst, sw_bp_ilen)) {
return -EINVAL;
} else if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn,
sizeof(diag_501), 1)) {
sw_bp_ilen, 1)) {
return -EINVAL;
}
@ -1310,7 +1341,7 @@ static int handle_sw_breakpoint(S390CPU *cpu, struct kvm_run *run)
cpu_synchronize_state(CPU(cpu));
pc = env->psw.addr - 4;
pc = env->psw.addr - sw_bp_ilen;
if (kvm_find_sw_breakpoint(CPU(cpu), pc)) {
env->psw.addr = pc;
return EXCP_DEBUG;
@ -1517,7 +1548,7 @@ static void sigp_store_adtl_status(void *arg)
{
SigpInfo *si = arg;
if (!kvm_check_extension(kvm_state, KVM_CAP_S390_VECTOR_REGISTERS)) {
if (!s390_has_feat(S390_FEAT_VECTOR)) {
set_sigp_status(si, SIGP_STAT_INVALID_ORDER);
return;
}
@ -1864,6 +1895,14 @@ static int handle_intercept(S390CPU *cpu)
cpu->env.sigp_order = 0;
r = EXCP_HALTED;
break;
case ICPT_OPEREXC:
/* currently only instr 0x0000 after enabled via capability */
r = handle_sw_breakpoint(cpu, run);
if (r == -ENOENT) {
enter_pgmcheck(cpu, PGM_OPERATION);
r = 0;
}
break;
case ICPT_SOFT_INTERCEPT:
fprintf(stderr, "KVM unimplemented icpt SOFT\n");
exit(1);
@ -2089,7 +2128,7 @@ static uint64_t build_channel_report_mcic(void)
MCIC_VB_WP | MCIC_VB_MS | MCIC_VB_PM | MCIC_VB_IA | MCIC_VB_FP |
MCIC_VB_GR | MCIC_VB_CR | MCIC_VB_ST | MCIC_VB_AR | MCIC_VB_PR |
MCIC_VB_FC | MCIC_VB_CT | MCIC_VB_CC;
if (kvm_check_extension(kvm_state, KVM_CAP_S390_VECTOR_REGISTERS)) {
if (s390_has_feat(S390_FEAT_VECTOR)) {
mcic |= MCIC_VB_VR;
}
return mcic;
@ -2282,3 +2321,320 @@ int kvm_arch_msi_data_to_gsi(uint32_t data)
{
abort();
}
static inline int test_bit_inv(long nr, const unsigned long *addr)
{
return test_bit(BE_BIT_NR(nr), addr);
}
static inline void set_bit_inv(long nr, unsigned long *addr)
{
set_bit(BE_BIT_NR(nr), addr);
}
static int query_cpu_subfunc(S390FeatBitmap features)
{
struct kvm_s390_vm_cpu_subfunc prop;
struct kvm_device_attr attr = {
.group = KVM_S390_VM_CPU_MODEL,
.attr = KVM_S390_VM_CPU_MACHINE_SUBFUNC,
.addr = (uint64_t) &prop,
};
int rc;
rc = kvm_vm_ioctl(kvm_state, KVM_GET_DEVICE_ATTR, &attr);
if (rc) {
return rc;
}
/*
* We're going to add all subfunctions now, if the corresponding feature
* is available that unlocks the query functions.
*/
s390_add_from_feat_block(features, S390_FEAT_TYPE_PLO, prop.plo);
if (test_bit(S390_FEAT_TOD_CLOCK_STEERING, features)) {
s390_add_from_feat_block(features, S390_FEAT_TYPE_PTFF, prop.ptff);
}
if (test_bit(S390_FEAT_MSA, features)) {
s390_add_from_feat_block(features, S390_FEAT_TYPE_KMAC, prop.kmac);
s390_add_from_feat_block(features, S390_FEAT_TYPE_KMC, prop.kmc);
s390_add_from_feat_block(features, S390_FEAT_TYPE_KM, prop.km);
s390_add_from_feat_block(features, S390_FEAT_TYPE_KIMD, prop.kimd);
s390_add_from_feat_block(features, S390_FEAT_TYPE_KLMD, prop.klmd);
}
if (test_bit(S390_FEAT_MSA_EXT_3, features)) {
s390_add_from_feat_block(features, S390_FEAT_TYPE_PCKMO, prop.pckmo);
}
if (test_bit(S390_FEAT_MSA_EXT_4, features)) {
s390_add_from_feat_block(features, S390_FEAT_TYPE_KMCTR, prop.kmctr);
s390_add_from_feat_block(features, S390_FEAT_TYPE_KMF, prop.kmf);
s390_add_from_feat_block(features, S390_FEAT_TYPE_KMO, prop.kmo);
s390_add_from_feat_block(features, S390_FEAT_TYPE_PCC, prop.pcc);
}
if (test_bit(S390_FEAT_MSA_EXT_5, features)) {
s390_add_from_feat_block(features, S390_FEAT_TYPE_PPNO, prop.ppno);
}
return 0;
}
static int configure_cpu_subfunc(const S390FeatBitmap features)
{
struct kvm_s390_vm_cpu_subfunc prop = {};
struct kvm_device_attr attr = {
.group = KVM_S390_VM_CPU_MODEL,
.attr = KVM_S390_VM_CPU_PROCESSOR_SUBFUNC,
.addr = (uint64_t) &prop,
};
if (!kvm_vm_check_attr(kvm_state, KVM_S390_VM_CPU_MODEL,
KVM_S390_VM_CPU_PROCESSOR_SUBFUNC)) {
/* hardware support might be missing, IBC will handle most of this */
return 0;
}
s390_fill_feat_block(features, S390_FEAT_TYPE_PLO, prop.plo);
if (test_bit(S390_FEAT_TOD_CLOCK_STEERING, features)) {
s390_fill_feat_block(features, S390_FEAT_TYPE_PTFF, prop.ptff);
prop.ptff[0] |= 0x80; /* query is always available */
}
if (test_bit(S390_FEAT_MSA, features)) {
s390_fill_feat_block(features, S390_FEAT_TYPE_KMAC, prop.kmac);
prop.kmac[0] |= 0x80; /* query is always available */
s390_fill_feat_block(features, S390_FEAT_TYPE_KMC, prop.kmc);
prop.kmc[0] |= 0x80; /* query is always available */
s390_fill_feat_block(features, S390_FEAT_TYPE_KM, prop.km);
prop.km[0] |= 0x80; /* query is always available */
s390_fill_feat_block(features, S390_FEAT_TYPE_KIMD, prop.kimd);
prop.kimd[0] |= 0x80; /* query is always available */
s390_fill_feat_block(features, S390_FEAT_TYPE_KLMD, prop.klmd);
prop.klmd[0] |= 0x80; /* query is always available */
}
if (test_bit(S390_FEAT_MSA_EXT_3, features)) {
s390_fill_feat_block(features, S390_FEAT_TYPE_PCKMO, prop.pckmo);
prop.pckmo[0] |= 0x80; /* query is always available */
}
if (test_bit(S390_FEAT_MSA_EXT_4, features)) {
s390_fill_feat_block(features, S390_FEAT_TYPE_KMCTR, prop.kmctr);
prop.kmctr[0] |= 0x80; /* query is always available */
s390_fill_feat_block(features, S390_FEAT_TYPE_KMF, prop.kmf);
prop.kmf[0] |= 0x80; /* query is always available */
s390_fill_feat_block(features, S390_FEAT_TYPE_KMO, prop.kmo);
prop.kmo[0] |= 0x80; /* query is always available */
s390_fill_feat_block(features, S390_FEAT_TYPE_PCC, prop.pcc);
prop.pcc[0] |= 0x80; /* query is always available */
}
if (test_bit(S390_FEAT_MSA_EXT_5, features)) {
s390_fill_feat_block(features, S390_FEAT_TYPE_PPNO, prop.ppno);
prop.ppno[0] |= 0x80; /* query is always available */
}
return kvm_vm_ioctl(kvm_state, KVM_SET_DEVICE_ATTR, &attr);
}
static int kvm_to_feat[][2] = {
{ KVM_S390_VM_CPU_FEAT_ESOP, S390_FEAT_ESOP },
{ KVM_S390_VM_CPU_FEAT_SIEF2, S390_FEAT_SIE_F2 },
{ KVM_S390_VM_CPU_FEAT_64BSCAO , S390_FEAT_SIE_64BSCAO },
{ KVM_S390_VM_CPU_FEAT_SIIF, S390_FEAT_SIE_SIIF },
{ KVM_S390_VM_CPU_FEAT_GPERE, S390_FEAT_SIE_GPERE },
{ KVM_S390_VM_CPU_FEAT_GSLS, S390_FEAT_SIE_GSLS },
{ KVM_S390_VM_CPU_FEAT_IB, S390_FEAT_SIE_IB },
{ KVM_S390_VM_CPU_FEAT_CEI, S390_FEAT_SIE_CEI },
{ KVM_S390_VM_CPU_FEAT_IBS, S390_FEAT_SIE_IBS },
{ KVM_S390_VM_CPU_FEAT_SKEY, S390_FEAT_SIE_SKEY },
{ KVM_S390_VM_CPU_FEAT_CMMA, S390_FEAT_SIE_CMMA },
{ KVM_S390_VM_CPU_FEAT_PFMFI, S390_FEAT_SIE_PFMFI},
{ KVM_S390_VM_CPU_FEAT_SIGPIF, S390_FEAT_SIE_SIGPIF},
};
static int query_cpu_feat(S390FeatBitmap features)
{
struct kvm_s390_vm_cpu_feat prop;
struct kvm_device_attr attr = {
.group = KVM_S390_VM_CPU_MODEL,
.attr = KVM_S390_VM_CPU_MACHINE_FEAT,
.addr = (uint64_t) &prop,
};
int rc;
int i;
rc = kvm_vm_ioctl(kvm_state, KVM_GET_DEVICE_ATTR, &attr);
if (rc) {
return rc;
}
for (i = 0; i < ARRAY_SIZE(kvm_to_feat); i++) {
if (test_bit_inv(kvm_to_feat[i][0], (unsigned long *)prop.feat)) {
set_bit(kvm_to_feat[i][1], features);
}
}
return 0;
}
static int configure_cpu_feat(const S390FeatBitmap features)
{
struct kvm_s390_vm_cpu_feat prop = {};
struct kvm_device_attr attr = {
.group = KVM_S390_VM_CPU_MODEL,
.attr = KVM_S390_VM_CPU_PROCESSOR_FEAT,
.addr = (uint64_t) &prop,
};
int i;
for (i = 0; i < ARRAY_SIZE(kvm_to_feat); i++) {
if (test_bit(kvm_to_feat[i][1], features)) {
set_bit_inv(kvm_to_feat[i][0], (unsigned long *)prop.feat);
}
}
return kvm_vm_ioctl(kvm_state, KVM_SET_DEVICE_ATTR, &attr);
}
bool kvm_s390_cpu_models_supported(void)
{
if (!ri_allowed()) {
/* compatibility machines interfere with the cpu model */
return false;
}
return kvm_vm_check_attr(kvm_state, KVM_S390_VM_CPU_MODEL,
KVM_S390_VM_CPU_MACHINE) &&
kvm_vm_check_attr(kvm_state, KVM_S390_VM_CPU_MODEL,
KVM_S390_VM_CPU_PROCESSOR) &&
kvm_vm_check_attr(kvm_state, KVM_S390_VM_CPU_MODEL,
KVM_S390_VM_CPU_MACHINE_FEAT) &&
kvm_vm_check_attr(kvm_state, KVM_S390_VM_CPU_MODEL,
KVM_S390_VM_CPU_PROCESSOR_FEAT) &&
kvm_vm_check_attr(kvm_state, KVM_S390_VM_CPU_MODEL,
KVM_S390_VM_CPU_MACHINE_SUBFUNC);
}
void kvm_s390_get_host_cpu_model(S390CPUModel *model, Error **errp)
{
struct kvm_s390_vm_cpu_machine prop = {};
struct kvm_device_attr attr = {
.group = KVM_S390_VM_CPU_MODEL,
.attr = KVM_S390_VM_CPU_MACHINE,
.addr = (uint64_t) &prop,
};
uint16_t unblocked_ibc = 0, cpu_type = 0;
int rc;
memset(model, 0, sizeof(*model));
if (!kvm_s390_cpu_models_supported()) {
error_setg(errp, "KVM doesn't support CPU models");
return;
}
/* query the basic cpu model properties */
rc = kvm_vm_ioctl(kvm_state, KVM_GET_DEVICE_ATTR, &attr);
if (rc) {
error_setg(errp, "KVM: Error querying host CPU model: %d", rc);
return;
}
cpu_type = cpuid_type(prop.cpuid);
if (has_ibc(prop.ibc)) {
model->lowest_ibc = lowest_ibc(prop.ibc);
unblocked_ibc = unblocked_ibc(prop.ibc);
}
model->cpu_id = cpuid_id(prop.cpuid);
model->cpu_ver = 0xff;
/* get supported cpu features indicated via STFL(E) */
s390_add_from_feat_block(model->features, S390_FEAT_TYPE_STFL,
(uint8_t *) prop.fac_mask);
/* dat-enhancement facility 2 has no bit but was introduced with stfle */
if (test_bit(S390_FEAT_STFLE, model->features)) {
set_bit(S390_FEAT_DAT_ENH_2, model->features);
}
/* get supported cpu features indicated e.g. via SCLP */
rc = query_cpu_feat(model->features);
if (rc) {
error_setg(errp, "KVM: Error querying CPU features: %d", rc);
return;
}
/* get supported cpu subfunctions indicated via query / test bit */
rc = query_cpu_subfunc(model->features);
if (rc) {
error_setg(errp, "KVM: Error querying CPU subfunctions: %d", rc);
return;
}
/* with cpu model support, CMM is only indicated if really available */
if (kvm_s390_cmma_available()) {
set_bit(S390_FEAT_CMM, model->features);
}
if (s390_known_cpu_type(cpu_type)) {
/* we want the exact model, even if some features are missing */
model->def = s390_find_cpu_def(cpu_type, ibc_gen(unblocked_ibc),
ibc_ec_ga(unblocked_ibc), NULL);
} else {
/* model unknown, e.g. too new - search using features */
model->def = s390_find_cpu_def(0, ibc_gen(unblocked_ibc),
ibc_ec_ga(unblocked_ibc),
model->features);
}
if (!model->def) {
error_setg(errp, "KVM: host CPU model could not be identified");
return;
}
/* strip of features that are not part of the maximum model */
bitmap_and(model->features, model->features, model->def->full_feat,
S390_FEAT_MAX);
}
void kvm_s390_apply_cpu_model(const S390CPUModel *model, Error **errp)
{
struct kvm_s390_vm_cpu_processor prop = {
.fac_list = { 0 },
};
struct kvm_device_attr attr = {
.group = KVM_S390_VM_CPU_MODEL,
.attr = KVM_S390_VM_CPU_PROCESSOR,
.addr = (uint64_t) &prop,
};
int rc;
if (!model) {
/* compatibility handling if cpu models are disabled */
if (kvm_s390_cmma_available() && !mem_path) {
kvm_s390_enable_cmma();
}
return;
}
if (!kvm_s390_cpu_models_supported()) {
error_setg(errp, "KVM doesn't support CPU models");
return;
}
prop.cpuid = s390_cpuid_from_cpu_model(model);
prop.ibc = s390_ibc_from_cpu_model(model);
/* configure cpu features indicated via STFL(e) */
s390_fill_feat_block(model->features, S390_FEAT_TYPE_STFL,
(uint8_t *) prop.fac_list);
rc = kvm_vm_ioctl(kvm_state, KVM_SET_DEVICE_ATTR, &attr);
if (rc) {
error_setg(errp, "KVM: Error configuring the CPU model: %d", rc);
return;
}
/* configure cpu features indicated e.g. via SCLP */
rc = configure_cpu_feat(model->features);
if (rc) {
error_setg(errp, "KVM: Error configuring CPU features: %d", rc);
return;
}
/* configure cpu subfunctions indicated via query / test bit */
rc = configure_cpu_subfunc(model->features);
if (rc) {
error_setg(errp, "KVM: Error configuring CPU subfunctions: %d", rc);
return;
}
/* enable CMM via CMMA - disable on hugetlbfs */
if (test_bit(S390_FEAT_CMM, model->features)) {
if (mem_path) {
error_report("Warning: CMM will not be enabled because it is not "
"compatible to hugetlbfs.");
} else {
kvm_s390_enable_cmma();
}
}
}

View file

@ -78,12 +78,7 @@ static const VMStateDescription vmstate_fpu = {
static bool vregs_needed(void *opaque)
{
#ifdef CONFIG_KVM
if (kvm_enabled()) {
return kvm_check_extension(kvm_state, KVM_CAP_S390_VECTOR_REGISTERS);
}
#endif
return 0;
return s390_has_feat(S390_FEAT_VECTOR);
}
static const VMStateDescription vmstate_vregs = {
@ -147,12 +142,7 @@ static const VMStateDescription vmstate_vregs = {
static bool riccb_needed(void *opaque)
{
#ifdef CONFIG_KVM
if (kvm_enabled()) {
return kvm_s390_get_ri();
}
#endif
return 0;
return s390_has_feat(S390_FEAT_RUNTIME_INSTRUMENTATION);
}
const VMStateDescription vmstate_riccb = {