Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

KVM: s390: Storage key manipulation IOCTL

Add a new IOCTL to allow userspace to manipulate storage keys directly.

This will make it easier to write selftests related to storage keys.

Acked-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>

+111
+42
Documentation/virt/kvm/api.rst
··· 6517 6517 6518 6518 `flags` must currently be zero. 6519 6519 6520 + 4.144 KVM_S390_KEYOP 6521 + -------------------- 6522 + 6523 + :Capability: KVM_CAP_S390_KEYOP 6524 + :Architectures: s390 6525 + :Type: vm ioctl 6526 + :Parameters: struct kvm_s390_keyop (in/out) 6527 + :Returns: 0 in case of success, < 0 on error 6528 + 6529 + The specified key operation is performed on the given guest address. The 6530 + previous storage key (or the relevant part thereof) will be returned in 6531 + `key`. 6532 + 6533 + :: 6534 + 6535 + struct kvm_s390_keyop { 6536 + __u64 guest_addr; 6537 + __u8 key; 6538 + __u8 operation; 6539 + }; 6540 + 6541 + Currently supported values for ``operation``: 6542 + 6543 + KVM_S390_KEYOP_ISKE 6544 + Returns the storage key for the guest address ``guest_addr`` in ``key``. 6545 + 6546 + KVM_S390_KEYOP_RRBE 6547 + Resets the reference bit for the guest address ``guest_addr``, returning the 6548 + R and C bits of the old storage key in ``key``; the remaining fields of 6549 + the storage key will be set to 0. 6550 + 6551 + KVM_S390_KEYOP_SSKE 6552 + Sets the storage key for the guest address ``guest_addr`` to the key 6553 + specified in ``key``, returning the previous value in ``key``. 6520 6554 6521 6555 .. _kvm_run: 6522 6556 ··· 9320 9286 The presence of this capability indicates that KVM_RUN will update the 9321 9287 KVM_RUN_X86_GUEST_MODE bit in kvm_run.flags to indicate whether the 9322 9288 vCPU was executing nested guest code when it exited. 9289 + 9290 + 8.46 KVM_CAP_S390_KEYOP 9291 + ----------------------- 9292 + 9293 + :Architectures: s390 9294 + 9295 + The presence of this capability indicates that the KVM_S390_KEYOP ioctl is 9296 + available. 9323 9297 9324 9298 KVM exits with the register state of either the L1 or L2 guest 9325 9299 depending on which executed at the time of an exit. Userspace must
+58
arch/s390/kvm/kvm-s390.c
··· 554 554 debug_unregister(kvm_s390_dbf_uv); 555 555 } 556 556 557 + static int kvm_s390_keyop(struct kvm_s390_mmu_cache *mc, struct kvm *kvm, int op, 558 + unsigned long addr, union skey skey) 559 + { 560 + union asce asce = kvm->arch.gmap->asce; 561 + gfn_t gfn = gpa_to_gfn(addr); 562 + int r; 563 + 564 + guard(read_lock)(&kvm->mmu_lock); 565 + 566 + switch (op) { 567 + case KVM_S390_KEYOP_SSKE: 568 + r = dat_cond_set_storage_key(mc, asce, gfn, skey, &skey, 0, 0, 0); 569 + if (r >= 0) 570 + return skey.skey; 571 + break; 572 + case KVM_S390_KEYOP_ISKE: 573 + r = dat_get_storage_key(asce, gfn, &skey); 574 + if (!r) 575 + return skey.skey; 576 + break; 577 + case KVM_S390_KEYOP_RRBE: 578 + r = dat_reset_reference_bit(asce, gfn); 579 + if (r > 0) 580 + return r << 1; 581 + break; 582 + default: 583 + return -EINVAL; 584 + } 585 + return r; 586 + } 587 + 557 588 /* Section: device related */ 558 589 long kvm_arch_dev_ioctl(struct file *filp, 559 590 unsigned int ioctl, unsigned long arg) ··· 629 598 case KVM_CAP_S390_DIAG318: 630 599 case KVM_CAP_IRQFD_RESAMPLE: 631 600 case KVM_CAP_S390_USER_OPEREXEC: 601 + case KVM_CAP_S390_KEYOP: 632 602 r = 1; 633 603 break; 634 604 case KVM_CAP_SET_GUEST_DEBUG2: ··· 2960 2928 if (copy_from_user(&mem_op, argp, sizeof(mem_op)) == 0) 2961 2929 r = kvm_s390_vm_mem_op(kvm, &mem_op); 2962 2930 else 2931 + r = -EFAULT; 2932 + break; 2933 + } 2934 + case KVM_S390_KEYOP: { 2935 + struct kvm_s390_mmu_cache *mc; 2936 + struct kvm_s390_keyop kop; 2937 + union skey skey; 2938 + 2939 + if (copy_from_user(&kop, argp, sizeof(kop))) { 2940 + r = -EFAULT; 2941 + break; 2942 + } 2943 + skey.skey = kop.key; 2944 + 2945 + mc = kvm_s390_new_mmu_cache(); 2946 + if (!mc) 2947 + return -ENOMEM; 2948 + 2949 + r = kvm_s390_keyop(mc, kvm, kop.operation, kop.guest_addr, skey); 2950 + kvm_s390_free_mmu_cache(mc); 2951 + if (r < 0) 2952 + break; 2953 + 2954 + kop.key = r; 2955 + r = 0; 2956 + if (copy_to_user(argp, &kop, sizeof(kop))) 2963 2957 r = -EFAULT; 2964 2958 break; 2965 2959 }
+11
include/uapi/linux/kvm.h
··· 974 974 #define KVM_CAP_GUEST_MEMFD_FLAGS 244 975 975 #define KVM_CAP_ARM_SEA_TO_USER 245 976 976 #define KVM_CAP_S390_USER_OPEREXEC 246 977 + #define KVM_CAP_S390_KEYOP 247 977 978 978 979 struct kvm_irq_routing_irqchip { 979 980 __u32 irqchip; ··· 1220 1219 __s32 tablefd; 1221 1220 }; 1222 1221 1222 + #define KVM_S390_KEYOP_ISKE 0x01 1223 + #define KVM_S390_KEYOP_RRBE 0x02 1224 + #define KVM_S390_KEYOP_SSKE 0x03 1225 + struct kvm_s390_keyop { 1226 + __u64 guest_addr; 1227 + __u8 key; 1228 + __u8 operation; 1229 + }; 1230 + 1223 1231 /* 1224 1232 * KVM_CREATE_VCPU receives as a parameter the vcpu slot, and returns 1225 1233 * a vcpu fd. ··· 1248 1238 #define KVM_S390_UCAS_MAP _IOW(KVMIO, 0x50, struct kvm_s390_ucas_mapping) 1249 1239 #define KVM_S390_UCAS_UNMAP _IOW(KVMIO, 0x51, struct kvm_s390_ucas_mapping) 1250 1240 #define KVM_S390_VCPU_FAULT _IOW(KVMIO, 0x52, unsigned long) 1241 + #define KVM_S390_KEYOP _IOWR(KVMIO, 0x53, struct kvm_s390_keyop) 1251 1242 1252 1243 /* Device model IOC */ 1253 1244 #define KVM_CREATE_IRQCHIP _IO(KVMIO, 0x60)