From 0efe406cac8a4d9f0b52eada4c6c2a768fe4b7d2 Mon Sep 17 00:00:00 2001 From: Jason J. Herne Date: Fri, 26 Jun 2015 11:54:51 -0400 Subject: s390x: Create QOM device for s390 storage keys A new QOM style device is provided to back guest storage keys. A special version for KVM is created, which handles the storage key access via KVM_S390_GET_SKEYS and KVM_S390_SET_SKEYS ioctl. Reviewed-by: David Hildenbrand Signed-off-by: Jason J. Herne Signed-off-by: Cornelia Huck --- include/hw/s390x/storage-keys.h | 55 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 include/hw/s390x/storage-keys.h (limited to 'include') diff --git a/include/hw/s390x/storage-keys.h b/include/hw/s390x/storage-keys.h new file mode 100644 index 0000000000..cfd7da79a4 --- /dev/null +++ b/include/hw/s390x/storage-keys.h @@ -0,0 +1,55 @@ +/* + * s390 storage key device + * + * Copyright 2015 IBM Corp. + * Author(s): Jason J. Herne + * + * 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 __S390_STORAGE_KEYS_H +#define __S390_STORAGE_KEYS_H + +#include + +#define TYPE_S390_SKEYS "s390-skeys" +#define S390_SKEYS(obj) \ + OBJECT_CHECK(S390SKeysState, (obj), TYPE_S390_SKEYS) + +typedef struct S390SKeysState { + DeviceState parent_obj; + +} S390SKeysState; + +#define S390_SKEYS_CLASS(klass) \ + OBJECT_CLASS_CHECK(S390SKeysClass, (klass), TYPE_S390_SKEYS) +#define S390_SKEYS_GET_CLASS(obj) \ + OBJECT_GET_CLASS(S390SKeysClass, (obj), TYPE_S390_SKEYS) + +typedef struct S390SKeysClass { + DeviceClass parent_class; + int (*skeys_enabled)(S390SKeysState *ks); + int (*get_skeys)(S390SKeysState *ks, uint64_t start_gfn, uint64_t count, + uint8_t *keys); + int (*set_skeys)(S390SKeysState *ks, uint64_t start_gfn, uint64_t count, + uint8_t *keys); +} S390SKeysClass; + +#define TYPE_KVM_S390_SKEYS "s390-skeys-kvm" +#define TYPE_QEMU_S390_SKEYS "s390-skeys-qemu" +#define QEMU_S390_SKEYS(obj) \ + OBJECT_CHECK(QEMUS390SKeysState, (obj), TYPE_QEMU_S390_SKEYS) + +typedef struct QEMUS390SKeysState { + S390SKeysState parent_obj; + uint8_t *keydata; + uint32_t key_count; +} QEMUS390SKeysState; + +void s390_skeys_init(void); + +S390SKeysState *s390_get_skeys_device(void); + +#endif /* __S390_STORAGE_KEYS_H */ -- cgit v1.2.3-55-g7522 From a4538a5cc57dd493ed1545be98fa0ead0d391b8a Mon Sep 17 00:00:00 2001 From: Jason J. Herne Date: Fri, 26 Jun 2015 14:07:21 -0400 Subject: s390x: Dump-skeys hmp support Add dump-skeys command to the human monitor. Reviewed-by: Thomas Huth Reviewed-by: David Hildenbrand Signed-off-by: Jason J. Herne Signed-off-by: Cornelia Huck --- hmp-commands.hx | 16 ++++++++++++++++ hw/s390x/s390-skeys.c | 12 ++++++++++++ include/hw/s390x/storage-keys.h | 2 ++ monitor.c | 4 ++++ 4 files changed, 34 insertions(+) (limited to 'include') diff --git a/hmp-commands.hx b/hmp-commands.hx index d3b7932ff6..803ff916c2 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1053,6 +1053,22 @@ gdb. Without -z|-l|-s, the dump format is ELF. together with begin. ETEXI +#if defined(TARGET_S390X) + { + .name = "dump-skeys", + .args_type = "filename:F", + .params = "", + .help = "Save guest storage keys into file 'filename'.\n", + .mhandler.cmd = hmp_dump_skeys, + }, +#endif + +STEXI +@item dump-skeys @var{filename} +@findex dump-skeys +Save guest storage keys to a file. +ETEXI + { .name = "snapshot_blkdev", .args_type = "reuse:-n,device:B,snapshot-file:s?,format:s?", diff --git a/hw/s390x/s390-skeys.c b/hw/s390x/s390-skeys.c index a1d10a9897..98a6938523 100644 --- a/hw/s390x/s390-skeys.c +++ b/hw/s390x/s390-skeys.c @@ -66,6 +66,18 @@ static void write_keys(QEMUFile *f, uint8_t *keys, uint64_t startgfn, } } +void hmp_dump_skeys(Monitor *mon, const QDict *qdict) +{ + const char *filename = qdict_get_str(qdict, "filename"); + Error *err = NULL; + + qmp_dump_skeys(filename, &err); + if (err) { + monitor_printf(mon, "%s\n", error_get_pretty(err)); + error_free(err); + } +} + void qmp_dump_skeys(const char *filename, Error **errp) { S390SKeysState *ss = s390_get_skeys_device(); diff --git a/include/hw/s390x/storage-keys.h b/include/hw/s390x/storage-keys.h index cfd7da79a4..0d04f196da 100644 --- a/include/hw/s390x/storage-keys.h +++ b/include/hw/s390x/storage-keys.h @@ -13,6 +13,7 @@ #define __S390_STORAGE_KEYS_H #include +#include "monitor/monitor.h" #define TYPE_S390_SKEYS "s390-skeys" #define S390_SKEYS(obj) \ @@ -52,4 +53,5 @@ void s390_skeys_init(void); S390SKeysState *s390_get_skeys_device(void); +void hmp_dump_skeys(Monitor *mon, const QDict *qdict); #endif /* __S390_STORAGE_KEYS_H */ diff --git a/monitor.c b/monitor.c index daa3d98cf3..3deba38105 100644 --- a/monitor.c +++ b/monitor.c @@ -82,6 +82,10 @@ #endif #include "hw/lm32/lm32_pic.h" +#if defined(TARGET_S390X) +#include "hw/s390x/storage-keys.h" +#endif + /* * Supported types: * -- cgit v1.2.3-55-g7522 From a08f0081c9886c1914d7bc2e6a29636a769fec84 Mon Sep 17 00:00:00 2001 From: Jason J. Herne Date: Fri, 26 Jun 2015 14:10:16 -0400 Subject: s390x: Info skeys sub-command Provide an info skeys hmp sub-command to allow the end user to dump a storage key for a given address. This is useful for guest operating system developers. Reviewed-by: Thomas Huth Reviewed-by: David Hildenbrand Signed-off-by: Jason J. Herne Signed-off-by: Cornelia Huck --- hmp-commands.hx | 2 ++ hw/s390x/s390-skeys.c | 23 +++++++++++++++++++++++ include/hw/s390x/storage-keys.h | 2 ++ monitor.c | 9 +++++++++ 4 files changed, 36 insertions(+) (limited to 'include') diff --git a/hmp-commands.hx b/hmp-commands.hx index 803ff916c2..c61468e703 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1806,6 +1806,8 @@ show roms show the TPM device @item info memory-devices show the memory devices +@item info skeys +Display the value of a storage key (s390 only) @end table ETEXI diff --git a/hw/s390x/s390-skeys.c b/hw/s390x/s390-skeys.c index 98a6938523..e3860c1dfd 100644 --- a/hw/s390x/s390-skeys.c +++ b/hw/s390x/s390-skeys.c @@ -66,6 +66,29 @@ static void write_keys(QEMUFile *f, uint8_t *keys, uint64_t startgfn, } } +void hmp_info_skeys(Monitor *mon, const QDict *qdict) +{ + S390SKeysState *ss = s390_get_skeys_device(); + S390SKeysClass *skeyclass = S390_SKEYS_GET_CLASS(ss); + uint64_t addr = qdict_get_int(qdict, "addr"); + uint8_t key; + int r; + + /* Quick check to see if guest is using storage keys*/ + if (!skeyclass->skeys_enabled(ss)) { + monitor_printf(mon, "Error: This guest is not using storage keys\n"); + return; + } + + r = skeyclass->get_skeys(ss, addr / TARGET_PAGE_SIZE, 1, &key); + if (r < 0) { + monitor_printf(mon, "Error: %s\n", strerror(-r)); + return; + } + + monitor_printf(mon, " key: 0x%X\n", key); +} + void hmp_dump_skeys(Monitor *mon, const QDict *qdict) { const char *filename = qdict_get_str(qdict, "filename"); diff --git a/include/hw/s390x/storage-keys.h b/include/hw/s390x/storage-keys.h index 0d04f196da..18e08d27d6 100644 --- a/include/hw/s390x/storage-keys.h +++ b/include/hw/s390x/storage-keys.h @@ -54,4 +54,6 @@ void s390_skeys_init(void); S390SKeysState *s390_get_skeys_device(void); void hmp_dump_skeys(Monitor *mon, const QDict *qdict); +void hmp_info_skeys(Monitor *mon, const QDict *qdict); + #endif /* __S390_STORAGE_KEYS_H */ diff --git a/monitor.c b/monitor.c index 3deba38105..451af6ff89 100644 --- a/monitor.c +++ b/monitor.c @@ -2881,6 +2881,15 @@ static mon_cmd_t info_cmds[] = { .help = "Show rocker OF-DPA groups", .mhandler.cmd = hmp_rocker_of_dpa_groups, }, +#if defined(TARGET_S390X) + { + .name = "skeys", + .args_type = "addr:l", + .params = "address", + .help = "Display the value of a storage key", + .mhandler.cmd = hmp_info_skeys, + }, +#endif { .name = NULL, }, -- cgit v1.2.3-55-g7522 From 9ef40173fbe99c0562d227980779a73613788782 Mon Sep 17 00:00:00 2001 From: Jason J. Herne Date: Thu, 9 Jul 2015 13:56:44 -0400 Subject: s390x: Disable storage key migration on old machine type This code disables storage key migration when an older machine type is specified. Reviewed-by: David Hildenbrand Signed-off-by: Jason J. Herne Signed-off-by: Cornelia Huck --- hw/s390x/s390-skeys.c | 33 ++++++++++++++++++++++++++++++--- hw/s390x/s390-virtio-ccw.c | 12 ++++++++++++ include/hw/s390x/storage-keys.h | 1 + 3 files changed, 43 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/hw/s390x/s390-skeys.c b/hw/s390x/s390-skeys.c index dea30422bd..539ef6d3a4 100644 --- a/hw/s390x/s390-skeys.c +++ b/hw/s390x/s390-skeys.c @@ -353,12 +353,39 @@ static int s390_storage_keys_load(QEMUFile *f, void *opaque, int version_id) return ret; } -static void s390_skeys_instance_init(Object *obj) +static inline bool s390_skeys_get_migration_enabled(Object *obj, Error **errp) +{ + S390SKeysState *ss = S390_SKEYS(obj); + + return ss->migration_enabled; +} + +static inline void s390_skeys_set_migration_enabled(Object *obj, bool value, + Error **errp) { S390SKeysState *ss = S390_SKEYS(obj); - register_savevm(NULL, TYPE_S390_SKEYS, 0, 1, s390_storage_keys_save, - s390_storage_keys_load, ss); + /* Prevent double registration of savevm handler */ + if (ss->migration_enabled == value) { + return; + } + + ss->migration_enabled = value; + + if (ss->migration_enabled) { + register_savevm(NULL, TYPE_S390_SKEYS, 0, 1, s390_storage_keys_save, + s390_storage_keys_load, ss); + } else { + unregister_savevm(DEVICE(ss), TYPE_S390_SKEYS, ss); + } +} + +static void s390_skeys_instance_init(Object *obj) +{ + object_property_add_bool(obj, "migration-enabled", + s390_skeys_get_migration_enabled, + s390_skeys_set_migration_enabled, NULL); + object_property_set_bool(obj, true, "migration-enabled", NULL); } static void s390_skeys_class_init(ObjectClass *oc, void *data) diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c index 0a057aeb90..e2a26e95b9 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c @@ -282,12 +282,24 @@ static const TypeInfo ccw_machine_info = { }, }; +#define CCW_COMPAT_2_4 \ + {\ + .driver = TYPE_S390_SKEYS,\ + .property = "migration-enabled",\ + .value = "off",\ + }, + static void ccw_machine_2_4_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); + static GlobalProperty compat_props[] = { + CCW_COMPAT_2_4 + { /* end of list */ } + }; mc->name = "s390-ccw-virtio-2.4"; mc->desc = "VirtIO-ccw based S390 machine v2.4"; + mc->compat_props = compat_props; } static const TypeInfo ccw_machine_2_4_info = { diff --git a/include/hw/s390x/storage-keys.h b/include/hw/s390x/storage-keys.h index 18e08d27d6..72b850cb17 100644 --- a/include/hw/s390x/storage-keys.h +++ b/include/hw/s390x/storage-keys.h @@ -21,6 +21,7 @@ typedef struct S390SKeysState { DeviceState parent_obj; + bool migration_enabled; } S390SKeysState; -- cgit v1.2.3-55-g7522