mirror of https://gitee.com/openkylin/qemu.git
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:
commit
f9ae6bcf1d
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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",\
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
||||
/*
|
||||
|
|
|
@ -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 */
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
246
qapi-schema.json
246
qapi-schema.json
|
@ -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.
|
||||
|
|
|
@ -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
21
qmp.c
|
@ -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)
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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) */
|
||||
|
|
|
@ -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)
|
|
@ -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 */
|
|
@ -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 */
|
File diff suppressed because it is too large
Load Diff
|
@ -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 */
|
|
@ -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;
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 = {
|
||||
|
|
Loading…
Reference in New Issue