Jason J. Herne | 0efe406 | 2015-06-26 11:54:51 -0400 | [diff] [blame] | 1 | /* |
| 2 | * s390 storage key device |
| 3 | * |
| 4 | * Copyright 2015 IBM Corp. |
| 5 | * Author(s): Jason J. Herne <jjherne@linux.vnet.ibm.com> |
| 6 | * |
| 7 | * This work is licensed under the terms of the GNU GPL, version 2 or (at |
| 8 | * your option) any later version. See the COPYING file in the top-level |
| 9 | * directory. |
| 10 | */ |
| 11 | |
Peter Maydell | 9615495 | 2016-01-26 18:17:00 +0000 | [diff] [blame] | 12 | #include "qemu/osdep.h" |
Jason J. Herne | 0efe406 | 2015-06-26 11:54:51 -0400 | [diff] [blame] | 13 | #include "hw/s390x/storage-keys.h" |
| 14 | #include "sysemu/kvm.h" |
| 15 | #include "qemu/error-report.h" |
Markus Armbruster | 0b8fa32 | 2019-05-23 16:35:07 +0200 | [diff] [blame] | 16 | #include "qemu/module.h" |
Jason J. Herne | 0efe406 | 2015-06-26 11:54:51 -0400 | [diff] [blame] | 17 | |
David Hildenbrand | 5227b32 | 2021-09-03 17:55:13 +0200 | [diff] [blame] | 18 | static bool kvm_s390_skeys_are_enabled(S390SKeysState *ss) |
Jason J. Herne | 0efe406 | 2015-06-26 11:54:51 -0400 | [diff] [blame] | 19 | { |
| 20 | S390SKeysClass *skeyclass = S390_SKEYS_GET_CLASS(ss); |
| 21 | uint8_t single_key; |
| 22 | int r; |
| 23 | |
| 24 | r = skeyclass->get_skeys(ss, 0, 1, &single_key); |
| 25 | if (r != 0 && r != KVM_S390_GET_SKEYS_NONE) { |
Markus Armbruster | 9af9e0f | 2015-12-18 16:35:19 +0100 | [diff] [blame] | 26 | error_report("S390_GET_KEYS error %d", r); |
Jason J. Herne | 0efe406 | 2015-06-26 11:54:51 -0400 | [diff] [blame] | 27 | } |
| 28 | return (r == 0); |
| 29 | } |
| 30 | |
| 31 | static int kvm_s390_skeys_get(S390SKeysState *ss, uint64_t start_gfn, |
| 32 | uint64_t count, uint8_t *keys) |
| 33 | { |
| 34 | struct kvm_s390_skeys args = { |
| 35 | .start_gfn = start_gfn, |
| 36 | .count = count, |
| 37 | .skeydata_addr = (__u64)keys |
| 38 | }; |
| 39 | |
| 40 | return kvm_vm_ioctl(kvm_state, KVM_S390_GET_SKEYS, &args); |
| 41 | } |
| 42 | |
| 43 | static int kvm_s390_skeys_set(S390SKeysState *ss, uint64_t start_gfn, |
| 44 | uint64_t count, uint8_t *keys) |
| 45 | { |
| 46 | struct kvm_s390_skeys args = { |
| 47 | .start_gfn = start_gfn, |
| 48 | .count = count, |
| 49 | .skeydata_addr = (__u64)keys |
| 50 | }; |
| 51 | |
| 52 | return kvm_vm_ioctl(kvm_state, KVM_S390_SET_SKEYS, &args); |
| 53 | } |
| 54 | |
| 55 | static void kvm_s390_skeys_class_init(ObjectClass *oc, void *data) |
| 56 | { |
| 57 | S390SKeysClass *skeyclass = S390_SKEYS_CLASS(oc); |
Thomas Huth | 574ee06 | 2017-08-24 12:08:48 +0200 | [diff] [blame] | 58 | DeviceClass *dc = DEVICE_CLASS(oc); |
Jason J. Herne | 0efe406 | 2015-06-26 11:54:51 -0400 | [diff] [blame] | 59 | |
David Hildenbrand | 5227b32 | 2021-09-03 17:55:13 +0200 | [diff] [blame] | 60 | skeyclass->skeys_are_enabled = kvm_s390_skeys_are_enabled; |
Jason J. Herne | 0efe406 | 2015-06-26 11:54:51 -0400 | [diff] [blame] | 61 | skeyclass->get_skeys = kvm_s390_skeys_get; |
| 62 | skeyclass->set_skeys = kvm_s390_skeys_set; |
Thomas Huth | 574ee06 | 2017-08-24 12:08:48 +0200 | [diff] [blame] | 63 | |
| 64 | /* Reason: Internal device (only one skeys device for the whole memory) */ |
| 65 | dc->user_creatable = false; |
Jason J. Herne | 0efe406 | 2015-06-26 11:54:51 -0400 | [diff] [blame] | 66 | } |
| 67 | |
| 68 | static const TypeInfo kvm_s390_skeys_info = { |
| 69 | .name = TYPE_KVM_S390_SKEYS, |
| 70 | .parent = TYPE_S390_SKEYS, |
| 71 | .instance_size = sizeof(S390SKeysState), |
| 72 | .class_init = kvm_s390_skeys_class_init, |
| 73 | .class_size = sizeof(S390SKeysClass), |
| 74 | }; |
| 75 | |
| 76 | static void kvm_s390_skeys_register_types(void) |
| 77 | { |
| 78 | type_register_static(&kvm_s390_skeys_info); |
| 79 | } |
| 80 | |
| 81 | type_init(kvm_s390_skeys_register_types) |