From: Christian Borntraeger <borntraeger@xxxxxxxxxx> For guest relocation and virsh dump qemu needs an interface to get/set additional registers from kvm. We also need the prefix register for all guest memory accesses to the prefix pages. The prefix register could also be set via the KVM_S390_SIGP_SET_PREFIX interrupt ioctl, but I also added the synchronous operation to have o symmetry: we want to have the same struct for get/set routine o the interrupt is only delivered before entering the SIE, we also want to cover the sequence set prefix/store status at prefix Signed-off-by: Christian Borntraeger <borntraeger@xxxxxxxxxx> --- Documentation/virtual/kvm/api.txt | 31 +++++++++++++++++++++++++++++++ arch/s390/include/asm/kvm.h | 9 +++++++++ arch/s390/kvm/kvm-s390.c | 30 ++++++++++++++++++++++++++++++ include/linux/kvm.h | 4 ++++ 4 files changed, 74 insertions(+) Index: b/Documentation/virtual/kvm/api.txt =================================================================== --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@ -1450,6 +1450,37 @@ is supported; 2 if the processor require an RMA, or 1 if the processor can use an RMA but doesn't require it, because it supports the Virtual RMA (VRMA) facility. +4.64 KVM_S390_GET_SREGS2 + +Capability: KVM_CAP_S390_SREGS2 +Architectures: s390x +Type: vcpu ioctl +Parameters: struct kvm_sregs2 (out) +Returns: 0 on success, -1 on error + +Reads special registers from the vcpu which are not covered by sregs. + +/* s390x */ +struct kvm_sregs2 { + __u64 ckc; /* clock comparator */ + __u64 cputm; /* cpu timer */ + __u64 gbea; /* guest breaking event address */ + __u32 todpr; /* tod programmable field */ + __u32 prefix; /* prefix register */ +}; + +4.65 KVM_S390_SET_SREGS2 + +Capability: KVM_CAP_S390_SREGS2 +Architectures: s390x +Type: vcpu ioctl +Parameters: struct kvm_sregs2 (in) +Returns: 0 on success, -1 on error + +Writes special registers into the vcpu. See KVM_S390_GET_SREGS2 for the +data structures. + + 5. The kvm_run structure Application code obtains a pointer to the kvm_run structure by Index: b/arch/s390/include/asm/kvm.h =================================================================== --- a/arch/s390/include/asm/kvm.h +++ b/arch/s390/include/asm/kvm.h @@ -28,6 +28,15 @@ struct kvm_sregs { __u64 crs[16]; }; +/* for KVM_S390_GET_SREGS2 and KVM_S390_SET_SREGS2 */ +struct kvm_s390_sregs2 { + __u64 ckc; /* clock comparator */ + __u64 cputm; /* cpu timer */ + __u64 gbea; /* guest breaking event address */ + __u32 todpr; /* tod programmable field */ + __u32 prefix; /* prefix register */ +}; + /* for KVM_GET_FPU and KVM_SET_FPU */ struct kvm_fpu { __u32 fpc; Index: b/arch/s390/kvm/kvm-s390.c =================================================================== --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -129,6 +129,7 @@ int kvm_dev_ioctl_check_extension(long e case KVM_CAP_S390_PSW: case KVM_CAP_S390_GMAP: case KVM_CAP_SYNC_MMU: + case KVM_CAP_S390_SREGS2: r = 1; break; default: @@ -673,6 +674,35 @@ long kvm_arch_vcpu_ioctl(struct file *fi case KVM_S390_INITIAL_RESET: r = kvm_arch_vcpu_ioctl_initial_reset(vcpu); break; + case KVM_S390_GET_SREGS2: { + struct kvm_s390_sregs2 sregs2; + + sregs2.prefix = vcpu->arch.sie_block->prefix; + sregs2.gbea = vcpu->arch.sie_block->gbea; + sregs2.cputm = vcpu->arch.sie_block->cputm; + sregs2.ckc = vcpu->arch.sie_block->ckc; + sregs2.todpr = vcpu->arch.sie_block->todpr; + r = -EFAULT; + if (copy_to_user(argp, &sregs2, sizeof(sregs2))) + break; + r = 0; + break; + } + case KVM_S390_SET_SREGS2: { + struct kvm_s390_sregs2 sregs2; + + r = -EFAULT; + if (copy_from_user(&sregs2, argp, sizeof(sregs2))) + break; + vcpu->arch.sie_block->prefix = sregs2.prefix; + vcpu->arch.sie_block->gbea = sregs2.gbea; + vcpu->arch.sie_block->cputm = sregs2.cputm; + vcpu->arch.sie_block->ckc = sregs2.ckc; + vcpu->arch.sie_block->todpr = sregs2.todpr; + flush_guest_cpu(vcpu); + r = 0; + break; + } default: r = -EINVAL; } Index: b/include/linux/kvm.h =================================================================== --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -557,6 +557,7 @@ struct kvm_ppc_pvinfo { #define KVM_CAP_MAX_VCPUS 66 /* returns max vcpus per vm */ #define KVM_CAP_PPC_PAPR 68 #define KVM_CAP_S390_GMAP 71 +#define KVM_CAP_S390_SREGS2 72 #ifdef KVM_CAP_IRQ_ROUTING @@ -762,6 +763,9 @@ struct kvm_clock_data { #define KVM_CREATE_SPAPR_TCE _IOW(KVMIO, 0xa8, struct kvm_create_spapr_tce) /* Available with KVM_CAP_RMA */ #define KVM_ALLOCATE_RMA _IOR(KVMIO, 0xa9, struct kvm_allocate_rma) +/* Available with KVM_CAP_S390_SREGS2 */ +#define KVM_S390_GET_SREGS2 _IOR(KVMIO, 0xaa, struct kvm_s390_sregs2) +#define KVM_S390_SET_SREGS2 _IOW(KVMIO, 0xab, struct kvm_s390_sregs2) #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html