diff options
Diffstat (limited to 'arch/s390/kvm/kvm-s390.c')
-rw-r--r-- | arch/s390/kvm/kvm-s390.c | 48 |
1 files changed, 23 insertions, 25 deletions
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 67345ae7ce8d..f17296e4fc89 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
@@ -62,6 +62,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { | |||
62 | { "instruction_chsc", VCPU_STAT(instruction_chsc) }, | 62 | { "instruction_chsc", VCPU_STAT(instruction_chsc) }, |
63 | { "instruction_stsi", VCPU_STAT(instruction_stsi) }, | 63 | { "instruction_stsi", VCPU_STAT(instruction_stsi) }, |
64 | { "instruction_stfl", VCPU_STAT(instruction_stfl) }, | 64 | { "instruction_stfl", VCPU_STAT(instruction_stfl) }, |
65 | { "instruction_tprot", VCPU_STAT(instruction_tprot) }, | ||
65 | { "instruction_sigp_sense", VCPU_STAT(instruction_sigp_sense) }, | 66 | { "instruction_sigp_sense", VCPU_STAT(instruction_sigp_sense) }, |
66 | { "instruction_sigp_emergency", VCPU_STAT(instruction_sigp_emergency) }, | 67 | { "instruction_sigp_emergency", VCPU_STAT(instruction_sigp_emergency) }, |
67 | { "instruction_sigp_stop", VCPU_STAT(instruction_sigp_stop) }, | 68 | { "instruction_sigp_stop", VCPU_STAT(instruction_sigp_stop) }, |
@@ -189,7 +190,13 @@ int kvm_arch_init_vm(struct kvm *kvm) | |||
189 | debug_register_view(kvm->arch.dbf, &debug_sprintf_view); | 190 | debug_register_view(kvm->arch.dbf, &debug_sprintf_view); |
190 | VM_EVENT(kvm, 3, "%s", "vm created"); | 191 | VM_EVENT(kvm, 3, "%s", "vm created"); |
191 | 192 | ||
193 | kvm->arch.gmap = gmap_alloc(current->mm); | ||
194 | if (!kvm->arch.gmap) | ||
195 | goto out_nogmap; | ||
196 | |||
192 | return 0; | 197 | return 0; |
198 | out_nogmap: | ||
199 | debug_unregister(kvm->arch.dbf); | ||
193 | out_nodbf: | 200 | out_nodbf: |
194 | free_page((unsigned long)(kvm->arch.sca)); | 201 | free_page((unsigned long)(kvm->arch.sca)); |
195 | out_err: | 202 | out_err: |
@@ -234,11 +241,13 @@ void kvm_arch_destroy_vm(struct kvm *kvm) | |||
234 | kvm_free_vcpus(kvm); | 241 | kvm_free_vcpus(kvm); |
235 | free_page((unsigned long)(kvm->arch.sca)); | 242 | free_page((unsigned long)(kvm->arch.sca)); |
236 | debug_unregister(kvm->arch.dbf); | 243 | debug_unregister(kvm->arch.dbf); |
244 | gmap_free(kvm->arch.gmap); | ||
237 | } | 245 | } |
238 | 246 | ||
239 | /* Section: vcpu related */ | 247 | /* Section: vcpu related */ |
240 | int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) | 248 | int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) |
241 | { | 249 | { |
250 | vcpu->arch.gmap = vcpu->kvm->arch.gmap; | ||
242 | return 0; | 251 | return 0; |
243 | } | 252 | } |
244 | 253 | ||
@@ -284,8 +293,7 @@ static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu) | |||
284 | 293 | ||
285 | int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) | 294 | int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) |
286 | { | 295 | { |
287 | atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH); | 296 | atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH | CPUSTAT_SM); |
288 | set_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests); | ||
289 | vcpu->arch.sie_block->ecb = 6; | 297 | vcpu->arch.sie_block->ecb = 6; |
290 | vcpu->arch.sie_block->eca = 0xC1002001U; | 298 | vcpu->arch.sie_block->eca = 0xC1002001U; |
291 | vcpu->arch.sie_block->fac = (int) (long) facilities; | 299 | vcpu->arch.sie_block->fac = (int) (long) facilities; |
@@ -453,6 +461,7 @@ static void __vcpu_run(struct kvm_vcpu *vcpu) | |||
453 | local_irq_disable(); | 461 | local_irq_disable(); |
454 | kvm_guest_enter(); | 462 | kvm_guest_enter(); |
455 | local_irq_enable(); | 463 | local_irq_enable(); |
464 | gmap_enable(vcpu->arch.gmap); | ||
456 | VCPU_EVENT(vcpu, 6, "entering sie flags %x", | 465 | VCPU_EVENT(vcpu, 6, "entering sie flags %x", |
457 | atomic_read(&vcpu->arch.sie_block->cpuflags)); | 466 | atomic_read(&vcpu->arch.sie_block->cpuflags)); |
458 | if (sie64a(vcpu->arch.sie_block, vcpu->arch.guest_gprs)) { | 467 | if (sie64a(vcpu->arch.sie_block, vcpu->arch.guest_gprs)) { |
@@ -461,6 +470,7 @@ static void __vcpu_run(struct kvm_vcpu *vcpu) | |||
461 | } | 470 | } |
462 | VCPU_EVENT(vcpu, 6, "exit sie icptcode %d", | 471 | VCPU_EVENT(vcpu, 6, "exit sie icptcode %d", |
463 | vcpu->arch.sie_block->icptcode); | 472 | vcpu->arch.sie_block->icptcode); |
473 | gmap_disable(vcpu->arch.gmap); | ||
464 | local_irq_disable(); | 474 | local_irq_disable(); |
465 | kvm_guest_exit(); | 475 | kvm_guest_exit(); |
466 | local_irq_enable(); | 476 | local_irq_enable(); |
@@ -474,17 +484,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
474 | sigset_t sigsaved; | 484 | sigset_t sigsaved; |
475 | 485 | ||
476 | rerun_vcpu: | 486 | rerun_vcpu: |
477 | if (vcpu->requests) | ||
478 | if (test_and_clear_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests)) | ||
479 | kvm_s390_vcpu_set_mem(vcpu); | ||
480 | |||
481 | /* verify, that memory has been registered */ | ||
482 | if (!vcpu->arch.sie_block->gmslm) { | ||
483 | vcpu_put(vcpu); | ||
484 | VCPU_EVENT(vcpu, 3, "%s", "no memory registered to run vcpu"); | ||
485 | return -EINVAL; | ||
486 | } | ||
487 | |||
488 | if (vcpu->sigset_active) | 487 | if (vcpu->sigset_active) |
489 | sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved); | 488 | sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved); |
490 | 489 | ||
@@ -545,7 +544,7 @@ rerun_vcpu: | |||
545 | return rc; | 544 | return rc; |
546 | } | 545 | } |
547 | 546 | ||
548 | static int __guestcopy(struct kvm_vcpu *vcpu, u64 guestdest, const void *from, | 547 | static int __guestcopy(struct kvm_vcpu *vcpu, u64 guestdest, void *from, |
549 | unsigned long n, int prefix) | 548 | unsigned long n, int prefix) |
550 | { | 549 | { |
551 | if (prefix) | 550 | if (prefix) |
@@ -562,7 +561,7 @@ static int __guestcopy(struct kvm_vcpu *vcpu, u64 guestdest, const void *from, | |||
562 | */ | 561 | */ |
563 | int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr) | 562 | int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr) |
564 | { | 563 | { |
565 | const unsigned char archmode = 1; | 564 | unsigned char archmode = 1; |
566 | int prefix; | 565 | int prefix; |
567 | 566 | ||
568 | if (addr == KVM_S390_STORE_STATUS_NOADDR) { | 567 | if (addr == KVM_S390_STORE_STATUS_NOADDR) { |
@@ -680,10 +679,10 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, | |||
680 | if (mem->guest_phys_addr) | 679 | if (mem->guest_phys_addr) |
681 | return -EINVAL; | 680 | return -EINVAL; |
682 | 681 | ||
683 | if (mem->userspace_addr & (PAGE_SIZE - 1)) | 682 | if (mem->userspace_addr & 0xffffful) |
684 | return -EINVAL; | 683 | return -EINVAL; |
685 | 684 | ||
686 | if (mem->memory_size & (PAGE_SIZE - 1)) | 685 | if (mem->memory_size & 0xffffful) |
687 | return -EINVAL; | 686 | return -EINVAL; |
688 | 687 | ||
689 | if (!user_alloc) | 688 | if (!user_alloc) |
@@ -697,15 +696,14 @@ void kvm_arch_commit_memory_region(struct kvm *kvm, | |||
697 | struct kvm_memory_slot old, | 696 | struct kvm_memory_slot old, |
698 | int user_alloc) | 697 | int user_alloc) |
699 | { | 698 | { |
700 | int i; | 699 | int rc; |
701 | struct kvm_vcpu *vcpu; | ||
702 | 700 | ||
703 | /* request update of sie control block for all available vcpus */ | 701 | |
704 | kvm_for_each_vcpu(i, vcpu, kvm) { | 702 | rc = gmap_map_segment(kvm->arch.gmap, mem->userspace_addr, |
705 | if (test_and_set_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests)) | 703 | mem->guest_phys_addr, mem->memory_size); |
706 | continue; | 704 | if (rc) |
707 | kvm_s390_inject_sigp_stop(vcpu, ACTION_RELOADVCPU_ON_STOP); | 705 | printk(KERN_WARNING "kvm-s390: failed to commit memory region\n"); |
708 | } | 706 | return; |
709 | } | 707 | } |
710 | 708 | ||
711 | void kvm_arch_flush_shadow(struct kvm *kvm) | 709 | void kvm_arch_flush_shadow(struct kvm *kvm) |