Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6
[pandora-kernel.git] / arch / s390 / kvm / kvm-s390.c
index 0ac36a6..1782cbc 100644 (file)
@@ -79,10 +79,6 @@ void kvm_arch_hardware_disable(void *garbage)
 {
 }
 
-void decache_vcpus_on_cpu(int cpu)
-{
-}
-
 int kvm_arch_hardware_setup(void)
 {
        return 0;
@@ -198,6 +194,7 @@ out_nokvm:
 void kvm_arch_destroy_vm(struct kvm *kvm)
 {
        debug_unregister(kvm->arch.dbf);
+       kvm_free_physmem(kvm);
        free_page((unsigned long)(kvm->arch.sca));
        kfree(kvm);
        module_put(THIS_MODULE);
@@ -250,11 +247,16 @@ static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
        vcpu->arch.sie_block->gbea = 1;
 }
 
+/* The current code can have up to 256 pages for virtio */
+#define VIRTIODESCSPACE (256ul * 4096ul)
+
 int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
 {
        atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH);
-       vcpu->arch.sie_block->gmslm = 0xffffffffffUL;
-       vcpu->arch.sie_block->gmsor = 0x000000000000;
+       vcpu->arch.sie_block->gmslm = vcpu->kvm->arch.guest_memsize +
+                                     vcpu->kvm->arch.guest_origin +
+                                     VIRTIODESCSPACE - 1ul;
+       vcpu->arch.sie_block->gmsor = vcpu->kvm->arch.guest_origin;
        vcpu->arch.sie_block->ecb   = 2;
        vcpu->arch.sie_block->eca   = 0xC1002001U;
        setup_timer(&vcpu->arch.ckc_timer, kvm_s390_idle_wakeup,
@@ -273,7 +275,8 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
        if (!vcpu)
                goto out_nomem;
 
-       vcpu->arch.sie_block = (struct sie_block *) get_zeroed_page(GFP_KERNEL);
+       vcpu->arch.sie_block = (struct kvm_s390_sie_block *)
+                                       get_zeroed_page(GFP_KERNEL);
 
        if (!vcpu->arch.sie_block)
                goto out_free_cpu;
@@ -423,6 +426,8 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
        return -EINVAL; /* not implemented yet */
 }
 
+extern void s390_handle_mcck(void);
+
 static void __vcpu_run(struct kvm_vcpu *vcpu)
 {
        memcpy(&vcpu->arch.sie_block->gg14, &vcpu->arch.guest_gprs[14], 16);
@@ -430,13 +435,21 @@ static void __vcpu_run(struct kvm_vcpu *vcpu)
        if (need_resched())
                schedule();
 
+       if (test_thread_flag(TIF_MCCK_PENDING))
+               s390_handle_mcck();
+
+       kvm_s390_deliver_pending_interrupts(vcpu);
+
        vcpu->arch.sie_block->icptcode = 0;
        local_irq_disable();
        kvm_guest_enter();
        local_irq_enable();
        VCPU_EVENT(vcpu, 6, "entering sie flags %x",
                   atomic_read(&vcpu->arch.sie_block->cpuflags));
-       sie64a(vcpu->arch.sie_block, vcpu->arch.guest_gprs);
+       if (sie64a(vcpu->arch.sie_block, vcpu->arch.guest_gprs)) {
+               VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction");
+               kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
+       }
        VCPU_EVENT(vcpu, 6, "exit sie icptcode %d",
                   vcpu->arch.sie_block->icptcode);
        local_irq_disable();
@@ -475,7 +488,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
        might_sleep();
 
        do {
-               kvm_s390_deliver_pending_interrupts(vcpu);
                __vcpu_run(vcpu);
                rc = kvm_handle_sie_intercept(vcpu);
        } while (!signal_pending(current) && !rc);
@@ -663,6 +675,10 @@ int kvm_arch_set_memory_region(struct kvm *kvm,
        return 0;
 }
 
+void kvm_arch_flush_shadow(struct kvm *kvm)
+{
+}
+
 gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn)
 {
        return gfn;