aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kvm
diff options
context:
space:
mode:
authorMichael Mueller <mimu@linux.vnet.ibm.com>2015-02-02 09:49:35 -0500
committerChristian Borntraeger <borntraeger@de.ibm.com>2015-02-09 06:44:13 -0500
commit658b6eda2042c0fe0e3f8acd7ffd11fc6f280119 (patch)
tree51849b96f3a5b295af5d943ad02659fab7caa714 /arch/s390/kvm
parent9d8d578605b4fca37bd2230bbacb3ad0ee48e7e4 (diff)
KVM: s390: add cpu model support
This patch enables cpu model support in kvm/s390 via the vm attribute interface. During KVM initialization, the host properties cpuid, IBC value and the facility list are stored in the architecture specific cpu model structure. During vcpu setup, these properties are taken to initialize the related SIE state. This mechanism allows to adjust the properties from user space and thus to implement different selectable cpu models. This patch uses the IBC functionality to block instructions that have not been implemented at the requested CPU type and GA level compared to the full host capability. Userspace has to initialize the cpu model before vcpu creation. A cpu model change of running vcpus is not possible. Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com> Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com> Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Diffstat (limited to 'arch/s390/kvm')
-rw-r--r--arch/s390/kvm/kvm-s390.c132
1 files changed, 132 insertions, 0 deletions
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 8c538a1a23c1..0c3623927563 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -502,6 +502,106 @@ static int kvm_s390_get_tod(struct kvm *kvm, struct kvm_device_attr *attr)
502 return ret; 502 return ret;
503} 503}
504 504
505static int kvm_s390_set_processor(struct kvm *kvm, struct kvm_device_attr *attr)
506{
507 struct kvm_s390_vm_cpu_processor *proc;
508 int ret = 0;
509
510 mutex_lock(&kvm->lock);
511 if (atomic_read(&kvm->online_vcpus)) {
512 ret = -EBUSY;
513 goto out;
514 }
515 proc = kzalloc(sizeof(*proc), GFP_KERNEL);
516 if (!proc) {
517 ret = -ENOMEM;
518 goto out;
519 }
520 if (!copy_from_user(proc, (void __user *)attr->addr,
521 sizeof(*proc))) {
522 memcpy(&kvm->arch.model.cpu_id, &proc->cpuid,
523 sizeof(struct cpuid));
524 kvm->arch.model.ibc = proc->ibc;
525 memcpy(kvm->arch.model.fac->kvm, proc->fac_list,
526 S390_ARCH_FAC_LIST_SIZE_BYTE);
527 } else
528 ret = -EFAULT;
529 kfree(proc);
530out:
531 mutex_unlock(&kvm->lock);
532 return ret;
533}
534
535static int kvm_s390_set_cpu_model(struct kvm *kvm, struct kvm_device_attr *attr)
536{
537 int ret = -ENXIO;
538
539 switch (attr->attr) {
540 case KVM_S390_VM_CPU_PROCESSOR:
541 ret = kvm_s390_set_processor(kvm, attr);
542 break;
543 }
544 return ret;
545}
546
547static int kvm_s390_get_processor(struct kvm *kvm, struct kvm_device_attr *attr)
548{
549 struct kvm_s390_vm_cpu_processor *proc;
550 int ret = 0;
551
552 proc = kzalloc(sizeof(*proc), GFP_KERNEL);
553 if (!proc) {
554 ret = -ENOMEM;
555 goto out;
556 }
557 memcpy(&proc->cpuid, &kvm->arch.model.cpu_id, sizeof(struct cpuid));
558 proc->ibc = kvm->arch.model.ibc;
559 memcpy(&proc->fac_list, kvm->arch.model.fac->kvm, S390_ARCH_FAC_LIST_SIZE_BYTE);
560 if (copy_to_user((void __user *)attr->addr, proc, sizeof(*proc)))
561 ret = -EFAULT;
562 kfree(proc);
563out:
564 return ret;
565}
566
567static int kvm_s390_get_machine(struct kvm *kvm, struct kvm_device_attr *attr)
568{
569 struct kvm_s390_vm_cpu_machine *mach;
570 int ret = 0;
571
572 mach = kzalloc(sizeof(*mach), GFP_KERNEL);
573 if (!mach) {
574 ret = -ENOMEM;
575 goto out;
576 }
577 get_cpu_id((struct cpuid *) &mach->cpuid);
578 mach->ibc = sclp_get_ibc();
579 memcpy(&mach->fac_mask, kvm_s390_fac_list_mask,
580 kvm_s390_fac_list_mask_size() * sizeof(u64));
581 memcpy((unsigned long *)&mach->fac_list, S390_lowcore.stfle_fac_list,
582 S390_ARCH_FAC_LIST_SIZE_U64);
583 if (copy_to_user((void __user *)attr->addr, mach, sizeof(*mach)))
584 ret = -EFAULT;
585 kfree(mach);
586out:
587 return ret;
588}
589
590static int kvm_s390_get_cpu_model(struct kvm *kvm, struct kvm_device_attr *attr)
591{
592 int ret = -ENXIO;
593
594 switch (attr->attr) {
595 case KVM_S390_VM_CPU_PROCESSOR:
596 ret = kvm_s390_get_processor(kvm, attr);
597 break;
598 case KVM_S390_VM_CPU_MACHINE:
599 ret = kvm_s390_get_machine(kvm, attr);
600 break;
601 }
602 return ret;
603}
604
505static int kvm_s390_vm_set_attr(struct kvm *kvm, struct kvm_device_attr *attr) 605static int kvm_s390_vm_set_attr(struct kvm *kvm, struct kvm_device_attr *attr)
506{ 606{
507 int ret; 607 int ret;
@@ -513,6 +613,9 @@ static int kvm_s390_vm_set_attr(struct kvm *kvm, struct kvm_device_attr *attr)
513 case KVM_S390_VM_TOD: 613 case KVM_S390_VM_TOD:
514 ret = kvm_s390_set_tod(kvm, attr); 614 ret = kvm_s390_set_tod(kvm, attr);
515 break; 615 break;
616 case KVM_S390_VM_CPU_MODEL:
617 ret = kvm_s390_set_cpu_model(kvm, attr);
618 break;
516 case KVM_S390_VM_CRYPTO: 619 case KVM_S390_VM_CRYPTO:
517 ret = kvm_s390_vm_set_crypto(kvm, attr); 620 ret = kvm_s390_vm_set_crypto(kvm, attr);
518 break; 621 break;
@@ -535,6 +638,9 @@ static int kvm_s390_vm_get_attr(struct kvm *kvm, struct kvm_device_attr *attr)
535 case KVM_S390_VM_TOD: 638 case KVM_S390_VM_TOD:
536 ret = kvm_s390_get_tod(kvm, attr); 639 ret = kvm_s390_get_tod(kvm, attr);
537 break; 640 break;
641 case KVM_S390_VM_CPU_MODEL:
642 ret = kvm_s390_get_cpu_model(kvm, attr);
643 break;
538 default: 644 default:
539 ret = -ENXIO; 645 ret = -ENXIO;
540 break; 646 break;
@@ -571,6 +677,17 @@ static int kvm_s390_vm_has_attr(struct kvm *kvm, struct kvm_device_attr *attr)
571 break; 677 break;
572 } 678 }
573 break; 679 break;
680 case KVM_S390_VM_CPU_MODEL:
681 switch (attr->attr) {
682 case KVM_S390_VM_CPU_PROCESSOR:
683 case KVM_S390_VM_CPU_MACHINE:
684 ret = 0;
685 break;
686 default:
687 ret = -ENXIO;
688 break;
689 }
690 break;
574 case KVM_S390_VM_CRYPTO: 691 case KVM_S390_VM_CRYPTO:
575 switch (attr->attr) { 692 switch (attr->attr) {
576 case KVM_S390_VM_CRYPTO_ENABLE_AES_KW: 693 case KVM_S390_VM_CRYPTO_ENABLE_AES_KW:
@@ -782,6 +899,17 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
782 S390_ARCH_FAC_LIST_SIZE_U64); 899 S390_ARCH_FAC_LIST_SIZE_U64);
783 900
784 /* 901 /*
902 * If this KVM host runs *not* in a LPAR, relax the facility bits
903 * of the kvm facility mask by all missing facilities. This will allow
904 * to determine the right CPU model by means of the remaining facilities.
905 * Live guest migration must prohibit the migration of KVMs running in
906 * a LPAR to non LPAR hosts.
907 */
908 if (!MACHINE_IS_LPAR)
909 for (i = 0; i < kvm_s390_fac_list_mask_size(); i++)
910 kvm_s390_fac_list_mask[i] &= kvm->arch.model.fac->kvm[i];
911
912 /*
785 * Apply the kvm facility mask to limit the kvm supported/tolerated 913 * Apply the kvm facility mask to limit the kvm supported/tolerated
786 * facility list. 914 * facility list.
787 */ 915 */
@@ -793,6 +921,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
793 } 921 }
794 922
795 kvm_s390_get_cpu_id(&kvm->arch.model.cpu_id); 923 kvm_s390_get_cpu_id(&kvm->arch.model.cpu_id);
924 kvm->arch.model.ibc = sclp_get_ibc() & 0x0fff;
796 925
797 if (kvm_s390_crypto_init(kvm) < 0) 926 if (kvm_s390_crypto_init(kvm) < 0)
798 goto out_crypto; 927 goto out_crypto;
@@ -1034,9 +1163,12 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
1034 hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 1163 hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
1035 vcpu->arch.ckc_timer.function = kvm_s390_idle_wakeup; 1164 vcpu->arch.ckc_timer.function = kvm_s390_idle_wakeup;
1036 1165
1166 mutex_lock(&vcpu->kvm->lock);
1037 vcpu->arch.cpu_id = vcpu->kvm->arch.model.cpu_id; 1167 vcpu->arch.cpu_id = vcpu->kvm->arch.model.cpu_id;
1038 memcpy(vcpu->kvm->arch.model.fac->sie, vcpu->kvm->arch.model.fac->kvm, 1168 memcpy(vcpu->kvm->arch.model.fac->sie, vcpu->kvm->arch.model.fac->kvm,
1039 S390_ARCH_FAC_LIST_SIZE_BYTE); 1169 S390_ARCH_FAC_LIST_SIZE_BYTE);
1170 vcpu->arch.sie_block->ibc = vcpu->kvm->arch.model.ibc;
1171 mutex_unlock(&vcpu->kvm->lock);
1040 1172
1041 kvm_s390_vcpu_crypto_setup(vcpu); 1173 kvm_s390_vcpu_crypto_setup(vcpu);
1042 1174