diff options
Diffstat (limited to 'arch/s390/kvm/kvm-s390.c')
-rw-r--r-- | arch/s390/kvm/kvm-s390.c | 50 |
1 files changed, 49 insertions, 1 deletions
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index f0937552175b..2d3248895def 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
@@ -233,6 +233,10 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) | |||
233 | (__u64) vcpu->arch.sie_block) | 233 | (__u64) vcpu->arch.sie_block) |
234 | vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda = 0; | 234 | vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda = 0; |
235 | smp_mb(); | 235 | smp_mb(); |
236 | |||
237 | if (kvm_is_ucontrol(vcpu->kvm)) | ||
238 | gmap_free(vcpu->arch.gmap); | ||
239 | |||
236 | free_page((unsigned long)(vcpu->arch.sie_block)); | 240 | free_page((unsigned long)(vcpu->arch.sie_block)); |
237 | kvm_vcpu_uninit(vcpu); | 241 | kvm_vcpu_uninit(vcpu); |
238 | kfree(vcpu); | 242 | kfree(vcpu); |
@@ -263,12 +267,20 @@ void kvm_arch_destroy_vm(struct kvm *kvm) | |||
263 | kvm_free_vcpus(kvm); | 267 | kvm_free_vcpus(kvm); |
264 | free_page((unsigned long)(kvm->arch.sca)); | 268 | free_page((unsigned long)(kvm->arch.sca)); |
265 | debug_unregister(kvm->arch.dbf); | 269 | debug_unregister(kvm->arch.dbf); |
266 | gmap_free(kvm->arch.gmap); | 270 | if (!kvm_is_ucontrol(kvm)) |
271 | gmap_free(kvm->arch.gmap); | ||
267 | } | 272 | } |
268 | 273 | ||
269 | /* Section: vcpu related */ | 274 | /* Section: vcpu related */ |
270 | int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) | 275 | int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) |
271 | { | 276 | { |
277 | if (kvm_is_ucontrol(vcpu->kvm)) { | ||
278 | vcpu->arch.gmap = gmap_alloc(current->mm); | ||
279 | if (!vcpu->arch.gmap) | ||
280 | return -ENOMEM; | ||
281 | return 0; | ||
282 | } | ||
283 | |||
272 | vcpu->arch.gmap = vcpu->kvm->arch.gmap; | 284 | vcpu->arch.gmap = vcpu->kvm->arch.gmap; |
273 | return 0; | 285 | return 0; |
274 | } | 286 | } |
@@ -687,6 +699,42 @@ long kvm_arch_vcpu_ioctl(struct file *filp, | |||
687 | case KVM_S390_INITIAL_RESET: | 699 | case KVM_S390_INITIAL_RESET: |
688 | r = kvm_arch_vcpu_ioctl_initial_reset(vcpu); | 700 | r = kvm_arch_vcpu_ioctl_initial_reset(vcpu); |
689 | break; | 701 | break; |
702 | #ifdef CONFIG_KVM_S390_UCONTROL | ||
703 | case KVM_S390_UCAS_MAP: { | ||
704 | struct kvm_s390_ucas_mapping ucasmap; | ||
705 | |||
706 | if (copy_from_user(&ucasmap, argp, sizeof(ucasmap))) { | ||
707 | r = -EFAULT; | ||
708 | break; | ||
709 | } | ||
710 | |||
711 | if (!kvm_is_ucontrol(vcpu->kvm)) { | ||
712 | r = -EINVAL; | ||
713 | break; | ||
714 | } | ||
715 | |||
716 | r = gmap_map_segment(vcpu->arch.gmap, ucasmap.user_addr, | ||
717 | ucasmap.vcpu_addr, ucasmap.length); | ||
718 | break; | ||
719 | } | ||
720 | case KVM_S390_UCAS_UNMAP: { | ||
721 | struct kvm_s390_ucas_mapping ucasmap; | ||
722 | |||
723 | if (copy_from_user(&ucasmap, argp, sizeof(ucasmap))) { | ||
724 | r = -EFAULT; | ||
725 | break; | ||
726 | } | ||
727 | |||
728 | if (!kvm_is_ucontrol(vcpu->kvm)) { | ||
729 | r = -EINVAL; | ||
730 | break; | ||
731 | } | ||
732 | |||
733 | r = gmap_unmap_segment(vcpu->arch.gmap, ucasmap.vcpu_addr, | ||
734 | ucasmap.length); | ||
735 | break; | ||
736 | } | ||
737 | #endif | ||
690 | default: | 738 | default: |
691 | r = -EINVAL; | 739 | r = -EINVAL; |
692 | } | 740 | } |